From 9d2440e961f24b717ddd78c387941cfd9e786ce4 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 10 May 2019 17:56:07 +0100 Subject: [PATCH 001/440] Test version - api copied from core with loader --- .editorconfig | 24 + .gitignore | 51 + CHANGELOG.txt | 4 + README.md | 1 + includes/RestApi.php | 146 + .../abstracts/abstract-wc-rest-controller.php | 467 +++ .../abstract-wc-rest-crud-controller.php | 627 ++++ .../abstract-wc-rest-posts-controller.php | 723 +++++ ...ract-wc-rest-shipping-zones-controller.php | 125 + .../abstract-wc-rest-terms-controller.php | 806 +++++ includes/v1/class-wc-rest-api-v1.php | 75 + .../class-wc-rest-coupons-v1-controller.php | 580 ++++ ...-rest-customer-downloads-v1-controller.php | 252 ++ .../class-wc-rest-customers-v1-controller.php | 924 ++++++ ...lass-wc-rest-order-notes-v1-controller.php | 439 +++ ...ss-wc-rest-order-refunds-v1-controller.php | 530 ++++ .../v1/class-wc-rest-orders-v1-controller.php | 1629 ++++++++++ ...-product-attribute-terms-v1-controller.php | 240 ++ ...-rest-product-attributes-v1-controller.php | 586 ++++ ...-rest-product-categories-v1-controller.php | 271 ++ ...-wc-rest-product-reviews-v1-controller.php | 578 ++++ ...product-shipping-classes-v1-controller.php | 134 + ...ass-wc-rest-product-tags-v1-controller.php | 134 + .../class-wc-rest-products-v1-controller.php | 2641 +++++++++++++++++ ...ass-wc-rest-report-sales-v1-controller.php | 397 +++ ...-rest-report-top-sellers-v1-controller.php | 174 ++ .../class-wc-rest-reports-v1-controller.php | 184 ++ ...lass-wc-rest-tax-classes-v1-controller.php | 364 +++ .../v1/class-wc-rest-taxes-v1-controller.php | 709 +++++ ...-rest-webhook-deliveries-v1-controller.php | 314 ++ .../class-wc-rest-webhooks-v1-controller.php | 763 +++++ includes/v2/class-wc-rest-api-v2.php | 97 + .../class-wc-rest-coupons-v2-controller.php | 542 ++++ ...-rest-customer-downloads-v2-controller.php | 165 + .../class-wc-rest-customers-v2-controller.php | 364 +++ ...s-wc-rest-network-orders-v2-controller.php | 174 ++ ...lass-wc-rest-order-notes-v2-controller.php | 182 ++ ...ss-wc-rest-order-refunds-v2-controller.php | 584 ++++ .../v2/class-wc-rest-orders-v2-controller.php | 1708 +++++++++++ ...wc-rest-payment-gateways-v2-controller.php | 466 +++ ...-product-attribute-terms-v2-controller.php | 27 + ...-rest-product-attributes-v2-controller.php | 27 + ...-rest-product-categories-v2-controller.php | 212 ++ ...-wc-rest-product-reviews-v2-controller.php | 199 ++ ...product-shipping-classes-v2-controller.php | 27 + ...ass-wc-rest-product-tags-v2-controller.php | 27 + ...-rest-product-variations-v2-controller.php | 1002 +++++++ .../class-wc-rest-products-v2-controller.php | 2207 ++++++++++++++ ...ass-wc-rest-report-sales-v2-controller.php | 27 + ...-rest-report-top-sellers-v2-controller.php | 27 + .../class-wc-rest-reports-v2-controller.php | 27 + ...-wc-rest-setting-options-v2-controller.php | 581 ++++ .../class-wc-rest-settings-v2-controller.php | 232 ++ ...wc-rest-shipping-methods-v2-controller.php | 231 ++ ...-shipping-zone-locations-v2-controller.php | 190 ++ ...st-shipping-zone-methods-v2-controller.php | 541 ++++ ...s-wc-rest-shipping-zones-v2-controller.php | 304 ++ ...rest-system-status-tools-v2-controller.php | 563 ++++ ...ss-wc-rest-system-status-v2-controller.php | 1180 ++++++++ ...lass-wc-rest-tax-classes-v2-controller.php | 27 + .../v2/class-wc-rest-taxes-v2-controller.php | 27 + ...-rest-webhook-deliveries-v2-controller.php | 153 + .../class-wc-rest-webhooks-v2-controller.php | 182 ++ includes/v3/class-wc-rest-api-v3.php | 113 + .../v3/class-wc-rest-coupons-controller.php | 27 + ...-wc-rest-customer-downloads-controller.php | 27 + .../v3/class-wc-rest-customers-controller.php | 307 ++ ...ass-wc-rest-data-continents-controller.php | 357 +++ includes/v3/class-wc-rest-data-controller.php | 184 ++ ...lass-wc-rest-data-countries-controller.php | 240 ++ ...ass-wc-rest-data-currencies-controller.php | 221 ++ ...lass-wc-rest-network-orders-controller.php | 27 + .../class-wc-rest-order-notes-controller.php | 167 ++ ...class-wc-rest-order-refunds-controller.php | 86 + .../v3/class-wc-rest-orders-controller.php | 271 ++ ...ss-wc-rest-payment-gateways-controller.php | 226 ++ ...est-product-attribute-terms-controller.php | 27 + ...-wc-rest-product-attributes-controller.php | 27 + ...-wc-rest-product-categories-controller.php | 271 ++ ...ass-wc-rest-product-reviews-controller.php | 1164 ++++++++ ...st-product-shipping-classes-controller.php | 27 + .../class-wc-rest-product-tags-controller.php | 27 + ...-wc-rest-product-variations-controller.php | 860 ++++++ .../v3/class-wc-rest-products-controller.php | 1341 +++++++++ ...-rest-report-coupons-totals-controller.php | 143 + ...est-report-customers-totals-controller.php | 154 + ...c-rest-report-orders-totals-controller.php | 127 + ...rest-report-products-totals-controller.php | 133 + ...-rest-report-reviews-totals-controller.php | 132 + .../class-wc-rest-report-sales-controller.php | 27 + ...-wc-rest-report-top-sellers-controller.php | 27 + .../v3/class-wc-rest-reports-controller.php | 72 + ...ass-wc-rest-setting-options-controller.php | 250 ++ .../v3/class-wc-rest-settings-controller.php | 112 + ...ss-wc-rest-shipping-methods-controller.php | 27 + ...est-shipping-zone-locations-controller.php | 27 + ...-rest-shipping-zone-methods-controller.php | 27 + ...lass-wc-rest-shipping-zones-controller.php | 27 + ...class-wc-rest-system-status-controller.php | 27 + ...wc-rest-system-status-tools-controller.php | 27 + .../class-wc-rest-tax-classes-controller.php | 27 + .../v3/class-wc-rest-taxes-controller.php | 27 + .../v3/class-wc-rest-webhooks-controller.php | 37 + .../wc-blocks/class-wc-rest-api-blocks-v1.php | 43 + ...cks-product-attribute-terms-controller.php | 185 ++ ...t-blocks-product-attributes-controller.php | 188 ++ ...t-blocks-product-categories-controller.php | 151 + ...ass-wc-rest-blocks-products-controller.php | 390 +++ phpcs.xml | 50 + readme.txt | 1 + woocommerce-rest-api.php | 41 + 111 files changed, 35670 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 CHANGELOG.txt create mode 100644 README.md create mode 100644 includes/RestApi.php create mode 100644 includes/abstracts/abstract-wc-rest-controller.php create mode 100644 includes/abstracts/abstract-wc-rest-crud-controller.php create mode 100644 includes/abstracts/abstract-wc-rest-posts-controller.php create mode 100644 includes/abstracts/abstract-wc-rest-shipping-zones-controller.php create mode 100644 includes/abstracts/abstract-wc-rest-terms-controller.php create mode 100644 includes/v1/class-wc-rest-api-v1.php create mode 100644 includes/v1/class-wc-rest-coupons-v1-controller.php create mode 100644 includes/v1/class-wc-rest-customer-downloads-v1-controller.php create mode 100644 includes/v1/class-wc-rest-customers-v1-controller.php create mode 100644 includes/v1/class-wc-rest-order-notes-v1-controller.php create mode 100644 includes/v1/class-wc-rest-order-refunds-v1-controller.php create mode 100644 includes/v1/class-wc-rest-orders-v1-controller.php create mode 100644 includes/v1/class-wc-rest-product-attribute-terms-v1-controller.php create mode 100644 includes/v1/class-wc-rest-product-attributes-v1-controller.php create mode 100644 includes/v1/class-wc-rest-product-categories-v1-controller.php create mode 100644 includes/v1/class-wc-rest-product-reviews-v1-controller.php create mode 100644 includes/v1/class-wc-rest-product-shipping-classes-v1-controller.php create mode 100644 includes/v1/class-wc-rest-product-tags-v1-controller.php create mode 100644 includes/v1/class-wc-rest-products-v1-controller.php create mode 100644 includes/v1/class-wc-rest-report-sales-v1-controller.php create mode 100644 includes/v1/class-wc-rest-report-top-sellers-v1-controller.php create mode 100644 includes/v1/class-wc-rest-reports-v1-controller.php create mode 100644 includes/v1/class-wc-rest-tax-classes-v1-controller.php create mode 100644 includes/v1/class-wc-rest-taxes-v1-controller.php create mode 100644 includes/v1/class-wc-rest-webhook-deliveries-v1-controller.php create mode 100644 includes/v1/class-wc-rest-webhooks-v1-controller.php create mode 100644 includes/v2/class-wc-rest-api-v2.php create mode 100644 includes/v2/class-wc-rest-coupons-v2-controller.php create mode 100644 includes/v2/class-wc-rest-customer-downloads-v2-controller.php create mode 100644 includes/v2/class-wc-rest-customers-v2-controller.php create mode 100644 includes/v2/class-wc-rest-network-orders-v2-controller.php create mode 100644 includes/v2/class-wc-rest-order-notes-v2-controller.php create mode 100644 includes/v2/class-wc-rest-order-refunds-v2-controller.php create mode 100644 includes/v2/class-wc-rest-orders-v2-controller.php create mode 100644 includes/v2/class-wc-rest-payment-gateways-v2-controller.php create mode 100644 includes/v2/class-wc-rest-product-attribute-terms-v2-controller.php create mode 100644 includes/v2/class-wc-rest-product-attributes-v2-controller.php create mode 100644 includes/v2/class-wc-rest-product-categories-v2-controller.php create mode 100644 includes/v2/class-wc-rest-product-reviews-v2-controller.php create mode 100644 includes/v2/class-wc-rest-product-shipping-classes-v2-controller.php create mode 100644 includes/v2/class-wc-rest-product-tags-v2-controller.php create mode 100644 includes/v2/class-wc-rest-product-variations-v2-controller.php create mode 100644 includes/v2/class-wc-rest-products-v2-controller.php create mode 100644 includes/v2/class-wc-rest-report-sales-v2-controller.php create mode 100644 includes/v2/class-wc-rest-report-top-sellers-v2-controller.php create mode 100644 includes/v2/class-wc-rest-reports-v2-controller.php create mode 100644 includes/v2/class-wc-rest-setting-options-v2-controller.php create mode 100644 includes/v2/class-wc-rest-settings-v2-controller.php create mode 100644 includes/v2/class-wc-rest-shipping-methods-v2-controller.php create mode 100644 includes/v2/class-wc-rest-shipping-zone-locations-v2-controller.php create mode 100644 includes/v2/class-wc-rest-shipping-zone-methods-v2-controller.php create mode 100644 includes/v2/class-wc-rest-shipping-zones-v2-controller.php create mode 100644 includes/v2/class-wc-rest-system-status-tools-v2-controller.php create mode 100644 includes/v2/class-wc-rest-system-status-v2-controller.php create mode 100644 includes/v2/class-wc-rest-tax-classes-v2-controller.php create mode 100644 includes/v2/class-wc-rest-taxes-v2-controller.php create mode 100644 includes/v2/class-wc-rest-webhook-deliveries-v2-controller.php create mode 100644 includes/v2/class-wc-rest-webhooks-v2-controller.php create mode 100644 includes/v3/class-wc-rest-api-v3.php create mode 100644 includes/v3/class-wc-rest-coupons-controller.php create mode 100644 includes/v3/class-wc-rest-customer-downloads-controller.php create mode 100644 includes/v3/class-wc-rest-customers-controller.php create mode 100644 includes/v3/class-wc-rest-data-continents-controller.php create mode 100644 includes/v3/class-wc-rest-data-controller.php create mode 100644 includes/v3/class-wc-rest-data-countries-controller.php create mode 100644 includes/v3/class-wc-rest-data-currencies-controller.php create mode 100644 includes/v3/class-wc-rest-network-orders-controller.php create mode 100644 includes/v3/class-wc-rest-order-notes-controller.php create mode 100644 includes/v3/class-wc-rest-order-refunds-controller.php create mode 100644 includes/v3/class-wc-rest-orders-controller.php create mode 100644 includes/v3/class-wc-rest-payment-gateways-controller.php create mode 100644 includes/v3/class-wc-rest-product-attribute-terms-controller.php create mode 100644 includes/v3/class-wc-rest-product-attributes-controller.php create mode 100644 includes/v3/class-wc-rest-product-categories-controller.php create mode 100644 includes/v3/class-wc-rest-product-reviews-controller.php create mode 100644 includes/v3/class-wc-rest-product-shipping-classes-controller.php create mode 100644 includes/v3/class-wc-rest-product-tags-controller.php create mode 100644 includes/v3/class-wc-rest-product-variations-controller.php create mode 100644 includes/v3/class-wc-rest-products-controller.php create mode 100644 includes/v3/class-wc-rest-report-coupons-totals-controller.php create mode 100644 includes/v3/class-wc-rest-report-customers-totals-controller.php create mode 100644 includes/v3/class-wc-rest-report-orders-totals-controller.php create mode 100644 includes/v3/class-wc-rest-report-products-totals-controller.php create mode 100644 includes/v3/class-wc-rest-report-reviews-totals-controller.php create mode 100644 includes/v3/class-wc-rest-report-sales-controller.php create mode 100644 includes/v3/class-wc-rest-report-top-sellers-controller.php create mode 100644 includes/v3/class-wc-rest-reports-controller.php create mode 100644 includes/v3/class-wc-rest-setting-options-controller.php create mode 100644 includes/v3/class-wc-rest-settings-controller.php create mode 100644 includes/v3/class-wc-rest-shipping-methods-controller.php create mode 100644 includes/v3/class-wc-rest-shipping-zone-locations-controller.php create mode 100644 includes/v3/class-wc-rest-shipping-zone-methods-controller.php create mode 100644 includes/v3/class-wc-rest-shipping-zones-controller.php create mode 100644 includes/v3/class-wc-rest-system-status-controller.php create mode 100644 includes/v3/class-wc-rest-system-status-tools-controller.php create mode 100644 includes/v3/class-wc-rest-tax-classes-controller.php create mode 100644 includes/v3/class-wc-rest-taxes-controller.php create mode 100644 includes/v3/class-wc-rest-webhooks-controller.php create mode 100644 includes/wc-blocks/class-wc-rest-api-blocks-v1.php create mode 100644 includes/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php create mode 100644 includes/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php create mode 100644 includes/wc-blocks/class-wc-rest-blocks-product-categories-controller.php create mode 100644 includes/wc-blocks/class-wc-rest-blocks-products-controller.php create mode 100644 phpcs.xml create mode 100644 readme.txt create mode 100644 woocommerce-rest-api.php diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..c3dfa83750f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# https://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +tab_width = 4 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +[*.txt] +trim_trailing_whitespace = false + +[*.{md,json,yml}] +trim_trailing_whitespace = false +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..6d673efc6ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,51 @@ +# Editors +project.xml +project.properties +/nbproject/private/ +.buildpath +.project +.settings* +.idea +.vscode +*.sublime-project +*.sublime-workspace +.sublimelinterrc + +# Grunt +/node_modules/ +none + +# Sass +.sass-cache/ + +# OS X metadata +.DS_Store + +# Windows junk +Thumbs.db + +# ApiGen +/wc-apidocs/ + +# Behat/CLI Tests +tests/cli/installer +tests/cli/composer.phar +tests/cli/composer.lock +tests/cli/composer.json +tests/cli/vendor + +# Unit tests +/tmp +/tests/bin/tmp +/tests/e2e-tests/config/local-*.json +/tests/e2e-tests/config/local.json + +# Logs +/logs + +# Composer +/vendor/ +contributors.md + +# Screenshots for e2e tests failures +/screenshots/ diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 00000000000..2edac50f70c --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,4 @@ +== Changelog == + += 0.0.1 = +TODO diff --git a/README.md b/README.md new file mode 100644 index 00000000000..1333ed77b7e --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +TODO diff --git a/includes/RestApi.php b/includes/RestApi.php new file mode 100644 index 00000000000..59d6bb9c93f --- /dev/null +++ b/includes/RestApi.php @@ -0,0 +1,146 @@ +get_file_name_from_class( $class ); + + if ( file_exists( "{$dir}{$file}" ) ) { + include "{$dir}{$file}"; + return; + } + + $file = $this->get_file_name_from_class( $class, 'abstract-' ); + + if ( file_exists( dirname( __FILE__ ) . "/abstracts/{$file}" ) ) { + include dirname( __FILE__ ) . "/abstracts/{$file}"; + return; + } + } + + if ( file_exists( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . "{$class}.php" ) ) { + include dirname( __FILE__ ) . DIRECTORY_SEPARATOR . "{$class}.php"; + return; + } + } + + /** + * Get API namespaces. + */ + protected function get_namespaces() { + return array( + 'wc/v1' => 'WC_Rest_API_V1', + 'wc/v2' => 'WC_Rest_API_V2', + 'wc/v3' => 'WC_Rest_API_V3', + 'wc-blocks/v1' => 'WC_Rest_API_Blocks_V1', + ); + } + + /** + * Register REST API routes. + */ + public function register_rest_routes() { + foreach ( $this->get_namespaces() as $namespace => $classname ) { + $api = new $classname(); + $api->includes(); + + foreach ( $api->get_controllers() as $controller ) { + $this->$controller = new $controller(); + $this->$controller->register_routes(); + } + } + } +} diff --git a/includes/abstracts/abstract-wc-rest-controller.php b/includes/abstracts/abstract-wc-rest-controller.php new file mode 100644 index 00000000000..987a4d78741 --- /dev/null +++ b/includes/abstracts/abstract-wc-rest-controller.php @@ -0,0 +1,467 @@ + + * + * NOTE THAT ONLY CODE RELEVANT FOR MOST ENDPOINTS SHOULD BE INCLUDED INTO THIS CLASS. + * If necessary extend this class and create new abstract classes like `WC_REST_CRUD_Controller` or `WC_REST_Terms_Controller`. + * + * @class WC_REST_Controller + * @package WooCommerce/Abstracts + * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * Abstract Rest Controller Class + * + * @package WooCommerce/Abstracts + * @extends WP_REST_Controller + * @version 2.6.0 + */ +abstract class WC_REST_Controller extends WP_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = ''; + + /** + * Add the schema from additional fields to an schema array. + * + * The type of object is inferred from the passed schema. + * + * @param array $schema Schema array. + * + * @return array + */ + protected function add_additional_fields_schema( $schema ) { + if ( empty( $schema['title'] ) ) { + return $schema; + } + + /** + * Can't use $this->get_object_type otherwise we cause an inf loop. + */ + $object_type = $schema['title']; + + $additional_fields = $this->get_additional_fields( $object_type ); + + foreach ( $additional_fields as $field_name => $field_options ) { + if ( ! $field_options['schema'] ) { + continue; + } + + $schema['properties'][ $field_name ] = $field_options['schema']; + } + + $schema['properties'] = apply_filters( 'woocommerce_rest_' . $object_type . '_schema', $schema['properties'] ); + + return $schema; + } + + /** + * Get normalized rest base. + * + * @return string + */ + protected function get_normalized_rest_base() { + return preg_replace( '/\(.*\)\//i', '', $this->rest_base ); + } + + /** + * Check batch limit. + * + * @param array $items Request items. + * @return bool|WP_Error + */ + protected function check_batch_limit( $items ) { + $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); + $total = 0; + + if ( ! empty( $items['create'] ) ) { + $total += count( $items['create'] ); + } + + if ( ! empty( $items['update'] ) ) { + $total += count( $items['update'] ); + } + + if ( ! empty( $items['delete'] ) ) { + $total += count( $items['delete'] ); + } + + if ( $total > $limit ) { + /* translators: %s: items limit */ + return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); + } + + return true; + } + + /** + * Bulk create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + /** + * REST Server + * + * @var WP_REST_Server $wp_rest_server + */ + global $wp_rest_server; + + // Get the request params. + $items = array_filter( $request->get_params() ); + $response = array(); + + // Check batch limit. + $limit = $this->check_batch_limit( $items ); + if ( is_wp_error( $limit ) ) { + return $limit; + } + + if ( ! empty( $items['create'] ) ) { + foreach ( $items['create'] as $item ) { + $_item = new WP_REST_Request( 'POST' ); + + // Default parameters. + $defaults = array(); + $schema = $this->get_public_item_schema(); + foreach ( $schema['properties'] as $arg => $options ) { + if ( isset( $options['default'] ) ) { + $defaults[ $arg ] = $options['default']; + } + } + $_item->set_default_params( $defaults ); + + // Set request parameters. + $_item->set_body_params( $item ); + $_response = $this->create_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['create'][] = array( + 'id' => 0, + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['create'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + if ( ! empty( $items['update'] ) ) { + foreach ( $items['update'] as $item ) { + $_item = new WP_REST_Request( 'PUT' ); + $_item->set_body_params( $item ); + $_response = $this->update_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['update'][] = array( + 'id' => $item['id'], + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['update'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + if ( ! empty( $items['delete'] ) ) { + foreach ( $items['delete'] as $id ) { + $id = (int) $id; + + if ( 0 === $id ) { + continue; + } + + $_item = new WP_REST_Request( 'DELETE' ); + $_item->set_query_params( + array( + 'id' => $id, + 'force' => true, + ) + ); + $_response = $this->delete_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['delete'][] = array( + 'id' => $id, + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['delete'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + return $response; + } + + /** + * Validate a text value for a text based setting. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string + */ + public function validate_setting_text_field( $value, $setting ) { + $value = is_null( $value ) ? '' : $value; + return wp_kses_post( trim( stripslashes( $value ) ) ); + } + + /** + * Validate select based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_select_field( $value, $setting ) { + if ( array_key_exists( $value, $setting['options'] ) ) { + return $value; + } else { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + /** + * Validate multiselect based settings. + * + * @since 3.0.0 + * @param array $values Values. + * @param array $setting Setting. + * @return array|WP_Error + */ + public function validate_setting_multiselect_field( $values, $setting ) { + if ( empty( $values ) ) { + return array(); + } + + if ( ! is_array( $values ) ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $final_values = array(); + foreach ( $values as $value ) { + if ( array_key_exists( $value, $setting['options'] ) ) { + $final_values[] = $value; + } + } + + return $final_values; + } + + /** + * Validate image_width based settings. + * + * @since 3.0.0 + * @param array $values Values. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_image_width_field( $values, $setting ) { + if ( ! is_array( $values ) ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $current = $setting['value']; + if ( isset( $values['width'] ) ) { + $current['width'] = intval( $values['width'] ); + } + if ( isset( $values['height'] ) ) { + $current['height'] = intval( $values['height'] ); + } + if ( isset( $values['crop'] ) ) { + $current['crop'] = (bool) $values['crop']; + } + return $current; + } + + /** + * Validate radio based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_radio_field( $value, $setting ) { + return $this->validate_setting_select_field( $value, $setting ); + } + + /** + * Validate checkbox based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_checkbox_field( $value, $setting ) { + if ( in_array( $value, array( 'yes', 'no' ) ) ) { + return $value; + } elseif ( empty( $value ) ) { + $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; + return $value; + } else { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + /** + * Validate textarea based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string + */ + public function validate_setting_textarea_field( $value, $setting ) { + $value = is_null( $value ) ? '' : $value; + return wp_kses( + trim( stripslashes( $value ) ), + array_merge( + array( + 'iframe' => array( + 'src' => true, + 'style' => true, + 'id' => true, + 'class' => true, + ), + ), + wp_kses_allowed_html( 'post' ) + ) + ); + } + + /** + * Add meta query. + * + * @since 3.0.0 + * @param array $args Query args. + * @param array $meta_query Meta query. + * @return array + */ + protected function add_meta_query( $args, $meta_query ) { + if ( empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); + } + + $args['meta_query'][] = $meta_query; + + return $args['meta_query']; + } + + /** + * Get the batch schema, conforming to JSON Schema. + * + * @return array + */ + public function get_public_batch_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'batch', + 'type' => 'object', + 'properties' => array( + 'create' => array( + 'description' => __( 'List of created resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + ), + ), + 'update' => array( + 'description' => __( 'List of updated resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + ), + ), + 'delete' => array( + 'description' => __( 'List of delete resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + ), + ), + ); + + return $schema; + } + + /** + * Gets an array of fields to be included on the response. + * Included fields are based on item schema and `_fields=` request argument. + * Introduced to support WordPress 4.9.6 changes. + * + * @since 3.5.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Fields to be included in the response. + */ + public function get_fields_for_response( $request ) { + $schema = $this->get_item_schema(); + $fields = isset( $schema['properties'] ) ? array_keys( $schema['properties'] ) : array(); + + $additional_fields = $this->get_additional_fields(); + foreach ( $additional_fields as $field_name => $field_options ) { + // For back-compat, include any field with an empty schema + // because it won't be present in $this->get_item_schema(). + if ( is_null( $field_options['schema'] ) ) { + $fields[] = $field_name; + } + } + + if ( ! isset( $request['_fields'] ) ) { + return $fields; + } + $requested_fields = is_array( $request['_fields'] ) ? $request['_fields'] : preg_split( '/[\s,]+/', $request['_fields'] ); + if ( 0 === count( $requested_fields ) ) { + return $fields; + } + // Trim off outside whitespace from the comma delimited list. + $requested_fields = array_map( 'trim', $requested_fields ); + // Always persist 'id', because it can be needed for add_additional_fields_to_object(). + if ( in_array( 'id', $fields, true ) ) { + $requested_fields[] = 'id'; + } + return array_intersect( $fields, $requested_fields ); + } +} diff --git a/includes/abstracts/abstract-wc-rest-crud-controller.php b/includes/abstracts/abstract-wc-rest-crud-controller.php new file mode 100644 index 00000000000..c42f1233141 --- /dev/null +++ b/includes/abstracts/abstract-wc-rest-crud-controller.php @@ -0,0 +1,627 @@ + 405 ) ); + } + + /** + * Check if a given request has access to read an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get object permalink. + * + * @param object $object Object. + * @return string + */ + protected function get_permalink( $object ) { + return ''; + } + + /** + * Prepares the object for the REST response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. + */ + protected function prepare_object_for_response( $object, $request ) { + // translators: %s: Class method name. + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + */ + protected function prepare_object_for_database( $request, $creating = false ) { + // translators: %s: Class method name. + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_object_for_response( $object, $request ); + $response = rest_ensure_response( $data ); + + if ( $this->public ) { + $response->link_header( 'alternate', $this->get_permalink( $object ), array( 'type' => 'text/html' ) ); + } + + return $response; + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + $object->save(); + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $object = $this->save_object( $request, true ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + try { + $this->update_additional_fields_for_object( $object, $request ); + } catch ( WC_Data_Exception $e ) { + $object->delete(); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + $object->delete(); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + /** + * Fires after a single object is created or updated via the REST API. + * + * @param WC_Data $object Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating object, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ) ); + + return $response; + } + + /** + * Update a single post. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $object = $this->save_object( $request, false ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + try { + $this->update_additional_fields_for_object( $object, $request ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + /** + * Fires after a single object is created or updated via the REST API. + * + * @param WC_Data $object Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating object, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + return rest_ensure_response( $response ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = array(); + $args['offset'] = $request['offset']; + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['paged'] = $request['page']; + $args['post__in'] = $request['include']; + $args['post__not_in'] = $request['exclude']; + $args['posts_per_page'] = $request['per_page']; + $args['name'] = $request['slug']; + $args['post_parent__in'] = $request['parent']; + $args['post_parent__not_in'] = $request['parent_exclude']; + $args['s'] = $request['search']; + + if ( 'date' === $args['orderby'] ) { + $args['orderby'] = 'date ID'; + } + + $args['date_query'] = array(); + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $request['before'] ) ) { + $args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $request['after'] ) ) { + $args['date_query'][0]['after'] = $request['after']; + } + + // Force the post_type argument, since it's not a user input variable. + $args['post_type'] = $this->post_type; + + /** + * 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_{$this->post_type}_object_query", $args, $request ); + + return $this->prepare_items_query( $args, $request ); + } + + /** + * Get objects. + * + * @since 3.0.0 + * @param array $query_args Query args. + * @return array + */ + protected function get_objects( $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( array( $this, 'get_object' ), $result ), + 'total' => (int) $total_posts, + 'pages' => (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ), + ); + } + + /** + * Get a collection of posts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $query_args = $this->prepare_objects_query( $request ); + $query_results = $this->get_objects( $query_args ); + + $objects = array(); + foreach ( $query_results['objects'] as $object ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { + continue; + } + + $data = $this->prepare_object_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 = $this->rest_base; + $attrib_prefix = '(?P<'; + if ( strpos( $base, $attrib_prefix ) !== false ) { + $attrib_names = array(); + preg_match( '/\(\?P<[^>]+>.*\)/', $base, $attrib_names, PREG_OFFSET_CAPTURE ); + foreach ( $attrib_names as $attrib_name_match ) { + $beginning_offset = strlen( $attrib_prefix ); + $attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] ); + $attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset ); + if ( isset( $request[ $attrib_name ] ) ) { + $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); + } + } + } + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $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; + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $object->delete( true ); + $result = 0 === $object->get_id(); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + $object->delete(); + $result = 'trash' === $object->get_status(); + } + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single object is deleted or trashed via the REST API. + * + * @param WC_Data $object The deleted or trashed object. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = array(); + $params['context'] = $this->get_context_param(); + $params['context']['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['search'] = array( + 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + '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['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' => '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', + 'id', + 'include', + 'title', + 'slug', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + if ( $this->hierarchical ) { + $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(), + ); + } + + /** + * Filter collection parameters for the posts controller. + * + * The dynamic part of the filter `$this->post_type` refers to the post + * type slug for the controller. + * + * This filter registers the collection parameter, but does not map the + * collection parameter to an internal WP_Query parameter. Use the + * `rest_{$this->post_type}_query` filter to set WP_Query parameters. + * + * @param array $query_params JSON Schema-formatted collection parameters. + * @param WP_Post_Type $post_type Post type object. + */ + return apply_filters( "rest_{$this->post_type}_collection_params", $params, $this->post_type ); + } +} diff --git a/includes/abstracts/abstract-wc-rest-posts-controller.php b/includes/abstracts/abstract-wc-rest-posts-controller.php new file mode 100644 index 00000000000..bffc4a6843e --- /dev/null +++ b/includes/abstracts/abstract-wc-rest-posts-controller.php @@ -0,0 +1,723 @@ +post_type, 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $post = get_post( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $data ); + + if ( $this->public ) { + $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) ); + } + + return $response; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + $post->post_type = $this->post_type; + $post_id = wp_insert_post( $post, true ); + + if ( is_wp_error( $post_id ) ) { + + if ( in_array( $post_id->get_error_code(), array( 'db_insert_error' ) ) ) { + $post_id->add_data( array( 'status' => 500 ) ); + } else { + $post_id->add_data( array( 'status' => 400 ) ); + } + return $post_id; + } + $post->ID = $post_id; + $post = get_post( $post_id ); + + $this->update_additional_fields_for_object( $post, $request ); + + // Add meta fields. + $meta_fields = $this->add_post_meta_fields( $post, $request ); + if ( is_wp_error( $meta_fields ) ) { + // Remove post. + $this->delete_post( $post ); + + return $meta_fields; + } + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post_id ) ) ); + + return $response; + } + + /** + * Add post meta fields. + * + * @param WP_Post $post Post Object. + * @param WP_REST_Request $request WP_REST_Request Object. + * @return bool|WP_Error + */ + protected function add_post_meta_fields( $post, $request ) { + return true; + } + + /** + * Delete post. + * + * @param WP_Post $post Post object. + */ + protected function delete_post( $post ) { + wp_delete_post( $post->ID, true ); + } + + /** + * Update a single post. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $post = get_post( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + // Convert the post object to an array, otherwise wp_update_post will expect non-escaped input. + $post_id = wp_update_post( (array) $post, true ); + if ( is_wp_error( $post_id ) ) { + if ( in_array( $post_id->get_error_code(), array( 'db_update_error' ) ) ) { + $post_id->add_data( array( 'status' => 500 ) ); + } else { + $post_id->add_data( array( 'status' => 400 ) ); + } + return $post_id; + } + + $post = get_post( $post_id ); + $this->update_additional_fields_for_object( $post, $request ); + + // Update meta fields. + $meta_fields = $this->update_post_meta_fields( $post, $request ); + if ( is_wp_error( $meta_fields ) ) { + return $meta_fields; + } + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + } + + /** + * Get a collection of posts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $args = array(); + $args['offset'] = $request['offset']; + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['paged'] = $request['page']; + $args['post__in'] = $request['include']; + $args['post__not_in'] = $request['exclude']; + $args['posts_per_page'] = $request['per_page']; + $args['name'] = $request['slug']; + $args['post_parent__in'] = $request['parent']; + $args['post_parent__not_in'] = $request['parent_exclude']; + $args['s'] = $request['search']; + + $args['date_query'] = array(); + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $request['before'] ) ) { + $args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $request['after'] ) ) { + $args['date_query'][0]['after'] = $request['after']; + } + + if ( 'wc/v1' === $this->namespace ) { + if ( is_array( $request['filter'] ) ) { + $args = array_merge( $args, $request['filter'] ); + unset( $args['filter'] ); + } + } + + // Force the post_type argument, since it's not a user input variable. + $args['post_type'] = $this->post_type; + + /** + * 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_{$this->post_type}_query", $args, $request ); + $query_args = $this->prepare_items_query( $args, $request ); + + $posts_query = new WP_Query(); + $query_result = $posts_query->query( $query_args ); + + $posts = array(); + foreach ( $query_result as $post ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { + continue; + } + + $data = $this->prepare_item_for_response( $post, $request ); + $posts[] = $this->prepare_response_for_collection( $data ); + } + + $page = (int) $query_args['paged']; + $total_posts = $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; + } + + $max_pages = ceil( $total_posts / (int) $query_args['posts_per_page'] ); + + $response = rest_ensure_response( $posts ); + $response->header( 'X-WP-Total', (int) $total_posts ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $request_params = $request->get_query_params(); + if ( ! empty( $request_params['filter'] ) ) { + // Normalize the pagination params. + unset( $request_params['filter']['posts_per_page'] ); + unset( $request_params['filter']['paged'] ); + } + $base = add_query_arg( $request_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; + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = (bool) $request['force']; + $post = get_post( $id ); + + if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0; + + /** + * Filter whether an item is trashable. + * + * Return false to disable trash support for the item. + * + * @param boolean $supports_trash Whether the item type support trashing. + * @param WP_Post $post The Post object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $result = wp_delete_post( $id, true ); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( 'trash' === $post->post_status ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + // (Note that internally this falls through to `wp_delete_post` if + // the trash is disabled.) + $result = wp_trash_post( $id ); + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param object $post The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $post, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Determine the allowed query_vars for a get_items() response and + * prepare for WP_Query. + * + * @param array $prepared_args Prepared arguments. + * @param WP_REST_Request $request Request object. + * @return array $query_args + */ + protected function prepare_items_query( $prepared_args = array(), $request = null ) { + + $valid_vars = array_flip( $this->get_allowed_query_vars() ); + $query_args = array(); + foreach ( $valid_vars as $var => $index ) { + if ( isset( $prepared_args[ $var ] ) ) { + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $var, refers to the query_var key. + * + * @param mixed $prepared_args[ $var ] The query_var value. + */ + $query_args[ $var ] = apply_filters( "woocommerce_rest_query_var-{$var}", $prepared_args[ $var ] ); + } + } + + $query_args['ignore_sticky_posts'] = true; + + if ( 'include' === $query_args['orderby'] ) { + $query_args['orderby'] = 'post__in'; + } elseif ( 'id' === $query_args['orderby'] ) { + $query_args['orderby'] = 'ID'; // ID must be capitalized. + } elseif ( 'slug' === $query_args['orderby'] ) { + $query_args['orderby'] = 'name'; + } + + return $query_args; + } + + /** + * Get all the WP Query vars that are allowed for the API request. + * + * @return array + */ + protected function get_allowed_query_vars() { + global $wp; + + /** + * Filter the publicly allowed query vars. + * + * Allows adjusting of the default query vars that are made public. + * + * @param array Array of allowed WP_Query query vars. + */ + $valid_vars = apply_filters( 'query_vars', $wp->public_query_vars ); + + $post_type_obj = get_post_type_object( $this->post_type ); + if ( current_user_can( $post_type_obj->cap->edit_posts ) ) { + /** + * Filter the allowed 'private' query vars for authorized users. + * + * If the user has the `edit_posts` capability, we also allow use of + * private query parameters, which are only undesirable on the + * frontend, but are safe for use in query strings. + * + * To disable anyway, use + * `add_filter( 'woocommerce_rest_private_query_vars', '__return_empty_array' );` + * + * @param array $private_query_vars Array of allowed query vars for authorized users. + * } + */ + $private = apply_filters( 'woocommerce_rest_private_query_vars', $wp->private_query_vars ); + $valid_vars = array_merge( $valid_vars, $private ); + } + // Define our own in addition to WP's normal vars. + $rest_valid = array( + 'date_query', + 'ignore_sticky_posts', + 'offset', + 'post__in', + 'post__not_in', + 'post_parent', + 'post_parent__in', + 'post_parent__not_in', + 'posts_per_page', + 'meta_query', + 'tax_query', + 'meta_key', + 'meta_value', + 'meta_compare', + 'meta_value_num', + ); + $valid_vars = array_merge( $valid_vars, $rest_valid ); + + /** + * Filter allowed query vars for the REST API. + * + * This filter allows you to add or remove query vars from the final allowed + * list for all requests, including unauthenticated ones. To alter the + * vars for editors only. + * + * @param array { + * Array of allowed WP_Query query vars. + * + * @param string $allowed_query_var The query var to allow. + * } + */ + $valid_vars = apply_filters( 'woocommerce_rest_query_vars', $valid_vars ); + + return $valid_vars; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $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['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' => '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', + 'id', + 'include', + 'title', + 'slug', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $post_type_obj = get_post_type_object( $this->post_type ); + + if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) { + $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(), + ); + } + + if ( 'wc/v1' === $this->namespace ) { + $params['filter'] = array( + 'type' => 'object', + 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce' ), + ); + } + + return $params; + } + + /** + * Update post meta fields. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return bool|WP_Error + */ + protected function update_post_meta_fields( $post, $request ) { + return true; + } +} diff --git a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php new file mode 100644 index 00000000000..b89a5a442c8 --- /dev/null +++ b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php @@ -0,0 +1,125 @@ + 404 ) ); + } + + return $zone; + } + + /** + * Check whether a given request has permission to read Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check whether a given request has permission to edit Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check whether a given request has permission to delete Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + +} diff --git a/includes/abstracts/abstract-wc-rest-terms-controller.php b/includes/abstracts/abstract-wc-rest-terms-controller.php new file mode 100644 index 00000000000..4d20b07ea34 --- /dev/null +++ b/includes/abstracts/abstract-wc-rest-terms-controller.php @@ -0,0 +1,806 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( + 'name' => array( + 'type' => 'string', + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'required' => true, + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Check if a given request has access to read the terms. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'read' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'create' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'read' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'edit' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'delete' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'batch' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check permissions. + * + * @param WP_REST_Request $request Full details about the request. + * @param string $context Request context. + * @return bool|WP_Error + */ + protected function check_permissions( $request, $context = 'read' ) { + // Get taxonomy. + $taxonomy = $this->get_taxonomy( $request ); + if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Check permissions for a single term. + $id = intval( $request['id'] ); + if ( $id ) { + $term = get_term( $id, $taxonomy ); + + if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { + return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id ); + } + + return wc_rest_check_product_term_permissions( $taxonomy, $context ); + } + + /** + * Get terms associated with a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $prepared_args = array( + 'exclude' => $request['exclude'], + 'include' => $request['include'], + 'order' => $request['order'], + 'orderby' => $request['orderby'], + 'product' => $request['product'], + 'hide_empty' => $request['hide_empty'], + 'number' => $request['per_page'], + 'search' => $request['search'], + 'slug' => $request['slug'], + ); + + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + + $taxonomy_obj = get_taxonomy( $taxonomy ); + + if ( $taxonomy_obj->hierarchical && isset( $request['parent'] ) ) { + if ( 0 === $request['parent'] ) { + // Only query top-level terms. + $prepared_args['parent'] = 0; + } else { + if ( $request['parent'] ) { + $prepared_args['parent'] = $request['parent']; + } + } + } + + /** + * Filter the query arguments, before passing them to `get_terms()`. + * + * Enables adding extra arguments or setting defaults for a terms + * collection request. + * + * @see https://developer.wordpress.org/reference/functions/get_terms/ + * + * @param array $prepared_args Array of arguments to be + * passed to get_terms. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( "woocommerce_rest_{$taxonomy}_query", $prepared_args, $request ); + + if ( ! empty( $prepared_args['product'] ) ) { + $query_result = $this->get_terms_for_product( $prepared_args, $request ); + $total_terms = $this->total_terms; + } else { + $query_result = get_terms( $taxonomy, $prepared_args ); + + $count_args = $prepared_args; + unset( $count_args['number'] ); + unset( $count_args['offset'] ); + $total_terms = wp_count_terms( $taxonomy, $count_args ); + + // Ensure we don't return results when offset is out of bounds. + // See https://core.trac.wordpress.org/ticket/35935. + if ( $prepared_args['offset'] && $prepared_args['offset'] >= $total_terms ) { + $query_result = array(); + } + + // wp_count_terms can return a falsy value when the term has no children. + if ( ! $total_terms ) { + $total_terms = 0; + } + } + $response = array(); + foreach ( $query_result as $term ) { + $data = $this->prepare_item_for_response( $term, $request ); + $response[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $response ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + $response->header( 'X-WP-Total', (int) $total_terms ); + $max_pages = ceil( $total_terms / $per_page ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $base = str_replace( '(?P[\d]+)', $request['attribute_id'], $this->rest_base ); + $base = add_query_arg( $request->get_query_params(), rest_url( '/' . $this->namespace . '/' . $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; + } + + /** + * Create a single term for a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $name = $request['name']; + $args = array(); + $schema = $this->get_item_schema(); + + if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { + $args['description'] = $request['description']; + } + if ( isset( $request['slug'] ) ) { + $args['slug'] = $request['slug']; + } + if ( isset( $request['parent'] ) ) { + if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + } + $args['parent'] = $request['parent']; + } + + $term = wp_insert_term( $name, $taxonomy, $args ); + if ( is_wp_error( $term ) ) { + $error_data = array( 'status' => 400 ); + + // If we're going to inform the client that the term exists, + // give them the identifier they can actually use. + $term_id = $term->get_error_data( 'term_exists' ); + if ( $term_id ) { + $error_data['resource_id'] = $term_id; + } + + return new WP_Error( $term->get_error_code(), $term->get_error_message(), $error_data ); + } + + $term = get_term( $term['term_id'], $taxonomy ); + + $this->update_additional_fields_for_object( $term, $request ); + + // Add term data. + $meta_fields = $this->update_term_meta_fields( $term, $request ); + if ( is_wp_error( $meta_fields ) ) { + wp_delete_term( $term->term_id, $taxonomy ); + + return $meta_fields; + } + + /** + * Fires after a single term is created or updated via the REST API. + * + * @param WP_Term $term Inserted Term object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating term, false when updating. + */ + do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + + $base = '/' . $this->namespace . '/' . $this->rest_base; + if ( ! empty( $request['attribute_id'] ) ) { + $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); + } + + $response->header( 'Location', rest_url( $base . '/' . $term->term_id ) ); + + return $response; + } + + /** + * Get a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function get_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $term = get_term( (int) $request['id'], $taxonomy ); + + if ( is_wp_error( $term ) ) { + return $term; + } + + $response = $this->prepare_item_for_response( $term, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Update a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $term = get_term( (int) $request['id'], $taxonomy ); + $schema = $this->get_item_schema(); + $prepared_args = array(); + + if ( isset( $request['name'] ) ) { + $prepared_args['name'] = $request['name']; + } + if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { + $prepared_args['description'] = $request['description']; + } + if ( isset( $request['slug'] ) ) { + $prepared_args['slug'] = $request['slug']; + } + if ( isset( $request['parent'] ) ) { + if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + } + $prepared_args['parent'] = $request['parent']; + } + + // Only update the term if we haz something to update. + if ( ! empty( $prepared_args ) ) { + $update = wp_update_term( $term->term_id, $term->taxonomy, $prepared_args ); + if ( is_wp_error( $update ) ) { + return $update; + } + } + + $term = get_term( (int) $request['id'], $taxonomy ); + + $this->update_additional_fields_for_object( $term, $request ); + + // Update term data. + $meta_fields = $this->update_term_meta_fields( $term, $request ); + if ( is_wp_error( $meta_fields ) ) { + return $meta_fields; + } + + /** + * Fires after a single term is created or updated via the REST API. + * + * @param WP_Term $term Inserted Term object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating term, false when updating. + */ + do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + return rest_ensure_response( $response ); + } + + /** + * Delete a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $term = get_term( (int) $request['id'], $taxonomy ); + // Get default category id. + $default_category_id = absint( get_option( 'default_product_cat', 0 ) ); + + // Prevent deleting the default product category. + if ( $default_category_id === (int) $request['id'] ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + + $retval = wp_delete_term( $term->term_id, $term->taxonomy ); + if ( ! $retval ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single term is deleted via the REST API. + * + * @param WP_Term $term The deleted term. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$taxonomy}", $term, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param object $term Term object. + * @param WP_REST_Request $request Full details about the request. + * @return array Links for the given term. + */ + protected function prepare_links( $term, $request ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + + if ( ! empty( $request['attribute_id'] ) ) { + $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); + } + + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $term->term_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + if ( $term->parent ) { + $parent_term = get_term( (int) $term->parent, $term->taxonomy ); + if ( $parent_term ) { + $links['up'] = array( + 'href' => rest_url( trailingslashit( $base ) . $parent_term->term_id ), + ); + } + } + + return $links; + } + + /** + * Update term meta fields. + * + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + return true; + } + + /** + * Get the terms attached to a product. + * + * This is an alternative to `get_terms()` that uses `get_the_terms()` + * instead, which hits the object cache. There are a few things not + * supported, notably `include`, `exclude`. In `self::get_items()` these + * are instead treated as a full query. + * + * @param array $prepared_args Arguments for `get_terms()`. + * @param WP_REST_Request $request Full details about the request. + * @return array List of term objects. (Total count in `$this->total_terms`). + */ + protected function get_terms_for_product( $prepared_args, $request ) { + $taxonomy = $this->get_taxonomy( $request ); + + $query_result = get_the_terms( $prepared_args['product'], $taxonomy ); + if ( empty( $query_result ) ) { + $this->total_terms = 0; + return array(); + } + + // get_items() verifies that we don't have `include` set, and default. + // ordering is by `name`. + if ( ! in_array( $prepared_args['orderby'], array( 'name', 'none', 'include' ), true ) ) { + switch ( $prepared_args['orderby'] ) { + case 'id': + $this->sort_column = 'term_id'; + break; + case 'slug': + case 'term_group': + case 'description': + case 'count': + $this->sort_column = $prepared_args['orderby']; + break; + } + usort( $query_result, array( $this, 'compare_terms' ) ); + } + if ( strtolower( $prepared_args['order'] ) !== 'asc' ) { + $query_result = array_reverse( $query_result ); + } + + // Pagination. + $this->total_terms = count( $query_result ); + $query_result = array_slice( $query_result, $prepared_args['offset'], $prepared_args['number'] ); + + return $query_result; + } + + /** + * Comparison function for sorting terms by a column. + * + * Uses `$this->sort_column` to determine field to sort by. + * + * @param stdClass $left Term object. + * @param stdClass $right Term object. + * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left. + */ + protected function compare_terms( $left, $right ) { + $col = $this->sort_column; + $left_val = $left->$col; + $right_val = $right->$col; + + if ( is_int( $left_val ) && is_int( $right_val ) ) { + return $left_val - $right_val; + } + + return strcmp( $left_val, $right_val ); + } + + /** + * Get the query params for collections + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + if ( '' !== $this->taxonomy && taxonomy_exists( $this->taxonomy ) ) { + $taxonomy = get_taxonomy( $this->taxonomy ); + } else { + $taxonomy = new stdClass(); + $taxonomy->hierarchical = true; + } + + $params['context']['default'] = 'view'; + + $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', + ); + if ( ! $taxonomy->hierarchical ) { + $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', + 'sanitize_callback' => 'sanitize_key', + 'default' => 'asc', + 'enum' => array( + 'asc', + 'desc', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by resource attribute.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'default' => 'name', + 'enum' => array( + 'id', + 'include', + 'name', + 'slug', + 'term_group', + 'description', + 'count', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['hide_empty'] = array( + 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'validate_callback' => 'rest_validate_request_arg', + ); + if ( $taxonomy->hierarchical ) { + $params['parent'] = array( + 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + } + $params['product'] = array( + 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['slug'] = array( + 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Get taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function get_taxonomy( $request ) { + // Check if taxonomy is defined. + // Prevents check for attribute taxonomy more than one time for each query. + if ( '' !== $this->taxonomy ) { + return $this->taxonomy; + } + + if ( ! empty( $request['attribute_id'] ) ) { + $taxonomy = wc_attribute_taxonomy_name_by_id( (int) $request['attribute_id'] ); + + $this->taxonomy = $taxonomy; + } + + return $this->taxonomy; + } +} diff --git a/includes/v1/class-wc-rest-api-v1.php b/includes/v1/class-wc-rest-api-v1.php new file mode 100644 index 00000000000..b5038186261 --- /dev/null +++ b/includes/v1/class-wc-rest-api-v1.php @@ -0,0 +1,75 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for coupons. + */ + public function register_routes() { + register_rest_route( $this->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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'required' => true, + 'type' => 'string', + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Query args. + * + * @param array $args Query args + * @param WP_REST_Request $request Request data. + * @return array + */ + public function query_args( $args, $request ) { + if ( ! empty( $request['code'] ) ) { + $id = wc_get_coupon_id_by_code( $request['code'] ); + $args['post__in'] = array( $id ); + } + + return $args; + } + + /** + * Prepare a single coupon output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $data + */ + public function prepare_item_for_response( $post, $request ) { + $coupon = new WC_Coupon( (int) $post->ID ); + $_data = $coupon->get_data(); + + $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); + $format_date = array( 'date_created', 'date_modified' ); + $format_date_utc = array( 'date_expires' ); + $format_null = array( 'usage_limit', 'usage_limit_per_user' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $_data[ $key ] = wc_format_decimal( $_data[ $key ], 2 ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ], false ) : null; + } + foreach ( $format_date_utc as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; + } + + // Format null values. + foreach ( $format_null as $key ) { + $_data[ $key ] = $_data[ $key ] ? $_data[ $key ] : null; + } + + $data = array( + 'id' => $_data['id'], + 'code' => $_data['code'], + 'date_created' => $_data['date_created'], + 'date_modified' => $_data['date_modified'], + 'discount_type' => $_data['discount_type'], + 'description' => $_data['description'], + 'amount' => $_data['amount'], + 'expiry_date' => $_data['date_expires'], + 'usage_count' => $_data['usage_count'], + 'individual_use' => $_data['individual_use'], + 'product_ids' => $_data['product_ids'], + 'exclude_product_ids' => $_data['excluded_product_ids'], + 'usage_limit' => $_data['usage_limit'], + 'usage_limit_per_user' => $_data['usage_limit_per_user'], + 'limit_usage_to_x_items' => $_data['limit_usage_to_x_items'], + 'free_shipping' => $_data['free_shipping'], + 'product_categories' => $_data['product_categories'], + 'excluded_product_categories' => $_data['excluded_product_categories'], + 'exclude_sale_items' => $_data['exclude_sale_items'], + 'minimum_amount' => $_data['minimum_amount'], + 'maximum_amount' => $_data['maximum_amount'], + 'email_restrictions' => $_data['email_restrictions'], + 'used_by' => $_data['used_by'], + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $post, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Only return writable props from schema. + * @param array $schema + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Prepare a single coupon for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $coupon = new WC_Coupon( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Update to schema to make compatible with CRUD schema. + if ( $request['exclude_product_ids'] ) { + $request['excluded_product_ids'] = $request['exclude_product_ids']; + } + if ( $request['expiry_date'] ) { + $request['date_expires'] = $request['expiry_date']; + } + + // Validate required POST fields. + if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { + if ( empty( $request['code'] ) ) { + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + } + } + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'code' : + $coupon_code = wc_format_coupon_code( $value ); + $id = $coupon->get_id() ? $coupon->get_id() : 0; + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon->set_code( $coupon_code ); + break; + case 'description' : + $coupon->set_description( wp_filter_post_kses( $value ) ); + break; + case 'expiry_date' : + $coupon->set_date_expires( $value ); + break; + default : + if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { + $coupon->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param WC_Coupon $coupon The coupon object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request ); + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $coupon_id = $this->save_coupon( $request ); + if ( is_wp_error( $coupon_id ) ) { + return $coupon_id; + } + + $post = get_post( $coupon_id ); + $this->update_additional_fields_for_object( $post, $request ); + + $this->add_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Update a single coupon. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon_id = $this->save_coupon( $request ); + if ( is_wp_error( $coupon_id ) ) { + return $coupon_id; + } + + $post = get_post( $coupon_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Saves a coupon to the database. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|int + */ + protected function save_coupon( $request ) { + try { + $coupon = $this->prepare_item_for_database( $request ); + + if ( is_wp_error( $coupon ) ) { + return $coupon; + } + + $coupon->save(); + return $coupon->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the Coupon's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Coupon description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'discount_type' => array( + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'fixed_cart', + 'enum' => array_keys( wc_get_coupon_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'amount' => array( + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'expiry_date' => array( + 'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'usage_count' => array( + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'individual_use' => array( + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_ids' => array( + 'description' => __( "List of product IDs the coupon can be used on.", 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'exclude_product_ids' => array( + 'description' => __( "List of product IDs the coupon cannot be used on.", 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit' => array( + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit_per_user' => array( + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'limit_usage_to_x_items' => array( + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'free_shipping' => array( + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_categories' => array( + 'description' => __( "List of category IDs the coupon applies to.", 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'excluded_product_categories' => array( + 'description' => __( "List of category IDs the coupon does not apply to.", 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'exclude_sale_items' => array( + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'minimum_amount' => array( + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'maximum_amount' => array( + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email_restrictions' => array( + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + 'used_by' => array( + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['code'] = array( + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v1/class-wc-rest-customer-downloads-v1-controller.php b/includes/v1/class-wc-rest-customer-downloads-v1-controller.php new file mode 100644 index 00000000000..7557161adef --- /dev/null +++ b/includes/v1/class-wc-rest-customer-downloads-v1-controller.php @@ -0,0 +1,252 @@ +/downloads endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Customers controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Controller + */ +class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'customers/(?P[\d]+)/downloads'; + + /** + * Register the routes for customers. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'customer_id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + 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' ), + ) ); + } + + /** + * Check whether a given request has permission to read customers. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $customer = get_user_by( 'id', (int) $request['customer_id'] ); + + if ( ! $customer ) { + return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_user_permissions( 'read', $customer->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all customer downloads. + * + * @param WP_REST_Request $request + * @return array + */ + public function get_items( $request ) { + $downloads = wc_get_customer_available_downloads( (int) $request['customer_id'] ); + + $data = array(); + foreach ( $downloads as $download_data ) { + $download = $this->prepare_item_for_response( (object) $download_data, $request ); + $download = $this->prepare_response_for_collection( $download ); + $data[] = $download; + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a single download output for response. + * + * @param stdObject $download Download object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $download, $request ) { + $data = (array) $download; + $data['access_expires'] = $data['access_expires'] ? wc_rest_prepare_date_response( $data['access_expires'] ) : 'never'; + $data['downloads_remaining'] = '' === $data['downloads_remaining'] ? 'unlimited' : $data['downloads_remaining']; + + // Remove "product_name" since it's new in 3.0. + unset( $data['product_name'] ); + + $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( $download, $request ) ); + + /** + * Filter customer download data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdObject $download Download object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $download Download object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given customer download. + */ + protected function prepare_links( $download, $request ) { + $base = str_replace( '(?P[\d]+)', $request['customer_id'], $this->rest_base ); + $links = array( + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'product' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $download->product_id ) ), + ), + 'order' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $download->order_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Customer Download's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer_download', + 'type' => 'object', + 'properties' => array( + 'download_url' => array( + 'description' => __( 'Download file URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_id' => array( + 'description' => __( 'Download ID (MD5).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Downloadable product ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_name' => array( + 'description' => __( 'Downloadable file name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_id' => array( + 'description' => __( 'Order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'downloads_remaining' => array( + 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'access_expires' => array( + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File details.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/includes/v1/class-wc-rest-customers-v1-controller.php b/includes/v1/class-wc-rest-customers-v1-controller.php new file mode 100644 index 00000000000..4659e60946b --- /dev/null +++ b/includes/v1/class-wc-rest-customers-v1-controller.php @@ -0,0 +1,924 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'New user email address.', 'woocommerce' ), + ), + 'username' => array( + 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), + 'description' => __( 'New user username.', 'woocommerce' ), + 'type' => 'string', + ), + 'password' => array( + 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), + 'description' => __( 'New user password.', 'woocommerce' ), + 'type' => 'string', + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + 'reassign' => array( + 'default' => 0, + 'type' => 'integer', + 'description' => __( 'ID to reassign posts to.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read customers. + * + * @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_user_permissions( 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create customers. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_user_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'read', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a customer. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'edit', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a customer. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'delete', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_user_permissions( 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all customers. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $prepared_args = array(); + $prepared_args['exclude'] = $request['exclude']; + $prepared_args['include'] = $request['include']; + $prepared_args['order'] = $request['order']; + $prepared_args['number'] = $request['per_page']; + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + $orderby_possibles = array( + 'id' => 'ID', + 'include' => 'include', + 'name' => 'display_name', + 'registered_date' => 'registered', + ); + $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; + $prepared_args['search'] = $request['search']; + + if ( '' !== $prepared_args['search'] ) { + $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; + } + + // Filter by email. + if ( ! empty( $request['email'] ) ) { + $prepared_args['search'] = $request['email']; + $prepared_args['search_columns'] = array( 'user_email' ); + } + + // Filter by role. + if ( 'all' !== $request['role'] ) { + $prepared_args['role'] = $request['role']; + } + + /** + * Filter arguments, before passing to WP_User_Query, when querying users via the REST API. + * + * @see https://developer.wordpress.org/reference/classes/wp_user_query/ + * + * @param array $prepared_args Array of arguments for WP_User_Query. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_customer_query', $prepared_args, $request ); + + $query = new WP_User_Query( $prepared_args ); + + $users = array(); + foreach ( $query->results as $user ) { + $data = $this->prepare_item_for_response( $user, $request ); + $users[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $users ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + $prepared_args['fields'] = 'ID'; + + $total_users = $query->get_total(); + if ( $total_users < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $prepared_args['number'] ); + unset( $prepared_args['offset'] ); + $count_query = new WP_User_Query( $prepared_args ); + $total_users = $count_query->get_total(); + } + $response->header( 'X-WP-Total', (int) $total_users ); + $max_pages = ceil( $total_users / $per_page ); + $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; + } + + /** + * Create a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + try { + if ( ! empty( $request['id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); + } + + // Sets the username. + $request['username'] = ! empty( $request['username'] ) ? $request['username'] : ''; + + // Sets the password. + $request['password'] = ! empty( $request['password'] ) ? $request['password'] : ''; + + // Create customer. + $customer = new WC_Customer; + $customer->set_username( $request['username'] ); + $customer->set_password( $request['password'] ); + $customer->set_email( $request['email'] ); + $this->update_customer_meta_fields( $customer, $request ); + $customer->save(); + + if ( ! $customer->get_id() ) { + throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); + } + + $user_data = get_userdata( $customer->get_id() ); + $this->update_additional_fields_for_object( $user_data, $request ); + + /** + * Fires after a customer is created or updated via the REST API. + * + * @param WP_User $user_data Data used to create the customer. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating customer, false when updating customer. + */ + do_action( 'woocommerce_rest_insert_customer', $user_data, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ) ); + + return $response; + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $user_data = get_userdata( $id ); + + if ( empty( $id ) || empty( $user_data->ID ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $customer = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $customer ); + + return $response; + } + + /** + * Update a single user. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $id = (int) $request['id']; + $customer = new WC_Customer( $id ); + + if ( ! $customer->get_id() ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); + } + + if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->get_email() ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); + } + + if ( ! empty( $request['username'] ) && $request['username'] !== $customer->get_username() ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); + } + + // Customer email. + if ( isset( $request['email'] ) ) { + $customer->set_email( sanitize_email( $request['email'] ) ); + } + + // Customer password. + if ( isset( $request['password'] ) ) { + $customer->set_password( $request['password'] ); + } + + $this->update_customer_meta_fields( $customer, $request ); + $customer->save(); + + $user_data = get_userdata( $customer->get_id() ); + $this->update_additional_fields_for_object( $user_data, $request ); + + if ( ! is_user_member_of_blog( $user_data->ID ) ) { + $user_data->add_role( 'customer' ); + } + + /** + * Fires after a customer is created or updated via the REST API. + * + * @param WP_User $customer Data used to create the customer. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating customer, false when updating customer. + */ + do_action( 'woocommerce_rest_insert_customer', $user_data, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $response ); + return $response; + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $reassign = isset( $request['reassign'] ) ? absint( $request['reassign'] ) : null; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $user_data = get_userdata( $id ); + if ( ! $user_data ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + if ( ! empty( $reassign ) ) { + if ( $reassign === $id || ! get_userdata( $reassign ) ) { + return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + + /** Include admin customer functions to get access to wp_delete_user() */ + require_once ABSPATH . 'wp-admin/includes/user.php'; + + $customer = new WC_Customer( $id ); + + if ( ! is_null( $reassign ) ) { + $result = $customer->delete_and_reassign( $reassign ); + } else { + $result = $customer->delete(); + } + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a customer is deleted via the REST API. + * + * @param WP_User $user_data User data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_customer', $user_data, $response, $request ); + + return $response; + } + + /** + * Prepare a single customer output for response. + * + * @param WP_User $user_data User object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $user_data, $request ) { + $customer = new WC_Customer( $user_data->ID ); + $_data = $customer->get_data(); + $last_order = wc_get_customer_last_order( $customer->get_id() ); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; // v1 API used UTC. + } + + $data = array( + 'id' => $_data['id'], + 'date_created' => $_data['date_created'], + 'date_modified' => $_data['date_modified'], + 'email' => $_data['email'], + 'first_name' => $_data['first_name'], + 'last_name' => $_data['last_name'], + 'username' => $_data['username'], + 'last_order' => array( + 'id' => is_object( $last_order ) ? $last_order->get_id() : null, + 'date' => is_object( $last_order ) ? wc_rest_prepare_date_response( $last_order->get_date_created() ) : null, // v1 API used UTC. + ), + 'orders_count' => $customer->get_order_count(), + 'total_spent' => $customer->get_total_spent(), + 'avatar_url' => $customer->get_avatar_url(), + 'billing' => $_data['billing'], + 'shipping' => $_data['shipping'], + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $user_data ) ); + + /** + * Filter customer data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_User $user_data User object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); + } + + /** + * Update customer meta fields. + * + * @param WC_Customer $customer + * @param WP_REST_Request $request + */ + protected function update_customer_meta_fields( $customer, $request ) { + $schema = $this->get_item_schema(); + + // Customer first name. + if ( isset( $request['first_name'] ) ) { + $customer->set_first_name( wc_clean( $request['first_name'] ) ); + } + + // Customer last name. + if ( isset( $request['last_name'] ) ) { + $customer->set_last_name( wc_clean( $request['last_name'] ) ); + } + + // Customer billing address. + if ( isset( $request['billing'] ) ) { + foreach ( array_keys( $schema['properties']['billing']['properties'] ) as $field ) { + if ( isset( $request['billing'][ $field ] ) && is_callable( array( $customer, "set_billing_{$field}" ) ) ) { + $customer->{"set_billing_{$field}"}( $request['billing'][ $field ] ); + } + } + } + + // Customer shipping address. + if ( isset( $request['shipping'] ) ) { + foreach ( array_keys( $schema['properties']['shipping']['properties'] ) as $field ) { + if ( isset( $request['shipping'][ $field ] ) && is_callable( array( $customer, "set_shipping_{$field}" ) ) ) { + $customer->{"set_shipping_{$field}"}( $request['shipping'][ $field ] ); + } + } + } + } + + /** + * Prepare links for the request. + * + * @param WP_User $customer Customer object. + * @return array Links for the given customer. + */ + protected function prepare_links( $customer ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Customer's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'email' => array( + 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'first_name' => array( + 'description' => __( 'Customer first name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'last_name' => array( + 'description' => __( 'Customer last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'username' => array( + 'description' => __( 'Customer login name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_user', + ), + ), + 'password' => array( + 'description' => __( 'Customer password.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'last_order' => array( + 'description' => __( 'Last order data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => array( + 'id' => array( + 'description' => __( 'Last order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date' => array( + 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + 'orders_count' => array( + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_spent' => array( + 'description' => __( 'Total amount spent.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avatar_url' => array( + 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'billing' => array( + 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get role names. + * + * @return array + */ + protected function get_role_names() { + global $wp_roles; + + return array_keys( $wp_roles->role_names ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $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( + 'default' => 'asc', + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'enum' => array( 'asc', 'desc' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'default' => 'name', + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'enum' => array( + 'id', + 'include', + 'name', + 'registered_date', + ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['email'] = array( + 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['role'] = array( + 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'customer', + 'enum' => array_merge( array( 'all' ), $this->get_role_names() ), + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } +} diff --git a/includes/v1/class-wc-rest-order-notes-v1-controller.php b/includes/v1/class-wc-rest-order-notes-v1-controller.php new file mode 100644 index 00000000000..976a295bf7a --- /dev/null +++ b/includes/v1/class-wc-rest-order-notes-v1-controller.php @@ -0,0 +1,439 @@ +/notes endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Order Notes controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Controller + */ +class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'orders/(?P[\d]+)/notes'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'shop_order'; + + /** + * Register the routes for order notes. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'note' => array( + 'type' => 'string', + 'description' => __( 'Order note content.', 'woocommerce' ), + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read order 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_post_permissions( $this->post_type, 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create order notes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a order note. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get order notes from an order. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $args = array( + 'post_id' => $order->get_id(), + 'approve' => 'approve', + 'type' => 'order_note', + ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $data = array(); + foreach ( $notes as $note ) { + $order_note = $this->prepare_item_for_response( $note, $request ); + $order_note = $this->prepare_response_for_collection( $order_note ); + $data[] = $order_note; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Create the note. + $note_id = $order->add_order_note( $request['note'], $request['customer_note'] ); + + if ( ! $note_id ) { + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $note = get_comment( $note_id ); + $this->update_additional_fields_for_object( $note, $request ); + + /** + * Fires after a order note is created or updated via the REST API. + * + * @param WP_Comment $note New order note object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $note, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); + + return $response; + } + + /** + * Get a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $note = get_comment( $id ); + + if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $order_note = $this->prepare_item_for_response( $note, $request ); + $response = rest_ensure_response( $order_note ); + + return $response; + } + + /** + * Delete a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $note = get_comment( $id ); + + if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $note, $request ); + + $result = wc_delete_order_note( $note->comment_ID ); + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a order note is deleted or trashed via the REST API. + * + * @param WP_Comment $note The deleted or trashed order note. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_order_note', $note, $response, $request ); + + return $response; + } + + /** + * Prepare a single order note output for response. + * + * @param WP_Comment $note Order note object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $note, $request ) { + $data = array( + 'id' => (int) $note->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + $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( $note ) ); + + /** + * Filter order note object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $note Order note object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $note Delivery order_note object. + * @return array Links for the given order note. + */ + protected function prepare_links( $note ) { + $order_id = (int) $note->comment_post_ID; + $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $note->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Order Notes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'order_note', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'note' => array( + 'description' => __( 'Order note.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_note' => array( + 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/includes/v1/class-wc-rest-order-refunds-v1-controller.php b/includes/v1/class-wc-rest-order-refunds-v1-controller.php new file mode 100644 index 00000000000..4b4bfa037ef --- /dev/null +++ b/includes/v1/class-wc-rest-order-refunds-v1-controller.php @@ -0,0 +1,530 @@ +/refunds endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @since 2.6.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Order Refunds controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Orders_V1_Controller + */ +class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'orders/(?P[\d]+)/refunds'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'shop_order_refund'; + + /** + * Order refunds actions. + */ + public function __construct() { + add_filter( "woocommerce_rest_{$this->post_type}_trashable", '__return_false' ); + add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for order refunds. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Prepare a single order refund output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * + * @return WP_Error|WP_REST_Response + */ + public function prepare_item_for_response( $post, $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + $refund = wc_get_order( $post ); + + if ( ! $refund || $refund->get_parent_id() !== $order->get_id() ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + } + + $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); + + $data = array( + 'id' => $refund->get_id(), + 'date_created' => wc_rest_prepare_date_response( $refund->get_date_created() ), + 'amount' => wc_format_decimal( $refund->get_amount(), $dp ), + 'reason' => $refund->get_reason(), + 'line_items' => array(), + ); + + // Add line items. + foreach ( $refund->get_items() as $item_id => $item ) { + $product = $refund->get_product_from_item( $item ); + $product_id = 0; + $variation_id = 0; + $product_sku = null; + + // Check if the product exists. + if ( is_object( $product ) ) { + $product_id = $item->get_product_id(); + $variation_id = $item->get_variation_id(); + $product_sku = $product->get_sku(); + } + + $item_meta = array(); + + $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; + + foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { + $item_meta[] = array( + 'key' => $formatted_meta->key, + 'label' => $formatted_meta->display_key, + 'value' => wc_clean( $formatted_meta->display_value ), + ); + } + + $line_item = array( + 'id' => $item_id, + 'name' => $item['name'], + 'sku' => $product_sku, + 'product_id' => (int) $product_id, + 'variation_id' => (int) $variation_id, + 'quantity' => wc_stock_amount( $item['qty'] ), + 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', + 'price' => wc_format_decimal( $refund->get_item_total( $item, false, false ), $dp ), + 'subtotal' => wc_format_decimal( $refund->get_line_subtotal( $item, false, false ), $dp ), + 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), + 'total' => wc_format_decimal( $refund->get_line_total( $item, false, false ), $dp ), + 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), + 'taxes' => array(), + 'meta' => $item_meta, + ); + + $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); + if ( isset( $item_line_taxes['total'] ) ) { + $line_tax = array(); + + foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + + $line_item['taxes'] = array_values( $line_tax ); + } + + $data['line_items'][] = $line_item; + } + + $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( $refund, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Order_Refund $refund Comment object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given order refund. + */ + protected function prepare_links( $refund, $request ) { + $order_id = $refund->get_parent_id(); + $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $refund->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), + ), + ); + + return $links; + } + + /** + * Query args. + * + * @param array $args Request args. + * @param WP_REST_Request $request Request object. + * @return array + */ + public function query_args( $args, $request ) { + $args['post_status'] = array_keys( wc_get_order_statuses() ); + $args['post_parent__in'] = array( absint( $request['order_id'] ) ); + + return $args; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order_data = get_post( (int) $request['order_id'] ); + + if ( empty( $order_data ) ) { + return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); + } + + if ( 0 > $request['amount'] ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + } + + // Create the refund. + $refund = wc_create_refund( array( + 'order_id' => $order_data->ID, + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) ); + + if ( is_wp_error( $refund ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + } + + if ( ! $refund ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + $post = get_post( $refund->get_id() ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'amount' => array( + 'description' => __( 'Refund amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'reason' => array( + 'description' => __( 'Reason for refund.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta' => array( + 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Meta label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + '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 = parent::get_collection_params(); + + $params['dp'] = array( + 'default' => wc_get_price_decimals(), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v1/class-wc-rest-orders-v1-controller.php b/includes/v1/class-wc-rest-orders-v1-controller.php new file mode 100644 index 00000000000..d03863c3bbd --- /dev/null +++ b/includes/v1/class-wc-rest-orders-v1-controller.php @@ -0,0 +1,1629 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for orders. + */ + public function register_routes() { + register_rest_route( $this->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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Prepare a single order output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $data + */ + public function prepare_item_for_response( $post, $request ) { + $order = wc_get_order( $post ); + $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); + + $data = array( + 'id' => $order->get_id(), + 'parent_id' => $order->get_parent_id(), + 'status' => $order->get_status(), + 'order_key' => $order->get_order_key(), + 'number' => $order->get_order_number(), + 'currency' => $order->get_currency(), + 'version' => $order->get_version(), + 'prices_include_tax' => $order->get_prices_include_tax(), + 'date_created' => wc_rest_prepare_date_response( $order->get_date_created() ), // v1 API used UTC. + 'date_modified' => wc_rest_prepare_date_response( $order->get_date_modified() ), // v1 API used UTC. + 'customer_id' => $order->get_customer_id(), + 'discount_total' => wc_format_decimal( $order->get_total_discount(), $dp ), + 'discount_tax' => wc_format_decimal( $order->get_discount_tax(), $dp ), + 'shipping_total' => wc_format_decimal( $order->get_shipping_total(), $dp ), + 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), $dp ), + 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), $dp ), + 'total' => wc_format_decimal( $order->get_total(), $dp ), + 'total_tax' => wc_format_decimal( $order->get_total_tax(), $dp ), + 'billing' => array(), + 'shipping' => array(), + 'payment_method' => $order->get_payment_method(), + 'payment_method_title' => $order->get_payment_method_title(), + 'transaction_id' => $order->get_transaction_id(), + 'customer_ip_address' => $order->get_customer_ip_address(), + 'customer_user_agent' => $order->get_customer_user_agent(), + 'created_via' => $order->get_created_via(), + 'customer_note' => $order->get_customer_note(), + 'date_completed' => wc_rest_prepare_date_response( $order->get_date_completed(), false ), // v1 API used local time. + 'date_paid' => wc_rest_prepare_date_response( $order->get_date_paid(), false ), // v1 API used local time. + 'cart_hash' => $order->get_cart_hash(), + 'line_items' => array(), + 'tax_lines' => array(), + 'shipping_lines' => array(), + 'fee_lines' => array(), + 'coupon_lines' => array(), + 'refunds' => array(), + ); + + // Add addresses. + $data['billing'] = $order->get_address( 'billing' ); + $data['shipping'] = $order->get_address( 'shipping' ); + + // Add line items. + foreach ( $order->get_items() as $item_id => $item ) { + $product = $order->get_product_from_item( $item ); + $product_id = 0; + $variation_id = 0; + $product_sku = null; + + // Check if the product exists. + if ( is_object( $product ) ) { + $product_id = $item->get_product_id(); + $variation_id = $item->get_variation_id(); + $product_sku = $product->get_sku(); + } + + $item_meta = array(); + + $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; + + foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { + $item_meta[] = array( + 'key' => $formatted_meta->key, + 'label' => $formatted_meta->display_key, + 'value' => wc_clean( $formatted_meta->display_value ), + ); + } + + $line_item = array( + 'id' => $item_id, + 'name' => $item['name'], + 'sku' => $product_sku, + 'product_id' => (int) $product_id, + 'variation_id' => (int) $variation_id, + 'quantity' => wc_stock_amount( $item['qty'] ), + 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', + 'price' => wc_format_decimal( $order->get_item_total( $item, false, false ), $dp ), + 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item, false, false ), $dp ), + 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), + 'total' => wc_format_decimal( $order->get_line_total( $item, false, false ), $dp ), + 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), + 'taxes' => array(), + 'meta' => $item_meta, + ); + + $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); + if ( isset( $item_line_taxes['total'] ) ) { + $line_tax = array(); + + foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + + $line_item['taxes'] = array_values( $line_tax ); + } + + $data['line_items'][] = $line_item; + } + + // Add taxes. + foreach ( $order->get_items( 'tax' ) as $key => $tax ) { + $tax_line = array( + 'id' => $key, + 'rate_code' => $tax['name'], + 'rate_id' => $tax['rate_id'], + 'label' => isset( $tax['label'] ) ? $tax['label'] : $tax['name'], + 'compound' => (bool) $tax['compound'], + 'tax_total' => wc_format_decimal( $tax['tax_amount'], $dp ), + 'shipping_tax_total' => wc_format_decimal( $tax['shipping_tax_amount'], $dp ), + ); + + $data['tax_lines'][] = $tax_line; + } + + // Add shipping. + foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { + $shipping_line = array( + 'id' => $shipping_item_id, + 'method_title' => $shipping_item['name'], + 'method_id' => $shipping_item['method_id'], + 'total' => wc_format_decimal( $shipping_item['cost'], $dp ), + 'total_tax' => wc_format_decimal( '', $dp ), + 'taxes' => array(), + ); + + $shipping_taxes = $shipping_item->get_taxes(); + + if ( ! empty( $shipping_taxes['total'] ) ) { + $shipping_line['total_tax'] = wc_format_decimal( array_sum( $shipping_taxes['total'] ), $dp ); + + foreach ( $shipping_taxes['total'] as $tax_rate_id => $tax ) { + $shipping_line['taxes'][] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + ); + } + } + + $data['shipping_lines'][] = $shipping_line; + } + + // Add fees. + foreach ( $order->get_fees() as $fee_item_id => $fee_item ) { + $fee_line = array( + 'id' => $fee_item_id, + 'name' => $fee_item['name'], + 'tax_class' => ! empty( $fee_item['tax_class'] ) ? $fee_item['tax_class'] : '', + 'tax_status' => 'taxable', + 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), $dp ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), $dp ), + 'taxes' => array(), + ); + + $fee_line_taxes = maybe_unserialize( $fee_item['line_tax_data'] ); + if ( isset( $fee_line_taxes['total'] ) ) { + $fee_tax = array(); + + foreach ( $fee_line_taxes['total'] as $tax_rate_id => $tax ) { + $fee_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + if ( isset( $fee_line_taxes['subtotal'] ) ) { + foreach ( $fee_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $fee_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + } + + $fee_line['taxes'] = array_values( $fee_tax ); + } + + $data['fee_lines'][] = $fee_line; + } + + // Add coupons. + foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) { + $coupon_line = array( + 'id' => $coupon_item_id, + 'code' => $coupon_item['name'], + 'discount' => wc_format_decimal( $coupon_item['discount_amount'], $dp ), + 'discount_tax' => wc_format_decimal( $coupon_item['discount_amount_tax'], $dp ), + ); + + $data['coupon_lines'][] = $coupon_line; + } + + // Add refunds. + foreach ( $order->get_refunds() as $refund ) { + $data['refunds'][] = array( + 'id' => $refund->get_id(), + 'refund' => $refund->get_reason() ? $refund->get_reason() : '', + 'total' => '-' . wc_format_decimal( $refund->get_amount(), $dp ), + ); + } + + $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( $order, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Order $order Order object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given order. + */ + protected function prepare_links( $order, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $order->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + if ( 0 !== (int) $order->get_user_id() ) { + $links['customer'] = array( + 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $order->get_user_id() ) ), + ); + } + if ( 0 !== (int) $order->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order->get_parent_id() ) ), + ); + } + return $links; + } + + /** + * Query args. + * + * @param array $args + * @param WP_REST_Request $request + * @return array + */ + public function query_args( $args, $request ) { + global $wpdb; + + // Set post_status. + if ( 'any' !== $request['status'] ) { + $args['post_status'] = 'wc-' . $request['status']; + } else { + $args['post_status'] = 'any'; + } + + if ( isset( $request['customer'] ) ) { + if ( ! empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); + } + + $args['meta_query'][] = array( + 'key' => '_customer_user', + 'value' => $request['customer'], + 'type' => 'NUMERIC', + ); + } + + // Search by product. + if ( ! empty( $request['product'] ) ) { + $order_ids = $wpdb->get_col( $wpdb->prepare( " + SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item' + ", $request['product'] ) ); + + // Force WP_Query return empty if don't found any order. + $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); + + $args['post__in'] = $order_ids; + } + + // Search. + if ( ! empty( $args['s'] ) ) { + $order_ids = wc_order_search( $args['s'] ); + + if ( ! empty( $order_ids ) ) { + unset( $args['s'] ); + $args['post__in'] = array_merge( $order_ids, array( 0 ) ); + } + } + + return $args; + } + + /** + * Prepare a single order for create. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|WC_Order $data Object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $order = new WC_Order( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Handle all writable props + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'billing' : + case 'shipping' : + $this->update_address( $order, $value, $key ); + break; + case 'line_items' : + case 'shipping_lines' : + case 'fee_lines' : + case 'coupon_lines' : + if ( is_array( $value ) ) { + foreach ( $value as $item ) { + if ( is_array( $item ) ) { + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $order->remove_item( $item['id'] ); + } else { + $this->set_item( $order, $key, $item ); + } + } + } + } + break; + default : + if ( is_callable( array( $order, "set_{$key}" ) ) ) { + $order->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filter the data for the insert. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WC_Order $order The order object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $order, $request ); + } + + /** + * Create base WC Order object. + * @deprecated 3.0.0 + * @param array $data + * @return WC_Order + */ + protected function create_base_order( $data ) { + return wc_create_order( $data ); + } + + /** + * Only return writable props from schema. + * @param array $schema + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Create order. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function create_order( $request ) { + try { + // Make sure customer exists. + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] && false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } + + $order = $this->prepare_item_for_database( $request ); + $order->set_created_via( 'rest-api' ); + $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $order->calculate_totals(); + $order->save(); + + // Handle set paid. + if ( true === $request['set_paid'] ) { + $order->payment_complete( $request['transaction_id'] ); + } + + return $order->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update order. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function update_order( $request ) { + try { + $order = $this->prepare_item_for_database( $request ); + $order->save(); + + // Handle set paid. + if ( $order->needs_payment() && true === $request['set_paid'] ) { + $order->payment_complete( $request['transaction_id'] ); + } + + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $order->calculate_totals( true ); + } + + return $order->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update address. + * + * @param WC_Order $order + * @param array $posted + * @param string $type + */ + protected function update_address( $order, $posted, $type = 'billing' ) { + foreach ( $posted as $key => $value ) { + if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { + $order->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Gets the product ID from the SKU or posted ID. + * + * @param array $posted Request data + * + * @return int + * @throws WC_REST_Exception + */ + protected function get_product_id( $posted ) { + if ( ! empty( $posted['sku'] ) ) { + $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); + } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['product_id']; + } elseif ( ! empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['variation_id']; + } else { + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + } + return $product_id; + } + + /** + * Maybe set an item prop if the value was posted. + * @param WC_Order_Item $item + * @param string $prop + * @param array $posted Request data. + */ + protected function maybe_set_item_prop( $item, $prop, $posted ) { + if ( isset( $posted[ $prop ] ) ) { + $item->{"set_$prop"}( $posted[ $prop ] ); + } + } + + /** + * Maybe set item props if the values were posted. + * @param WC_Order_Item $item + * @param string[] $props + * @param array $posted Request data. + */ + protected function maybe_set_item_props( $item, $props, $posted ) { + foreach ( $props as $prop ) { + $this->maybe_set_item_prop( $item, $prop, $posted ); + } + } + + /** + * Create or update a line item. + * + * @param array $posted Line item data. + * @param string $action 'create' to add line item or 'update' to update it. + * + * @return WC_Order_Item_Product + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_line_items( $posted, $action = 'create' ) { + $item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + $product = wc_get_product( $this->get_product_id( $posted ) ); + + if ( $product !== $item->get_product() ) { + $item->set_product( $product ); + + if ( 'create' === $action ) { + $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; + $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); + $item->set_total( $total ); + $item->set_subtotal( $total ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); + + return $item; + } + + /** + * Create or update an order shipping method. + * + * @param $posted $shipping Item data. + * @param string $action 'create' to add shipping or 'update' to update it. + * + * @return WC_Order_Item_Shipping + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_shipping_lines( $posted, $action ) { + $item = new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['method_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); + + return $item; + } + + /** + * Create or update an order fee. + * + * @param array $posted Item data. + * @param string $action 'create' to add fee or 'update' to update it. + * + * @return WC_Order_Item_Fee + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_fee_lines( $posted, $action ) { + $item = new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['name'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); + + return $item; + } + + /** + * Create or update an order coupon. + * + * @param array $posted Item data. + * @param string $action 'create' to add coupon or 'update' to update it. + * + * @return WC_Order_Item_Coupon + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_coupon_lines( $posted, $action ) { + $item = new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['code'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); + + return $item; + } + + /** + * Wrapper method to create/update order items. + * When updating, the item ID provided is checked to ensure it is associated + * with the order. + * + * @param WC_Order $order order + * @param string $item_type + * @param array $posted item provided in the request body + * @throws WC_REST_Exception If item ID is not associated with order + */ + protected function set_item( $order, $item_type, $posted ) { + global $wpdb; + + if ( ! empty( $posted['id'] ) ) { + $action = 'update'; + } else { + $action = 'create'; + } + + $method = 'prepare_' . $item_type; + + // Verify provided line item ID is associated with order. + if ( 'update' === $action ) { + $result = $wpdb->get_row( + $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d", + absint( $posted['id'] ), + absint( $order->get_id() ) + ) ); + if ( is_null( $result ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + } + } + + // Prepare item data + $item = $this->$method( $posted, $action ); + + /** + * Action hook to adjust item before save. + * @since 3.0.0 + */ + do_action( 'woocommerce_rest_set_order_item', $item, $posted ); + + // Save or add to order + if ( 'create' === $action ) { + $order->add_item( $item ); + } else { + $item->save(); + } + } + + /** + * Helper method to check if the resource ID associated with the provided item is null. + * Items can be deleted by setting the resource ID to null. + * + * @param array $item Item provided in the request body. + * @return bool True if the item resource ID is null, false otherwise. + */ + protected function item_is_null( $item ) { + $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); + + foreach ( $keys as $key ) { + if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { + return true; + } + } + + return false; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order_id = $this->create_order( $request ); + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $post = get_post( $order_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Update a single order. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $order_id = $this->update_order( $request ); + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $post = get_post( $order_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get order statuses without prefixes. + * @return array + */ + protected function get_order_statuses() { + $order_statuses = array(); + + foreach ( array_keys( wc_get_order_statuses() ) as $status ) { + $order_statuses[] = str_replace( 'wc-', '', $status ); + } + + return $order_statuses; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + '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' => __( 'Parent order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Order status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'pending', + 'enum' => $this->get_order_statuses(), + 'context' => array( 'view', 'edit' ), + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'number' => array( + 'description' => __( 'Order number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'currency' => array( + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), + 'type' => 'string', + 'default' => get_woocommerce_currency(), + 'enum' => array_keys( get_woocommerce_currencies() ), + 'context' => array( 'view', 'edit' ), + ), + 'version' => array( + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'prices_include_tax' => array( + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order was created, as GMT.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_id' => array( + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 0, + 'context' => array( 'view', 'edit' ), + ), + 'discount_total' => array( + 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_tax' => array( + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_total' => array( + 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax' => array( + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_tax' => array( + 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Grand total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Sum of all taxes.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'billing' => array( + 'description' => __( 'Billing address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'Shipping address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'payment_method' => array( + 'description' => __( 'Payment method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'payment_method_title' => array( + 'description' => __( 'Payment method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'set_paid' => array( + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), + 'transaction_id' => array( + 'description' => __( 'Unique transaction ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_ip_address' => array( + 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_user_agent' => array( + 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'created_via' => array( + 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_note' => array( + 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_completed' => array( + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_paid' => array( + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_hash' => array( + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta' => array( + 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Meta label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'tax_lines' => array( + 'description' => __( 'Tax lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_code' => array( + 'description' => __( 'Tax rate code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Tax rate label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'compound' => array( + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_total' => array( + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax_total' => array( + 'description' => __( 'Shipping tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'shipping_lines' => array( + 'description' => __( 'Shipping lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_title' => array( + 'description' => __( 'Shipping method name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'fee_lines' => array( + 'description' => __( 'Fee lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Fee name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'taxable', 'none' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'coupon_lines' => array( + 'description' => __( 'Coupons line data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'discount' => array( + 'description' => __( 'Discount total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'discount_tax' => array( + 'description' => __( 'Discount total tax.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'refunds' => array( + 'description' => __( 'List of refunds.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Refund ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reason' => array( + 'description' => __( 'Refund reason.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Refund total.', 'woocommerce' ), + 'type' => 'string', + '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 = parent::get_collection_params(); + + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any' ), $this->get_order_statuses() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['customer'] = array( + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['product'] = array( + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['dp'] = array( + 'default' => wc_get_price_decimals(), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v1/class-wc-rest-product-attribute-terms-v1-controller.php b/includes/v1/class-wc-rest-product-attribute-terms-v1-controller.php new file mode 100644 index 00000000000..d40b90877d8 --- /dev/null +++ b/includes/v1/class-wc-rest-product-attribute-terms-v1-controller.php @@ -0,0 +1,240 @@ +/terms endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Product Attribute Terms controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Terms_Controller + */ +class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/attributes/(?P[\d]+)/terms'; + + /** + * Register the routes for terms. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'type' => 'string', + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + )); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Prepare a single product attribute term output for response. + * + * @param WP_Term $item Term object. + * @param WP_REST_Request $request + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + // Get term order. + $menu_order = get_term_meta( $item->term_id, 'order_' . $this->taxonomy, true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Update term meta fields. + * + * @param WP_Term $term + * @param WP_REST_Request $request + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + $id = (int) $term->term_id; + + update_term_meta( $id, 'order_' . $this->taxonomy, $request['menu_order'] ); + + return true; + } + + /** + * Get the Attribute Term's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_attribute_term', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v1/class-wc-rest-product-attributes-v1-controller.php b/includes/v1/class-wc-rest-product-attributes-v1-controller.php new file mode 100644 index 00000000000..e4290657e1d --- /dev/null +++ b/includes/v1/class-wc-rest-product-attributes-v1-controller.php @@ -0,0 +1,586 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'type' => 'string', + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + )); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check if a given request has access to read the attributes. + * + * @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( 'attributes', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'attributes', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'attributes', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all attributes. + * + * @param WP_REST_Request $request + * @return array + */ + public function get_items( $request ) { + $attributes = wc_get_attribute_taxonomies(); + $data = array(); + foreach ( $attributes as $attribute_obj ) { + $attribute = $this->prepare_item_for_response( $attribute_obj, $request ); + $attribute = $this->prepare_response_for_collection( $attribute ); + $data[] = $attribute; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + global $wpdb; + + $id = wc_create_attribute( array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => ! empty( $request['type'] ) ? $request['type'] : 'select', + 'order_by' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', + 'has_archives' => true === $request['has_archives'], + ) ); + + // Checks for errors. + if ( is_wp_error( $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', $id->get_error_message(), array( 'status' => 400 ) ); + } + + $attribute = $this->get_attribute( $id ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $this->update_additional_fields_for_object( $attribute, $request ); + + /** + * Fires after a single product attribute is created or updated via the REST API. + * + * @param stdObject $attribute Inserted attribute object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating attribute, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( '/' . $this->namespace . '/' . $this->rest_base . '/' . $attribute->attribute_id ) ); + + return $response; + } + + /** + * Get a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function get_item( $request ) { + $attribute = $this->get_attribute( (int) $request['id'] ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $response = $this->prepare_item_for_response( $attribute, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Update a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + global $wpdb; + + $id = (int) $request['id']; + $edited = wc_update_attribute( $id, array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => $request['type'], + 'order_by' => $request['order_by'], + 'has_archives' => $request['has_archives'], + ) ); + + // Checks for errors. + if ( is_wp_error( $edited ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', $edited->get_error_message(), array( 'status' => 400 ) ); + } + + $attribute = $this->get_attribute( $id ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $this->update_additional_fields_for_object( $attribute, $request ); + + /** + * Fires after a single product attribute is created or updated via the REST API. + * + * @param stdObject $attribute Inserted attribute object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating attribute, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $attribute = $this->get_attribute( (int) $request['id'] ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + + $deleted = wc_delete_attribute( $attribute->attribute_id ); + + if ( false === $deleted ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single attribute is deleted via the REST API. + * + * @param stdObject $attribute The deleted attribute. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_product_attribute', $attribute, $response, $request ); + + return $response; + } + + /** + * Prepare a single product attribute output for response. + * + * @param obj $item Term object. + * @param WP_REST_Request $request + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $data = array( + 'id' => (int) $item->attribute_id, + 'name' => $item->attribute_label, + 'slug' => wc_attribute_taxonomy_name( $item->attribute_name ), + 'type' => $item->attribute_type, + 'order_by' => $item->attribute_orderby, + 'has_archives' => (bool) $item->attribute_public, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter a attribute item returned from the API. + * + * Allows modification of the product attribute data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original attribute object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_product_attribute', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $attribute Attribute object. + * @return array Links for the given attribute. + */ + protected function prepare_links( $attribute ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $attribute->attribute_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Attribute's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_attribute', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'type' => array( + 'description' => __( 'Type of attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'select', + 'enum' => array_keys( wc_get_attribute_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'order_by' => array( + 'description' => __( 'Default sort order.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'menu_order', + 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ), + 'context' => array( 'view', 'edit' ), + ), + 'has_archives' => array( + 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + 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; + } + + /** + * Get attribute name. + * + * @param WP_REST_Request $request Full details about the request. + * @return string + */ + protected function get_taxonomy( $request ) { + if ( '' !== $this->attribute ) { + return $this->attribute; + } + + if ( $request['id'] ) { + $name = wc_attribute_taxonomy_name_by_id( (int) $request['id'] ); + + $this->attribute = $name; + } + + return $this->attribute; + } + + /** + * Get attribute data. + * + * @param int $id Attribute ID. + * @return stdClass|WP_Error + */ + protected function get_attribute( $id ) { + global $wpdb; + + $attribute = $wpdb->get_row( $wpdb->prepare( " + SELECT * + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); + + if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { + return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return $attribute; + } + + /** + * Validate attribute slug. + * + * @deprecated 3.2.0 + * @param string $slug + * @param bool $new_data + * @return bool|WP_Error + */ + protected function validate_attribute_slug( $slug, $new_data = true ) { + if ( strlen( $slug ) >= 28 ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } + + return true; + } + + /** + * Schedule to flush rewrite rules. + * + * @deprecated 3.2.0 + * @since 3.0.0 + */ + protected function flush_rewrite_rules() { + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); + } +} diff --git a/includes/v1/class-wc-rest-product-categories-v1-controller.php b/includes/v1/class-wc-rest-product-categories-v1-controller.php new file mode 100644 index 00000000000..9f12ee2a932 --- /dev/null +++ b/includes/v1/class-wc-rest-product-categories-v1-controller.php @@ -0,0 +1,271 @@ +term_id, 'display_type', true ); + + // Get category order. + $menu_order = get_term_meta( $item->term_id, 'order', true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'parent' => (int) $item->parent, + 'description' => $item->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => null, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + // Get category image. + $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); + if ( $image_id ) { + $attachment = get_post( $image_id ); + + $data['image'] = array( + 'id' => (int) $image_id, + 'date_created' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), + 'src' => wp_get_attachment_url( $image_id ), + 'title' => get_the_title( $attachment ), + 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Update term meta fields. + * + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Request instance. + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + $id = (int) $term->term_id; + + if ( isset( $request['display'] ) ) { + update_term_meta( $id, 'display_type', 'default' === $request['display'] ? '' : $request['display'] ); + } + + if ( isset( $request['menu_order'] ) ) { + update_term_meta( $id, 'order', $request['menu_order'] ); + } + + if ( isset( $request['image'] ) ) { + if ( empty( $request['image']['id'] ) && ! empty( $request['image']['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $request['image']['src'] ) ); + + if ( is_wp_error( $upload ) ) { + return $upload; + } + + $image_id = wc_rest_set_uploaded_image_as_attachment( $upload ); + } else { + $image_id = isset( $request['image']['id'] ) ? absint( $request['image']['id'] ) : 0; + } + + // Check if image_id is a valid image attachment before updating the term meta. + if ( $image_id && wp_attachment_is_image( $image_id ) ) { + update_term_meta( $id, 'thumbnail_id', $image_id ); + + // Set the image alt. + if ( ! empty( $request['image']['alt'] ) ) { + update_post_meta( $image_id, '_wp_attachment_image_alt', wc_clean( $request['image']['alt'] ) ); + } + + // Set the image title. + if ( ! empty( $request['image']['title'] ) ) { + wp_update_post( array( + 'ID' => $image_id, + 'post_title' => wc_clean( $request['image']['title'] ), + ) ); + } + } else { + delete_term_meta( $id, 'thumbnail_id' ); + } + } + + return true; + } + + /** + * Get the Category schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'parent' => array( + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'display' => array( + 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'default', + 'enum' => array( 'default', 'products', 'subcategories', 'both' ), + 'context' => array( 'view', 'edit' ), + ), + 'image' => array( + 'description' => __( 'Image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'title' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v1/class-wc-rest-product-reviews-v1-controller.php b/includes/v1/class-wc-rest-product-reviews-v1-controller.php new file mode 100644 index 00000000000..37237ae7992 --- /dev/null +++ b/includes/v1/class-wc-rest-product-reviews-v1-controller.php @@ -0,0 +1,578 @@ +/reviews. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Product Reviews Controller Class. + * + * @package WooCommerce/API + * @extends WC_REST_Controller + */ +class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/(?P[\d]+)/reviews'; + + /** + * Register the routes for product reviews. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'review' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Review content.', 'woocommerce' ), + ), + 'name' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + ), + 'email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read webhook deliveries. + * + * @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_post_permissions( 'product', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + + if ( $post && ! wc_rest_check_post_permissions( 'product', 'read', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a new product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'create', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to update a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'edit', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to delete a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'delete', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get all reviews from a product. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $reviews = get_approved_comments( $product_id ); + $data = array(); + foreach ( $reviews as $review_data ) { + $review = $this->prepare_item_for_response( $review_data, $request ); + $review = $this->prepare_response_for_collection( $review ); + $data[] = $review; + } + + return rest_ensure_response( $data ); + } + + /** + * Get a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $review = get_comment( $id ); + + if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $delivery = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $delivery ); + + return $response; + } + + + /** + * Create a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + + /** + * Filter a product review (comment) before it is inserted via the REST API. + * + * Allows modification of the comment right before it is inserted via `wp_insert_comment`. + * + * @param array $prepared_review The prepared comment data for `wp_insert_comment`. + * @param WP_REST_Request $request Request used to insert the comment. + */ + $prepared_review = apply_filters( 'rest_pre_insert_product_review', $prepared_review, $request ); + + $product_review_id = wp_insert_comment( $prepared_review ); + if ( ! $product_review_id ) { + return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); + + $product_review = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $product_review, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Comment $product_review Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $product_review_id ) ) ); + + return $response; + } + + /** + * Update a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $product_review_id = (int) $request['id']; + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $review = get_comment( $product_review_id ); + + if ( empty( $product_review_id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + + $updated = wp_update_comment( $prepared_review ); + if ( 0 === $updated ) { + return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( ! empty( $request['rating'] ) ) { + update_comment_meta( $product_review_id, 'rating', $request['rating'] ); + } + + $product_review = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $product_review, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Comment $comment Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a product review. + * + * @param WP_REST_Request $request Full details about the request + * + * @return bool|WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $product_review_id = absint( is_array( $request['id'] ) ? $request['id']['id'] : $request['id'] ); + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + $product_review = get_comment( $product_review_id ); + if ( empty( $product_review_id ) || empty( $product_review->comment_ID ) || empty( $product_review->comment_post_ID ) ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + /** + * Filter whether a product review is trashable. + * + * Return false to disable trash support for the product review. + * + * @param boolean $supports_trash Whether the object supports trashing. + * @param WP_Post $product_review The object being considered for trashing support. + */ + $supports_trash = apply_filters( 'rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $product_review ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + + if ( $force ) { + $result = wp_delete_comment( $product_review_id, true ); + } else { + if ( ! $supports_trash ) { + return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + if ( 'trash' === $product_review->comment_approved ) { + return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + } + + $result = wp_trash_comment( $product_review->comment_ID ); + } + + if ( ! $result ) { + return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a product review is deleted via the REST API. + * + * @param object $product_review The deleted item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'rest_delete_product_review', $product_review, $response, $request ); + + return $response; + } + + /** + * Prepare a single product review output for response. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $review, $request ) { + $data = array( + 'id' => (int) $review->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $review->comment_date_gmt ), + 'review' => $review->comment_content, + 'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ), + 'name' => $review->comment_author, + 'email' => $review->comment_author_email, + 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), + ); + + $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( $review, $request ) ); + + /** + * Filter product reviews object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $review Product review object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + } + + /** + * Prepare a single product review to be inserted into the database. + * + * @param WP_REST_Request $request Request object. + * @return array|WP_Error $prepared_review + */ + protected function prepare_item_for_database( $request ) { + $prepared_review = array( 'comment_approved' => 1, 'comment_type' => 'review' ); + + if ( isset( $request['id'] ) ) { + $prepared_review['comment_ID'] = (int) $request['id']; + } + + if ( isset( $request['review'] ) ) { + $prepared_review['comment_content'] = $request['review']; + } + + if ( isset( $request['product_id'] ) ) { + $prepared_review['comment_post_ID'] = (int) $request['product_id']; + } + + if ( isset( $request['name'] ) ) { + $prepared_review['comment_author'] = $request['name']; + } + + if ( isset( $request['email'] ) ) { + $prepared_review['comment_author_email'] = $request['email']; + } + + if ( isset( $request['date_created'] ) ) { + $prepared_review['comment_date'] = $request['date_created']; + } + + if ( isset( $request['date_created_gmt'] ) ) { + $prepared_review['comment_date_gmt'] = $request['date_created_gmt']; + } + + return apply_filters( 'rest_preprocess_product_review', $prepared_review, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given product review. + */ + protected function prepare_links( $review, $request ) { + $product_id = (int) $request['product_id']; + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $review->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Product Review's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_review', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'rating' => array( + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'verified' => array( + 'description' => __( 'Shows if the reviewer bought the product or not.', '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() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/includes/v1/class-wc-rest-product-shipping-classes-v1-controller.php b/includes/v1/class-wc-rest-product-shipping-classes-v1-controller.php new file mode 100644 index 00000000000..445c109df27 --- /dev/null +++ b/includes/v1/class-wc-rest-product-shipping-classes-v1-controller.php @@ -0,0 +1,134 @@ + (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Shipping Class schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Shipping class name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v1/class-wc-rest-product-tags-v1-controller.php b/includes/v1/class-wc-rest-product-tags-v1-controller.php new file mode 100644 index 00000000000..accdfae4c63 --- /dev/null +++ b/includes/v1/class-wc-rest-product-tags-v1-controller.php @@ -0,0 +1,134 @@ + (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Tag's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v1/class-wc-rest-products-v1-controller.php b/includes/v1/class-wc-rest-products-v1-controller.php new file mode 100644 index 00000000000..f8162881862 --- /dev/null +++ b/includes/v1/class-wc-rest-products-v1-controller.php @@ -0,0 +1,2641 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + add_action( "woocommerce_rest_insert_{$this->post_type}", array( $this, 'clear_transients' ) ); + } + + /** + * Register the routes for products. + */ + public function register_routes() { + register_rest_route( $this->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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'type' => 'boolean', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Get post types. + * + * @return array + */ + protected function get_post_types() { + return array( 'product', 'product_variation' ); + } + + /** + * Query args. + * + * @param array $args Request args. + * @param WP_REST_Request $request Request data. + * @return array + */ + public function query_args( $args, $request ) { + // Set post_status. + $args['post_status'] = $request['status']; + + // Taxonomy query to filter products by type, category, + // tag, shipping class, and attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies = array( + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) && is_array( $request[ $key ] ) ) { + $request[ $key ] = array_filter( $request[ $key ] ); + } + + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + if ( ! empty( $tax_query ) ) { + $args['tax_query'] = $tax_query; + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) ); + } + + // Apply all WP_Query filters again. + if ( is_array( $request['filter'] ) ) { + $args = array_merge( $args, $request['filter'] ); + unset( $args['filter'] ); + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + return $args; + } + + /** + * Get the downloads for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_downloads( $product ) { + $downloads = array(); + + if ( $product->is_downloadable() ) { + foreach ( $product->get_downloads() as $file_id => $file ) { + $downloads[] = array( + 'id' => $file_id, // MD5 hash. + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param string $taxonomy Taxonomy slug. + * @return array + */ + protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { + $terms = array(); + + foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { + $terms[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + ); + } + + return $terms; + } + + /** + * Get the images for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_images( $product ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( $product->get_image_id() ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $position => $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified_gmt ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + 'position' => (int) $position, + ); + } + + // Set a placeholder image if the product has no images set. + if ( empty( $images ) ) { + $images[] = array( + 'id' => 0, + 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), // Default to now. + 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), + 'src' => wc_placeholder_img_src(), + 'name' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), + 'position' => 0, + ); + } + + return $images; + } + + /** + * Get attribute taxonomy label. + * + * @param string $name Taxonomy name. + * @return string + */ + protected function get_attribute_taxonomy_label( $name ) { + $tax = get_taxonomy( $name ); + $labels = get_taxonomy_labels( $tax ); + + return $labels->singular_name; + } + + /** + * Get default attributes. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_default_attributes( $product ) { + $default = array(); + + if ( $product->is_type( 'variable' ) ) { + foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { + if ( 0 === strpos( $key, 'pa_' ) ) { + $default[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $key ), + 'name' => $this->get_attribute_taxonomy_label( $key ), + 'option' => $value, + ); + } else { + $default[] = array( + 'id' => 0, + 'name' => wc_attribute_taxonomy_slug( $key ), + 'option' => $value, + ); + } + } + } + + return $default; + } + + /** + * Get attribute options. + * + * @param int $product_id Product ID. + * @param array $attribute Attribute data. + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( $product_id, $attribute['name'], array( 'fields' => 'names' ) ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_attributes( $product ) { + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + // Variation attributes. + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + $name = str_replace( 'attribute_', '', $attribute_name ); + + if ( ! $attribute ) { + continue; + } + + // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. + if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $name ); + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $name ), + 'name' => $this->get_attribute_taxonomy_label( $name ), + 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $name, + 'option' => $attribute, + ); + } + } + } else { + foreach ( $product->get_attributes() as $attribute ) { + if ( $attribute['is_taxonomy'] ) { + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $attribute['name'] ), + 'name' => $this->get_attribute_taxonomy_label( $attribute['name'] ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $attribute['name'], + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + } + + return $attributes; + } + + /** + * Get product menu order. + * + * @deprecated 3.0.0 + * @param WC_Product $product Product instance. + * @return int + */ + protected function get_product_menu_order( $product ) { + return $product->get_menu_order(); + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_product_data( $product ) { + $data = array( + 'id' => $product->get_id(), + 'name' => $product->get_name(), + 'slug' => $product->get_slug(), + 'permalink' => $product->get_permalink(), + 'date_created' => wc_rest_prepare_date_response( $product->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified() ), + 'type' => $product->get_type(), + 'status' => $product->get_status(), + 'featured' => $product->is_featured(), + 'catalog_visibility' => $product->get_catalog_visibility(), + 'description' => wpautop( do_shortcode( $product->get_description() ) ), + 'short_description' => apply_filters( 'woocommerce_short_description', $product->get_short_description() ), + 'sku' => $product->get_sku(), + 'price' => $product->get_price(), + 'regular_price' => $product->get_regular_price(), + 'sale_price' => $product->get_sale_price() ? $product->get_sale_price() : '', + 'date_on_sale_from' => $product->get_date_on_sale_from() ? date( 'Y-m-d', $product->get_date_on_sale_from()->getTimestamp() ) : '', + 'date_on_sale_to' => $product->get_date_on_sale_to() ? date( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ) : '', + 'price_html' => $product->get_price_html(), + 'on_sale' => $product->is_on_sale(), + 'purchasable' => $product->is_purchasable(), + 'total_sales' => $product->get_total_sales(), + 'virtual' => $product->is_virtual(), + 'downloadable' => $product->is_downloadable(), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit(), + 'download_expiry' => $product->get_download_expiry(), + 'download_type' => 'standard', + 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url() : '', + 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text() : '', + 'tax_status' => $product->get_tax_status(), + 'tax_class' => $product->get_tax_class(), + 'manage_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity(), + 'in_stock' => $product->is_in_stock(), + 'backorders' => $product->get_backorders(), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'weight' => $product->get_weight(), + 'dimensions' => array( + 'length' => $product->get_length(), + 'width' => $product->get_width(), + 'height' => $product->get_height(), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => $product->get_shipping_class_id(), + 'reviews_allowed' => $product->get_reviews_allowed(), + 'average_rating' => wc_format_decimal( $product->get_average_rating(), 2 ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids() ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids() ), + 'parent_id' => $product->get_parent_id(), + 'purchase_note' => wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ), + 'categories' => $this->get_taxonomy_terms( $product ), + 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), + 'images' => $this->get_images( $product ), + 'attributes' => $this->get_attributes( $product ), + 'default_attributes' => $this->get_default_attributes( $product ), + 'variations' => array(), + 'grouped_products' => array(), + 'menu_order' => $product->get_menu_order(), + ); + + return $data; + } + + /** + * Get an individual variation's data. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_variation_data( $product ) { + $variations = array(); + + foreach ( $product->get_children() as $child_id ) { + $variation = wc_get_product( $child_id ); + if ( ! $variation || ! $variation->exists() ) { + continue; + } + + $variations[] = array( + 'id' => $variation->get_id(), + 'date_created' => wc_rest_prepare_date_response( $variation->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $variation->get_date_modified() ), + 'permalink' => $variation->get_permalink(), + 'sku' => $variation->get_sku(), + 'price' => $variation->get_price(), + 'regular_price' => $variation->get_regular_price(), + 'sale_price' => $variation->get_sale_price(), + 'date_on_sale_from' => $variation->get_date_on_sale_from() ? date( 'Y-m-d', $variation->get_date_on_sale_from()->getTimestamp() ) : '', + 'date_on_sale_to' => $variation->get_date_on_sale_to() ? date( 'Y-m-d', $variation->get_date_on_sale_to()->getTimestamp() ) : '', + 'on_sale' => $variation->is_on_sale(), + 'purchasable' => $variation->is_purchasable(), + 'visible' => $variation->is_visible(), + 'virtual' => $variation->is_virtual(), + 'downloadable' => $variation->is_downloadable(), + 'downloads' => $this->get_downloads( $variation ), + 'download_limit' => '' !== $variation->get_download_limit() ? (int) $variation->get_download_limit() : -1, + 'download_expiry' => '' !== $variation->get_download_expiry() ? (int) $variation->get_download_expiry() : -1, + 'tax_status' => $variation->get_tax_status(), + 'tax_class' => $variation->get_tax_class(), + 'manage_stock' => $variation->managing_stock(), + 'stock_quantity' => $variation->get_stock_quantity(), + 'in_stock' => $variation->is_in_stock(), + 'backorders' => $variation->get_backorders(), + 'backorders_allowed' => $variation->backorders_allowed(), + 'backordered' => $variation->is_on_backorder(), + 'weight' => $variation->get_weight(), + 'dimensions' => array( + 'length' => $variation->get_length(), + 'width' => $variation->get_width(), + 'height' => $variation->get_height(), + ), + 'shipping_class' => $variation->get_shipping_class(), + 'shipping_class_id' => $variation->get_shipping_class_id(), + 'image' => $this->get_images( $variation ), + 'attributes' => $this->get_attributes( $variation ), + ); + } + + return $variations; + } + + /** + * Prepare a single product output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $post, $request ) { + $product = wc_get_product( $post ); + $data = $this->get_product_data( $product ); + + // Add variations to variable products. + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + $data['variations'] = $this->get_variation_data( $product ); + } + + // Add grouped products data. + if ( $product->is_type( 'grouped' ) && $product->has_child() ) { + $data['grouped_products'] = $product->get_children(); + } + + $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, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Product $product Product object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given product. + */ + protected function prepare_links( $product, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $product->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + if ( $product->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_parent_id() ) ), + ); + } + + return $links; + } + + /** + * Prepare a single product for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + + // Type is the most important part here because we need to be using the correct class and methods. + if ( isset( $request['type'] ) ) { + $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + + $product = new $classname( $id ); + } elseif ( isset( $request['id'] ) ) { + $product = wc_get_product( $id ); + } else { + $product = new WC_Product_Simple(); + } + + // Post title. + if ( isset( $request['name'] ) ) { + $product->set_name( wp_filter_post_kses( $request['name'] ) ); + } + + // Post content. + if ( isset( $request['description'] ) ) { + $product->set_description( wp_filter_post_kses( $request['description'] ) ); + } + + // Post excerpt. + if ( isset( $request['short_description'] ) ) { + $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); + } + + // Post status. + if ( isset( $request['status'] ) ) { + $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // Post slug. + if ( isset( $request['slug'] ) ) { + $product->set_slug( $request['slug'] ); + } + + // Menu order. + if ( isset( $request['menu_order'] ) ) { + $product->set_menu_order( $request['menu_order'] ); + } + + // Comment status. + if ( isset( $request['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $request['reviews_allowed'] ); + } + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param WC_Product $product An object representing a single item prepared + * for inserting or updating the database. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $product, $request ); + } + + /** + * Create a single product. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $product_id = 0; + + try { + $product_id = $this->save_product( $request ); + $post = get_post( $product_id ); + $this->update_additional_fields_for_object( $post, $request ); + $this->update_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_product', $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } catch ( WC_Data_Exception $e ) { + $this->delete_post( $product_id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + $this->delete_post( $product_id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update a single product. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + try { + $product_id = $this->save_product( $request ); + $post = get_post( $product_id ); + $this->update_additional_fields_for_object( $post, $request ); + $this->update_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_product', $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + return rest_ensure_response( $response ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Saves a product to the database. + * + * @param WP_REST_Request $request Full details about the request. + * @return int + */ + public function save_product( $request ) { + $product = $this->prepare_item_for_database( $request ); + return $product->save(); + } + + /** + * Save product images. + * + * @deprecated 3.0.0 + * @param int $product_id + * @param array $images + * @throws WC_REST_Exception + */ + protected function save_product_images( $product_id, $images ) { + $product = wc_get_product( $product_id ); + + return set_product_images( $product, $images ); + } + + /** + * Set product images. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param array $images Images data. + * @return WC_Product + */ + protected function set_product_images( $product, $images ) { + if ( is_array( $images ) ) { + $gallery = array(); + + foreach ( $images as $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { + throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + if ( isset( $image['position'] ) && 0 === absint( $image['position'] ) ) { + $product->set_image_id( $attachment_id ); + } else { + $gallery[] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( array( 'ID' => $attachment_id, 'post_title' => $image['name'] ) ); + } + } + + if ( ! empty( $gallery ) ) { + $product->set_gallery_image_ids( $gallery ); + } + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Save product shipping data. + * + * @param WC_Product $product Product instance. + * @param array $data Shipping data. + * @return WC_Product + */ + protected function save_product_shipping_data( $product, $data ) { + // Virtual. + if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { + $product->set_weight( '' ); + $product->set_height( '' ); + $product->set_length( '' ); + $product->set_width( '' ); + } else { + if ( isset( $data['weight'] ) ) { + $product->set_weight( $data['weight'] ); + } + + // Height. + if ( isset( $data['dimensions']['height'] ) ) { + $product->set_height( $data['dimensions']['height'] ); + } + + // Width. + if ( isset( $data['dimensions']['width'] ) ) { + $product->set_width( $data['dimensions']['width'] ); + } + + // Length. + if ( isset( $data['dimensions']['length'] ) ) { + $product->set_length( $data['dimensions']['length'] ); + } + } + + // Shipping class. + if ( isset( $data['shipping_class'] ) ) { + $data_store = $product->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + + return $product; + } + + /** + * Save downloadable files. + * + * @param WC_Product $product Product instance. + * @param array $downloads Downloads data. + * @param int $deprecated Deprecated since 3.0. + * @return WC_Product + */ + protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { + if ( $deprecated ) { + wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); + } + + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); + $files[] = $download; + } + $product->set_downloads( $files ); + + return $product; + } + + /** + * Save taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param array $terms Terms data. + * @param string $taxonomy Taxonomy name. + * @return WC_Product + */ + protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { + $term_ids = wp_list_pluck( $terms, 'id' ); + + if ( 'cat' === $taxonomy ) { + $product->set_category_ids( $term_ids ); + } elseif ( 'tag' === $taxonomy ) { + $product->set_tag_ids( $term_ids ); + } + + return $product; + } + + /** + * Save default attributes. + * + * @since 3.0.0 + * + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return WC_Product + */ + protected function save_default_attributes( $product, $request ) { + if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { + $attributes = $product->get_attributes(); + $default_attributes = array(); + + foreach ( $request['default_attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( isset( $attributes[ $attribute_name ] ) ) { + $_attribute = $attributes[ $attribute_name ]; + + if ( $_attribute['is_variation'] ) { + $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( ! empty( $_attribute['is_taxonomy'] ) ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $value = $term->slug; + } else { + $value = sanitize_title( $value ); + } + } + + if ( $value ) { + $default_attributes[ $attribute_name ] = $value; + } + } + } + } + + $product->set_default_attributes( $default_attributes ); + } + + return $product; + } + + /** + * Save product meta. + * + * @deprecated 3.0.0 + * @param WC_Product $product + * @param WP_REST_Request $request + * @return bool + * @throws WC_REST_Exception + */ + protected function save_product_meta( $product, $request ) { + $product = $this->set_product_meta( $product, $request ); + $product->save(); + + return true; + } + + /** + * Set product meta. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return WC_Product + */ + protected function set_product_meta( $product, $request ) { + // Virtual. + if ( isset( $request['virtual'] ) ) { + $product->set_virtual( $request['virtual'] ); + } + + // Tax status. + if ( isset( $request['tax_status'] ) ) { + $product->set_tax_status( $request['tax_status'] ); + } + + // Tax Class. + if ( isset( $request['tax_class'] ) ) { + $product->set_tax_class( $request['tax_class'] ); + } + + // Catalog Visibility. + if ( isset( $request['catalog_visibility'] ) ) { + $product->set_catalog_visibility( $request['catalog_visibility'] ); + } + + // Purchase Note. + if ( isset( $request['purchase_note'] ) ) { + $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); + } + + // Featured Product. + if ( isset( $request['featured'] ) ) { + $product->set_featured( $request['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $request ); + + // SKU. + if ( isset( $request['sku'] ) ) { + $product->set_sku( wc_clean( $request['sku'] ) ); + } + + // Attributes. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + } else { + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $product->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $product->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + } + + // Product parent ID for groups. + if ( isset( $request['parent_id'] ) ) { + $product->set_parent_id( $request['parent_id'] ); + } + + // Sold individually. + if ( isset( $request['sold_individually'] ) ) { + $product->set_sold_individually( $request['sold_individually'] ); + } + + // Stock status. + if ( isset( $request['in_stock'] ) ) { + $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; + } else { + $stock_status = $product->get_stock_status(); + } + + // Stock data. + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $request['manage_stock'] ) ) { + $product->set_manage_stock( $request['manage_stock'] ); + } + + // Backorders. + if ( isset( $request['backorders'] ) ) { + $product->set_backorders( $request['backorders'] ); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( $product->get_manage_stock() ) { + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $request['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $request['upsell_ids'] ) ) { + $upsells = array(); + $ids = $request['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + } + + $product->set_upsell_ids( $upsells ); + } + + // Cross sells. + if ( isset( $request['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $request['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + } + + $product->set_cross_sell_ids( $crosssells ); + } + + // Product categories. + if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); + } + + // Downloadable. + if ( isset( $request['downloadable'] ) ) { + $product->set_downloadable( $request['downloadable'] ); + } + + // Downloadable options. + if ( $product->get_downloadable() ) { + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $product->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $product->set_download_expiry( $request['download_expiry'] ); + } + } + + // Product url and button text for external products. + if ( $product->is_type( 'external' ) ) { + if ( isset( $request['external_url'] ) ) { + $product->set_product_url( $request['external_url'] ); + } + + if ( isset( $request['button_text'] ) ) { + $product->set_button_text( $request['button_text'] ); + } + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $request ); + } + + return $product; + } + + /** + * Save variations. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return bool + */ + protected function save_variations_data( $product, $request ) { + foreach ( $request['variations'] as $menu_order => $data ) { + $variation = new WC_Product_Variation( isset( $data['id'] ) ? absint( $data['id'] ) : 0 ); + + // Create initial name and status. + if ( ! $variation->get_slug() ) { + /* translators: 1: variation id 2: product name */ + $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); + $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); + } + + // Parent ID. + $variation->set_parent_id( $product->get_id() ); + + // Menu order. + $variation->set_menu_order( $menu_order ); + + // Status. + if ( isset( $data['visible'] ) ) { + $variation->set_status( false === $data['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $data['sku'] ) ) { + $variation->set_sku( wc_clean( $data['sku'] ) ); + } + + // Thumbnail. + if ( isset( $data['image'] ) && is_array( $data['image'] ) ) { + $image = $data['image']; + $image = current( $image ); + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->set_product_images( $variation, array( $image ) ); + } + + // Virtual variation. + if ( isset( $data['virtual'] ) ) { + $variation->set_virtual( $data['virtual'] ); + } + + // Downloadable variation. + if ( isset( $data['downloadable'] ) ) { + $variation->set_downloadable( $data['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $data['downloads'] ); + } + + // Download limit. + if ( isset( $data['download_limit'] ) ) { + $variation->set_download_limit( $data['download_limit'] ); + } + + // Download expiry. + if ( isset( $data['download_expiry'] ) ) { + $variation->set_download_expiry( $data['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $data ); + + // Stock handling. + if ( isset( $data['manage_stock'] ) ) { + $variation->set_manage_stock( $data['manage_stock'] ); + } + + if ( isset( $data['in_stock'] ) ) { + $variation->set_stock_status( true === $data['in_stock'] ? 'instock' : 'outofstock' ); + } + + if ( isset( $data['backorders'] ) ) { + $variation->set_backorders( $data['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $data['stock_quantity'] ) ) { + $variation->set_stock_quantity( $data['stock_quantity'] ); + } elseif ( isset( $data['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $data['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $data['regular_price'] ) ) { + $variation->set_regular_price( $data['regular_price'] ); + } + + // Sale Price. + if ( isset( $data['sale_price'] ) ) { + $variation->set_sale_price( $data['sale_price'] ); + } + + if ( isset( $data['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $data['date_on_sale_from'] ); + } + + if ( isset( $data['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $data['date_on_sale_to'] ); + } + + // Tax class. + if ( isset( $data['tax_class'] ) ) { + $variation->set_tax_class( $data['tax_class'] ); + } + + // Description. + if ( isset( $data['description'] ) ) { + $variation->set_description( wp_kses_post( $data['description'] ) ); + } + + // Update taxonomies. + if ( isset( $data['attributes'] ) ) { + $attributes = array(); + $parent_attributes = $product->get_attributes(); + + foreach ( $data['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + $variation->save(); + + do_action( 'woocommerce_rest_save_product_variation', $variation->get_id(), $menu_order, $data ); + } + + return true; + } + + /** + * Add post meta fields. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request data. + * @return bool|WP_Error + */ + protected function add_post_meta_fields( $post, $request ) { + return $this->update_post_meta_fields( $post, $request ); + } + + /** + * Update post meta fields. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request data. + * @return bool|WP_Error + */ + protected function update_post_meta_fields( $post, $request ) { + $product = wc_get_product( $post ); + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + $product = $this->set_product_images( $product, $request['images'] ); + } + + // Save product meta fields. + $product = $this->set_product_meta( $product, $request ); + + // Save the product data. + $product->save(); + + // Save variations. + if ( $product->is_type( 'variable' ) ) { + if ( isset( $request['variations'] ) && is_array( $request['variations'] ) ) { + $this->save_variations_data( $product, $request ); + } + } + + // Clear caches here so in sync with any new variations/children. + wc_delete_product_transients( $product->get_id() ); + wp_cache_delete( 'product-' . $product->get_id(), 'products' ); + + return true; + } + + /** + * Clear cache/transients. + * + * @param WP_Post $post Post data. + */ + public function clear_transients( $post ) { + wc_delete_product_transients( $post->ID ); + } + + /** + * Delete post. + * + * @param int|WP_Post $id Post ID or WP_Post instance. + */ + protected function delete_post( $id ) { + if ( ! empty( $id->ID ) ) { + $id = $id->ID; + } elseif ( ! is_numeric( $id ) || 0 >= $id ) { + return; + } + + // Delete product attachments. + $attachments = get_posts( array( + 'post_parent' => $id, + 'post_status' => 'any', + 'post_type' => 'attachment', + ) ); + + foreach ( (array) $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + // Delete product. + $product = wc_get_product( $id ); + $product->delete( true ); + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = (bool) $request['force']; + $post = get_post( $id ); + $product = wc_get_product( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0; + + /** + * Filter whether an item is trashable. + * + * Return false to disable trash support for the item. + * + * @param boolean $supports_trash Whether the item type support trashing. + * @param WP_Post $post The Post object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + if ( $product->is_type( 'variable' ) ) { + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->delete( true ); + } + } + } else { + // For other product types, if the product has children, remove the relationship. + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->set_parent_id( 0 ); + $child->save(); + } + } + } + + $product->delete( true ); + $result = ! ( $product->get_id() > 0 ); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( 'trash' === $post->post_status ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + // (Note that internally this falls through to `wp_delete_post` if + // the trash is disabled.) + $product->delete(); + $result = 'trash' === $product->get_status(); + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + // Delete parent product transients. + if ( $parent_id = wp_get_post_parent_id( $id ) ) { + wc_delete_product_transients( $parent_id ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param object $post The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); + + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( 'Start date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( 'End date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_type' => array( + 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'standard', + 'enum' => array( 'standard' ), + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of upsell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Variation ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( 'Start date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( 'End date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'visible' => array( + 'description' => __( 'If the variation is visible.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['slug'] = array( + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['type'] = array( + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_types() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['category'] = array( + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['tag'] = array( + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['shipping_class'] = array( + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute'] = array( + 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute_term'] = array( + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['sku'] = array( + 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v1/class-wc-rest-report-sales-v1-controller.php b/includes/v1/class-wc-rest-report-sales-v1-controller.php new file mode 100644 index 00000000000..56aa1854c30 --- /dev/null +++ b/includes/v1/class-wc-rest-report-sales-v1-controller.php @@ -0,0 +1,397 @@ +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' ), + ) ); + } + + /** + * Check whether a given request has permission to read report. + * + * @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( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get sales reports. + * + * @param WP_REST_Request $request + * @return array|WP_Error + */ + public function get_items( $request ) { + $data = array(); + $item = $this->prepare_item_for_response( null, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report sales object for serialization. + * + * @param null $_ + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $_, $request ) { + // Set date filtering. + $filter = array( + 'period' => $request['period'], + 'date_min' => $request['date_min'], + 'date_max' => $request['date_max'], + ); + $this->setup_report( $filter ); + + // New customers. + $users_query = new WP_User_Query( + array( + 'fields' => array( 'user_registered' ), + 'role' => 'customer', + ) + ); + + $customers = $users_query->get_results(); + + foreach ( $customers as $key => $customer ) { + if ( strtotime( $customer->user_registered ) < $this->report->start_date || strtotime( $customer->user_registered ) > $this->report->end_date ) { + unset( $customers[ $key ] ); + } + } + + $total_customers = count( $customers ); + $report_data = $this->report->get_report_data(); + $period_totals = array(); + + // Setup period totals by ensuring each period in the interval has data. + for ( $i = 0; $i <= $this->report->chart_interval; $i++ ) { + + switch ( $this->report->chart_groupby ) { + case 'day' : + $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $this->report->start_date ) ); + break; + default : + $time = date( 'Y-m', strtotime( "+{$i} MONTH", $this->report->start_date ) ); + break; + } + + // Set the customer signups for each period. + $customer_count = 0; + foreach ( $customers as $customer ) { + if ( date( ( 'day' == $this->report->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) { + $customer_count++; + } + } + + $period_totals[ $time ] = array( + 'sales' => wc_format_decimal( 0.00, 2 ), + 'orders' => 0, + 'items' => 0, + 'tax' => wc_format_decimal( 0.00, 2 ), + 'shipping' => wc_format_decimal( 0.00, 2 ), + 'discount' => wc_format_decimal( 0.00, 2 ), + 'customers' => $customer_count, + ); + } + + // add total sales, total order count, total tax and total shipping for each period + foreach ( $report_data->orders as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 ); + $period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 ); + $period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 ); + } + + foreach ( $report_data->order_counts as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['orders'] = (int) $order->count; + } + + // Add total order items for each period. + foreach ( $report_data->order_items as $order_item ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['items'] = (int) $order_item->order_item_count; + } + + // Add total discount for each period. + foreach ( $report_data->coupons as $discount ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 ); + } + + $sales_data = array( + 'total_sales' => $report_data->total_sales, + 'net_sales' => $report_data->net_sales, + 'average_sales' => $report_data->average_sales, + 'total_orders' => $report_data->total_orders, + 'total_items' => $report_data->total_items, + 'total_tax' => wc_format_decimal( $report_data->total_tax + $report_data->total_shipping_tax, 2 ), + 'total_shipping' => $report_data->total_shipping, + 'total_refunds' => $report_data->total_refunds, + 'total_discount' => $report_data->total_coupons, + 'totals_grouped_by' => $this->report->chart_groupby, + 'totals' => $period_totals, + 'total_customers' => $total_customers, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $sales_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( array( + 'about' => array( + 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), + ), + ) ); + + /** + * Filter a report sales returned from the API. + * + * Allows modification of the report sales data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $data The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_sales', $response, (object) $sales_data, $request ); + } + + /** + * Setup the report object and parse any date filtering. + * + * @param array $filter date filtering + */ + protected function setup_report( $filter ) { + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' ); + + $this->report = new WC_Report_Sales_By_Date(); + + if ( empty( $filter['period'] ) ) { + // Custom date range. + $filter['period'] = 'custom'; + + if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) { + + // Overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges. + $_GET['start_date'] = $filter['date_min']; + $_GET['end_date'] = isset( $filter['date_max'] ) ? $filter['date_max'] : null; + + } else { + + // Default custom range to today. + $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); + } + } else { + $filter['period'] = empty( $filter['period'] ) ? 'week' : $filter['period']; + + // Change "week" period to "7day". + if ( 'week' === $filter['period'] ) { + $filter['period'] = '7day'; + } + } + + $this->report->calculate_current_range( $filter['period'] ); + } + + /** + * 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' => 'sales_report', + 'type' => 'object', + 'properties' => array( + 'total_sales' => array( + 'description' => __( 'Gross sales in the period.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'net_sales' => array( + 'description' => __( 'Net sales in the period.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'average_sales' => array( + 'description' => __( 'Average net daily sales.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_orders' => array( + 'description' => __( 'Total of orders placed.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_items' => array( + 'description' => __( 'Total of items purchased.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Total charged for taxes.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_shipping' => array( + 'description' => __( 'Total charged for shipping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_refunds' => array( + 'description' => __( 'Total of refunded orders.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_discount' => array( + 'description' => __( 'Total of coupons used.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'totals_grouped_by' => array( + 'description' => __( 'Group type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'totals' => array( + 'description' => __( 'Totals.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'array', + ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + 'period' => array( + 'description' => __( 'Report period.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'week', 'month', 'last_month', 'year' ), + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'date_min' => array( + /* translators: %s: date format */ + 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), + 'type' => 'string', + 'format' => 'date', + 'validate_callback' => 'wc_rest_validate_reports_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'date_max' => array( + /* translators: %s: date format */ + 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), + 'type' => 'string', + 'format' => 'date', + 'validate_callback' => 'wc_rest_validate_reports_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + ); + } +} diff --git a/includes/v1/class-wc-rest-report-top-sellers-v1-controller.php b/includes/v1/class-wc-rest-report-top-sellers-v1-controller.php new file mode 100644 index 00000000000..de8ec7e80c9 --- /dev/null +++ b/includes/v1/class-wc-rest-report-top-sellers-v1-controller.php @@ -0,0 +1,174 @@ + $request['period'], + 'date_min' => $request['date_min'], + 'date_max' => $request['date_max'], + ); + $this->setup_report( $filter ); + + $report_data = $this->report->get_order_report_data( array( + 'data' => array( + '_product_id' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => '', + 'name' => 'product_id', + ), + '_qty' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => 'SUM', + 'name' => 'order_item_qty', + ), + ), + 'order_by' => 'order_item_qty DESC', + 'group_by' => 'product_id', + 'limit' => isset( $filter['limit'] ) ? absint( $filter['limit'] ) : 12, + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + $top_sellers = array(); + + foreach ( $report_data as $item ) { + $product = wc_get_product( $item->product_id ); + + if ( $product ) { + $top_sellers[] = array( + 'name' => $product->get_name(), + 'product_id' => (int) $item->product_id, + 'quantity' => wc_stock_amount( $item->order_item_qty ), + ); + } + } + + $data = array(); + foreach ( $top_sellers as $top_seller ) { + $item = $this->prepare_item_for_response( (object) $top_seller, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report sales object for serialization. + * + * @param stdClass $top_seller + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $top_seller, $request ) { + $data = array( + 'name' => $top_seller->name, + 'product_id' => $top_seller->product_id, + 'quantity' => $top_seller->quantity, + ); + + $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( array( + 'about' => array( + 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), + ), + 'product' => array( + 'href' => rest_url( sprintf( '/%s/products/%s', $this->namespace, $top_seller->product_id ) ), + ), + ) ); + + /** + * Filter a report top sellers returned from the API. + * + * Allows modification of the report top sellers data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $top_seller The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_top_sellers', $response, $top_seller, $request ); + } + + /** + * 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' => 'top_sellers_report', + 'type' => 'object', + 'properties' => array( + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'quantity' => array( + 'description' => __( 'Total number of purchases.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v1/class-wc-rest-reports-v1-controller.php b/includes/v1/class-wc-rest-reports-v1-controller.php new file mode 100644 index 00000000000..2d284aa48bc --- /dev/null +++ b/includes/v1/class-wc-rest-reports-v1-controller.php @@ -0,0 +1,184 @@ +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' ), + ) ); + } + + /** + * Check whether a given request has permission to read reports. + * + * @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( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get reports list. + * + * @since 3.5.0 + * @return array + */ + protected function get_reports() { + return array( + array( + 'slug' => 'sales', + 'description' => __( 'List of sales reports.', 'woocommerce' ), + ), + array( + 'slug' => 'top_sellers', + 'description' => __( 'List of top sellers products.', 'woocommerce' ), + ), + ); + } + + /** + * Get all reports. + * + * @param WP_REST_Request $request + * @return array|WP_Error + */ + public function get_items( $request ) { + $data = array(); + $reports = $this->get_reports(); + + foreach ( $reports as $report ) { + $item = $this->prepare_item_for_response( (object) $report, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'description' => $report->description, + ); + + $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( array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $report->slug ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), + ), + ) ); + + /** + * 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', $response, $report, $request ); + } + + /** + * 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', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/includes/v1/class-wc-rest-tax-classes-v1-controller.php b/includes/v1/class-wc-rest-tax-classes-v1-controller.php new file mode 100644 index 00000000000..f857256ac95 --- /dev/null +++ b/includes/v1/class-wc-rest-tax-classes-v1-controller.php @@ -0,0 +1,364 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', array( + 'args' => array( + 'slug' => array( + 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read tax classes. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create tax classes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all tax classes. + * + * @param WP_REST_Request $request + * @return array + */ + public function get_items( $request ) { + $tax_classes = array(); + + // Add standard class. + $tax_classes[] = array( + 'slug' => 'standard', + 'name' => __( 'Standard rate', 'woocommerce' ), + ); + + $classes = WC_Tax::get_tax_classes(); + + foreach ( $classes as $class ) { + $tax_classes[] = array( + 'slug' => sanitize_title( $class ), + 'name' => $class, + ); + } + + $data = array(); + foreach ( $tax_classes as $tax_class ) { + $class = $this->prepare_item_for_response( $tax_class, $request ); + $class = $this->prepare_response_for_collection( $class ); + $data[] = $class; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + $exists = false; + $classes = WC_Tax::get_tax_classes(); + $tax_class = array( + 'slug' => sanitize_title( $request['name'] ), + 'name' => $request['name'], + ); + + // Check if class exists. + foreach ( $classes as $key => $class ) { + if ( sanitize_title( $class ) === $tax_class['slug'] ) { + $exists = true; + break; + } + } + + // Return error if tax class already exists. + if ( $exists ) { + return new WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Add the new class. + $classes[] = $tax_class['name']; + + update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); + + $this->update_additional_fields_for_object( $tax_class, $request ); + + /** + * Fires after a tax class is created or updated via the REST API. + * + * @param stdClass $tax_class Data used to create the tax class. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax class, false when updating tax class. + */ + do_action( 'woocommerce_rest_insert_tax_class', (object) $tax_class, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax_class, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $tax_class['slug'] ) ) ); + + return $response; + } + + /** + * Delete a single tax class. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + global $wpdb; + + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $tax_class = array( + 'slug' => sanitize_title( $request['slug'] ), + 'name' => '', + ); + $classes = WC_Tax::get_tax_classes(); + $deleted = false; + + foreach ( $classes as $key => $class ) { + if ( sanitize_title( $class ) === $tax_class['slug'] ) { + $tax_class['name'] = $class; + unset( $classes[ $key ] ); + $deleted = true; + break; + } + } + + if ( ! $deleted ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); + + // Delete tax rate locations locations from the selected class. + $wpdb->query( $wpdb->prepare( " + DELETE locations.* + FROM {$wpdb->prefix}woocommerce_tax_rate_locations AS locations + INNER JOIN + {$wpdb->prefix}woocommerce_tax_rates AS rates + ON rates.tax_rate_id = locations.tax_rate_id + WHERE rates.tax_rate_class = '%s' + ", $tax_class['slug'] ) ); + + // Delete tax rates in the selected class. + $wpdb->delete( $wpdb->prefix . 'woocommerce_tax_rates', array( 'tax_rate_class' => $tax_class['slug'] ), array( '%s' ) ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax_class, $request ); + + /** + * Fires after a tax class is deleted via the REST API. + * + * @param stdClass $tax_class The tax data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_tax', (object) $tax_class, $response, $request ); + + return $response; + } + + /** + * Prepare a single tax class output for response. + * + * @param array $tax_class Tax class data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $tax_class, $request ) { + $data = $tax_class; + + $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() ); + + /** + * Filter tax object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $tax_class Tax object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_tax', $response, (object) $tax_class, $request ); + } + + /** + * Prepare links for the request. + * + * @return array Links for the given tax class. + */ + protected function prepare_links() { + $links = array( + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Tax Classes schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'tax_class', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Tax class name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'required' => true, + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/includes/v1/class-wc-rest-taxes-v1-controller.php b/includes/v1/class-wc-rest-taxes-v1-controller.php new file mode 100644 index 00000000000..1b8c9bdd0aa --- /dev/null +++ b/includes/v1/class-wc-rest-taxes-v1-controller.php @@ -0,0 +1,709 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read taxes. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create taxes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a tax. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all taxes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + global $wpdb; + + $prepared_args = array(); + $prepared_args['order'] = $request['order']; + $prepared_args['number'] = $request['per_page']; + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + $orderby_possibles = array( + 'id' => 'tax_rate_id', + 'order' => 'tax_rate_order', + ); + $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; + $prepared_args['class'] = $request['class']; + + /** + * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. + * + * @param array $prepared_args Array of arguments for $wpdb->get_results(). + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request ); + + $query = " + SELECT * + FROM {$wpdb->prefix}woocommerce_tax_rates + WHERE 1 = 1 + "; + + // Filter by tax class. + if ( ! empty( $prepared_args['class'] ) ) { + $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; + $query .= " AND tax_rate_class = '$class'"; + } + + // Order tax rates. + $order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) ); + + // Pagination. + $pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] ); + + // Query taxes. + $results = $wpdb->get_results( $query . $order_by . $pagination ); + + $taxes = array(); + foreach ( $results as $tax ) { + $data = $this->prepare_item_for_response( $tax, $request ); + $taxes[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $taxes ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + // Query only for ids. + $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); + + // Calculate totals. + $total_taxes = (int) $wpdb->num_rows; + $response->header( 'X-WP-Total', (int) $total_taxes ); + $max_pages = ceil( $total_taxes / $per_page ); + $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; + } + + /** + * Take tax data from the request and return the updated or newly created rate. + * + * @param WP_REST_Request $request Full details about the request. + * @param stdClass|null $current Existing tax object. + * @return object + */ + protected function create_or_update_tax( $request, $current = null ) { + $id = absint( isset( $request['id'] ) ? $request['id'] : 0 ); + $data = array(); + $fields = array( + 'tax_rate_country', + 'tax_rate_state', + 'tax_rate', + 'tax_rate_name', + 'tax_rate_priority', + 'tax_rate_compound', + 'tax_rate_shipping', + 'tax_rate_order', + 'tax_rate_class', + ); + + foreach ( $fields as $field ) { + // Keys via API differ from the stored names returned by _get_tax_rate. + $key = 'tax_rate' === $field ? 'rate' : str_replace( 'tax_rate_', '', $field ); + + // Remove data that was not posted. + if ( ! isset( $request[ $key ] ) ) { + continue; + } + + // Test new data against current data. + if ( $current && $current->$field === $request[ $key ] ) { + continue; + } + + // Add to data array. + switch ( $key ) { + case 'tax_rate_priority' : + case 'tax_rate_compound' : + case 'tax_rate_shipping' : + case 'tax_rate_order' : + $data[ $field ] = absint( $request[ $key ] ); + break; + case 'tax_rate_class' : + $data[ $field ] = 'standard' !== $request['tax_rate_class'] ? $request['tax_rate_class'] : ''; + break; + default : + $data[ $field ] = wc_clean( $request[ $key ] ); + break; + } + } + + if ( $id ) { + WC_Tax::_update_tax_rate( $id, $data ); + } else { + $id = WC_Tax::_insert_tax_rate( $data ); + } + + // Add locales. + if ( ! empty( $request['postcode'] ) ) { + WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) ); + } + if ( ! empty( $request['city'] ) ) { + WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) ); + } + + return WC_Tax::_get_tax_rate( $id, OBJECT ); + } + + /** + * Create a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $tax = $this->create_or_update_tax( $request ); + + $this->update_additional_fields_for_object( $tax, $request ); + + /** + * Fires after a tax is created or updated via the REST API. + * + * @param stdClass $tax Data used to create the tax. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax, false when updating tax. + */ + do_action( 'woocommerce_rest_insert_tax', $tax, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ) ); + + return $response; + } + + /** + * Get a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax_obj ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tax = $this->prepare_item_for_response( $tax_obj, $request ); + $response = rest_ensure_response( $tax ); + + return $response; + } + + /** + * Update a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax_obj ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tax = $this->create_or_update_tax( $request, $tax_obj ); + + $this->update_additional_fields_for_object( $tax, $request ); + + /** + * Fires after a tax is created or updated via the REST API. + * + * @param stdClass $tax Data used to create the tax. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax, false when updating tax. + */ + do_action( 'woocommerce_rest_insert_tax', $tax, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + $response = rest_ensure_response( $response ); + + return $response; + } + + /** + * Delete a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + global $wpdb; + + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $tax = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + + WC_Tax::_delete_tax_rate( $id ); + + if ( 0 === $wpdb->rows_affected ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a tax is deleted via the REST API. + * + * @param stdClass $tax The tax data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request ); + + return $response; + } + + /** + * Prepare a single tax output for response. + * + * @param stdClass $tax Tax object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $tax, $request ) { + global $wpdb; + + $id = (int) $tax->tax_rate_id; + $data = array( + 'id' => $id, + 'country' => $tax->tax_rate_country, + 'state' => $tax->tax_rate_state, + 'postcode' => '', + 'city' => '', + 'rate' => $tax->tax_rate, + 'name' => $tax->tax_rate_name, + 'priority' => (int) $tax->tax_rate_priority, + 'compound' => (bool) $tax->tax_rate_compound, + 'shipping' => (bool) $tax->tax_rate_shipping, + 'order' => (int) $tax->tax_rate_order, + 'class' => $tax->tax_rate_class ? $tax->tax_rate_class : 'standard', + ); + + // Get locales from a tax rate. + $locales = $wpdb->get_results( $wpdb->prepare( " + SELECT location_code, location_type + FROM {$wpdb->prefix}woocommerce_tax_rate_locations + WHERE tax_rate_id = %d + ", $id ) ); + + if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) { + foreach ( $locales as $locale ) { + $data[ $locale->location_type ] = $locale->location_code; + } + } + + $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( $tax ) ); + + /** + * Filter tax object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $tax Tax object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_tax', $response, $tax, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $tax Tax object. + * @return array Links for the given tax. + */ + protected function prepare_links( $tax ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Taxes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'tax', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'country' => array( + 'description' => __( 'Country ISO 3166 code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'State code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postcode / ZIP.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'rate' => array( + 'description' => __( 'Tax rate.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tax rate name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'priority' => array( + 'description' => __( 'Tax priority.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 1, + 'context' => array( 'view', 'edit' ), + ), + 'compound' => array( + 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'shipping' => array( + 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'standard', + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + 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(); + $params['context']['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['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( + 'default' => 'asc', + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'enum' => array( 'asc', 'desc' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'default' => 'order', + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'enum' => array( + 'id', + 'order', + ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['class'] = array( + 'description' => __( 'Sort by tax class.', 'woocommerce' ), + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'sanitize_callback' => 'sanitize_title', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v1/class-wc-rest-webhook-deliveries-v1-controller.php b/includes/v1/class-wc-rest-webhook-deliveries-v1-controller.php new file mode 100644 index 00000000000..7b51ac7f4d3 --- /dev/null +++ b/includes/v1/class-wc-rest-webhook-deliveries-v1-controller.php @@ -0,0 +1,314 @@ +/deliveries endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Webhook Deliveries controller class. + * + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @package WooCommerce/API + * @extends WC_REST_Controller + */ +class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'webhooks/(?P[\d]+)/deliveries'; + + /** + * Register the routes for webhook deliveries. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'webhook_id' => array( + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + 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( + 'webhook_id' => array( + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read taxes. + * + * @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( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a tax. + * + * @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( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all webhook deliveries. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $webhook = wc_get_webhook( (int) $request['webhook_id'] ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $logs = array(); + $data = array(); + foreach ( $logs as $log ) { + $delivery = $this->prepare_item_for_response( (object) $log, $request ); + $delivery = $this->prepare_response_for_collection( $delivery ); + $data[] = $delivery; + } + + return rest_ensure_response( $data ); + } + + /** + * Get a single webhook delivery. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $webhook = wc_get_webhook( (int) $request['webhook_id'] ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $log = array(); + + if ( empty( $id ) || empty( $log ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $delivery = $this->prepare_item_for_response( (object) $log, $request ); + $response = rest_ensure_response( $delivery ); + + return $response; + } + + /** + * Prepare a single webhook delivery output for response. + * + * @param stdClass $log Delivery log object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $log, $request ) { + $data = (array) $log; + $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( $log ) ); + + /** + * Filter webhook delivery object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $log Delivery log object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $log Delivery log object. + * @return array Links for the given webhook delivery. + */ + protected function prepare_links( $log ) { + $webhook_id = (int) $log->request_headers['X-WC-Webhook-ID']; + $base = str_replace( '(?P[\d]+)', $webhook_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $log->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/webhooks/%d', $this->namespace, $webhook_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook_delivery', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'duration' => array( + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'summary' => array( + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_url' => array( + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_headers' => array( + 'description' => __( 'Request headers.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'request_body' => array( + 'description' => __( 'Request body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_code' => array( + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_message' => array( + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_headers' => array( + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'response_body' => array( + 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + '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() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/includes/v1/class-wc-rest-webhooks-v1-controller.php b/includes/v1/class-wc-rest-webhooks-v1-controller.php new file mode 100644 index 00000000000..15a9d07244c --- /dev/null +++ b/includes/v1/class-wc-rest-webhooks-v1-controller.php @@ -0,0 +1,763 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'topic' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook topic.', 'woocommerce' ), + ), + 'delivery_url' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read webhooks. + * + * @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( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create webhooks. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a webhook. + * + * @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( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a webhook. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a webhook. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get the default REST API version. + * + * @since 3.0.0 + * @return string + */ + protected function get_default_api_version() { + return 'wp_api_v1'; + } + + /** + * Get all webhooks. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $args = array(); + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['status'] = 'all' === $request['status'] ? '' : $request['status']; + $args['include'] = implode( ',', $request['include'] ); + $args['exclude'] = implode( ',', $request['exclude'] ); + $args['limit'] = $request['per_page']; + $args['search'] = $request['search']; + $args['before'] = $request['before']; + $args['after'] = $request['after']; + + if ( empty( $request['offset'] ) ) { + $args['offset'] = 1 < $request['page'] ? ( $request['page'] - 1 ) * $args['limit'] : 0; + } + + /** + * Filter arguments, before passing to WC_Webhook_Data_Store->search_webhooks, when querying webhooks via the REST API. + * + * @param array $args Array of arguments for $wpdb->get_results(). + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request ); + unset( $prepared_args['page'] ); + $prepared_args['paginate'] = true; + + // Get the webhooks. + $webhooks = array(); + $data_store = WC_Data_Store::load( 'webhook' ); + $results = $data_store->search_webhooks( $prepared_args ); + $webhook_ids = $results->webhooks; + + foreach ( $webhook_ids as $webhook_id ) { + $data = $this->prepare_item_for_response( $webhook_id, $request ); + $webhooks[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $webhooks ); + $per_page = (int) $prepared_args['limit']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + $total_webhooks = $results->total; + $max_pages = $results->max_num_pages; + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); + + $response->header( 'X-WP-Total', $total_webhooks ); + $response->header( 'X-WP-TotalPages', $max_pages ); + + 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; + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + + if ( empty( $id ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $id, $request ); + $response = rest_ensure_response( $data ); + + return $response; + } + + /** + * Create a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + // Validate topic. + if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Validate delivery URL. + if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + $webhook = new WC_Webhook(); + $webhook->set_name( $post->post_title ); + $webhook->set_user_id( $post->post_author ); + $webhook->set_status( 'publish' === $post->post_status ? 'active' : 'disabled' ); + $webhook->set_topic( $request['topic'] ); + $webhook->set_delivery_url( $request['delivery_url'] ); + $webhook->set_secret( ! empty( $request['secret'] ) ? $request['secret'] : wp_generate_password( 50, true, true ) ); + $webhook->set_api_version( $this->get_default_api_version() ); + $webhook->save(); + + $this->update_additional_fields_for_object( $webhook, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WC_Webhook $webhook Webhook data. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $webhook->get_id() ) ) ); + + // Send ping. + $webhook->deliver_ping(); + + return $response; + } + + /** + * Update a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Update topic. + if ( ! empty( $request['topic'] ) ) { + if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { + $webhook->set_topic( $request['topic'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update delivery URL. + if ( ! empty( $request['delivery_url'] ) ) { + if ( wc_is_valid_url( $request['delivery_url'] ) ) { + $webhook->set_delivery_url( $request['delivery_url'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update secret. + if ( ! empty( $request['secret'] ) ) { + $webhook->set_secret( $request['secret'] ); + } + + // Update status. + if ( ! empty( $request['status'] ) ) { + if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { + $webhook->set_status( $request['status'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + if ( isset( $post->post_title ) ) { + $webhook->set_name( $post->post_title ); + } + + $webhook->save(); + + $this->update_additional_fields_for_object( $webhook, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WC_Webhook $webhook Webhook data. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook, $request ); + $result = $webhook->delete( true ); + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param WC_Webhook $webhook The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_webhook_object", $webhook, $response, $request ); + + return $response; + } + + /** + * Prepare a single webhook for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $data = new stdClass; + + // Post ID. + if ( isset( $request['id'] ) ) { + $data->ID = absint( $request['id'] ); + } + + // Validate required POST fields. + if ( 'POST' === $request->get_method() && empty( $data->ID ) ) { + $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ); // @codingStandardsIgnoreLine + + // Post author. + $data->post_author = get_current_user_id(); + + // Post password. + $data->post_password = 'webhook_' . wp_generate_password(); + + // Post status. + $data->post_status = 'publish'; + } else { + + // Allow edit post title. + if ( ! empty( $request['name'] ) ) { + $data->post_title = $request['name']; + } + } + + // Comment status. + $data->comment_status = 'closed'; + + // Ping status. + $data->ping_status = 'closed'; + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param stdClass $data An object representing a single item prepared + * for inserting or updating the database. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $data, $request ); + } + + /** + * Prepare a single webhook output for response. + * + * @param int $id Webhook ID or object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $id, $request ) { + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $data = array( + 'id' => $webhook->get_id(), + 'name' => $webhook->get_name(), + 'status' => $webhook->get_status(), + 'topic' => $webhook->get_topic(), + 'resource' => $webhook->get_resource(), + 'event' => $webhook->get_event(), + 'hooks' => $webhook->get_hooks(), + 'delivery_url' => $webhook->get_delivery_url(), + 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), + ); + + $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( $webhook->get_id() ) ); + + /** + * Filter webhook object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Webhook $webhook Webhook object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); + } + + /** + * Prepare links for the request. + * + * @param int $id Webhook ID. + * @return array + */ + protected function prepare_links( $id ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Webhook status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'active', + 'enum' => array_keys( wc_get_webhook_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'topic' => array( + 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'resource' => array( + 'description' => __( 'Webhook resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'event' => array( + 'description' => __( 'Webhook event.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'hooks' => array( + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'delivery_url' => array( + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'secret' => array( + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $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['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' => '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', + 'id', + 'title', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['status'] = array( + 'default' => 'all', + 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'all', 'active', 'paused', 'disabled' ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v2/class-wc-rest-api-v2.php b/includes/v2/class-wc-rest-api-v2.php new file mode 100644 index 00000000000..ec6eb37228c --- /dev/null +++ b/includes/v2/class-wc-rest-api-v2.php @@ -0,0 +1,97 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'required' => true, + 'type' => 'string', + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return new WC_Coupon( $id ); + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + + $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); + $format_date = array( 'date_created', 'date_modified', 'date_expires' ); + $format_null = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], 2 ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format null values. + foreach ( $format_null as $key ) { + $data[ $key ] = $data[ $key ] ? $data[ $key ] : null; + } + + return array( + 'id' => $object->get_id(), + 'code' => $data['code'], + 'amount' => $data['amount'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_type' => $data['discount_type'], + 'description' => $data['description'], + 'date_expires' => $data['date_expires'], + 'date_expires_gmt' => $data['date_expires_gmt'], + 'usage_count' => $data['usage_count'], + 'individual_use' => $data['individual_use'], + 'product_ids' => $data['product_ids'], + 'excluded_product_ids' => $data['excluded_product_ids'], + 'usage_limit' => $data['usage_limit'], + 'usage_limit_per_user' => $data['usage_limit_per_user'], + 'limit_usage_to_x_items' => $data['limit_usage_to_x_items'], + 'free_shipping' => $data['free_shipping'], + 'product_categories' => $data['product_categories'], + 'excluded_product_categories' => $data['excluded_product_categories'], + 'exclude_sale_items' => $data['exclude_sale_items'], + 'minimum_amount' => $data['minimum_amount'], + 'maximum_amount' => $data['maximum_amount'], + 'email_restrictions' => $data['email_restrictions'], + 'used_by' => $data['used_by'], + 'meta_data' => $data['meta_data'], + ); + } + + /** + * Prepare a single coupon output for response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = $this->get_formatted_item_data( $object ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + if ( ! empty( $request['code'] ) ) { + $id = wc_get_coupon_id_by_code( $request['code'] ); + $args['post__in'] = array( $id ); + } + + // Get only ids. + $args['fields'] = 'ids'; + + return $args; + } + + /** + * Only return writable props from schema. + * + * @param array $schema Schema. + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Prepare a single coupon for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $coupon = new WC_Coupon( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Validate required POST fields. + if ( $creating && empty( $request['code'] ) ) { + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + } + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'code': + $coupon_code = wc_format_coupon_code( $value ); + $id = $coupon->get_id() ? $coupon->get_id() : 0; + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon->set_code( $coupon_code ); + break; + case 'meta_data': + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + case 'description': + $coupon->set_description( wp_filter_post_kses( $value ) ); + break; + default: + if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { + $coupon->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $coupon Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $coupon, $request, $creating ); + } + + /** + * Get the Coupon's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'amount' => array( + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_type' => array( + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'fixed_cart', + 'enum' => array_keys( wc_get_coupon_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Coupon description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_expires' => array( + 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_expires_gmt' => array( + 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'usage_count' => array( + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'individual_use' => array( + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_ids' => array( + 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'excluded_product_ids' => array( + 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit' => array( + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit_per_user' => array( + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'limit_usage_to_x_items' => array( + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'free_shipping' => array( + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_categories' => array( + 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'excluded_product_categories' => array( + 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'exclude_sale_items' => array( + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'minimum_amount' => array( + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'maximum_amount' => array( + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email_restrictions' => array( + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + 'used_by' => array( + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['code'] = array( + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v2/class-wc-rest-customer-downloads-v2-controller.php b/includes/v2/class-wc-rest-customer-downloads-v2-controller.php new file mode 100644 index 00000000000..887761e074b --- /dev/null +++ b/includes/v2/class-wc-rest-customer-downloads-v2-controller.php @@ -0,0 +1,165 @@ +/downloads endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Customers controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Customer_Downloads_V1_Controller + */ +class WC_REST_Customer_Downloads_V2_Controller extends WC_REST_Customer_Downloads_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Prepare a single download output for response. + * + * @param stdClass $download Download object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $download, $request ) { + $data = array( + 'download_id' => $download->download_id, + 'download_url' => $download->download_url, + 'product_id' => $download->product_id, + 'product_name' => $download->product_name, + 'download_name' => $download->download_name, + 'order_id' => $download->order_id, + 'order_key' => $download->order_key, + 'downloads_remaining' => '' === $download->downloads_remaining ? 'unlimited' : $download->downloads_remaining, + 'access_expires' => $download->access_expires ? wc_rest_prepare_date_response( $download->access_expires ) : 'never', + 'access_expires_gmt' => $download->access_expires ? wc_rest_prepare_date_response( get_gmt_from_date( $download->access_expires ) ) : 'never', + 'file' => $download->file, + ); + + $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( $download, $request ) ); + + /** + * Filter customer download data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $download Download object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); + } + + /** + * Get the Customer Download's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer_download', + 'type' => 'object', + 'properties' => array( + 'download_id' => array( + 'description' => __( 'Download ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_url' => array( + 'description' => __( 'Download file URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Downloadable product ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_name' => array( + 'description' => __( 'Downloadable file name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_id' => array( + 'description' => __( 'Order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'downloads_remaining' => array( + 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'access_expires' => array( + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'access_expires_gmt' => array( + 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File details.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-customers-v2-controller.php b/includes/v2/class-wc-rest-customers-v2-controller.php new file mode 100644 index 00000000000..cbb3d22afff --- /dev/null +++ b/includes/v2/class-wc-rest-customers-v2-controller.php @@ -0,0 +1,364 @@ +get_data(); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => $data['email'], + 'first_name' => $data['first_name'], + 'last_name' => $data['last_name'], + 'role' => $data['role'], + 'username' => $data['username'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'is_paying_customer' => $data['is_paying_customer'], + 'orders_count' => $object->get_order_count(), + 'total_spent' => $object->get_total_spent(), + 'avatar_url' => $object->get_avatar_url(), + 'meta_data' => $data['meta_data'], + ); + } + + /** + * Prepare a single customer output for response. + * + * @param WP_User $user_data User object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $user_data, $request ) { + $customer = new WC_Customer( $user_data->ID ); + $data = $this->get_formatted_item_data( $customer ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $user_data ) ); + + /** + * Filter customer data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_User $user_data User object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); + } + + /** + * Update customer meta fields. + * + * @param WC_Customer $customer Customer data. + * @param WP_REST_Request $request Request data. + */ + protected function update_customer_meta_fields( $customer, $request ) { + parent::update_customer_meta_fields( $customer, $request ); + + // Meta data. + if ( isset( $request['meta_data'] ) ) { + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $customer->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } + } + + /** + * Get the Customer's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'email' => array( + 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'first_name' => array( + 'description' => __( 'Customer first name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'last_name' => array( + 'description' => __( 'Customer last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'role' => array( + 'description' => __( 'Customer role.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'username' => array( + 'description' => __( 'Customer login name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_user', + ), + ), + 'password' => array( + 'description' => __( 'Customer password.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'billing' => array( + 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'is_paying_customer' => array( + 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), + 'type' => 'bool', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'orders_count' => array( + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_spent' => array( + 'description' => __( 'Total amount spent.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avatar_url' => array( + 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-network-orders-v2-controller.php b/includes/v2/class-wc-rest-network-orders-v2-controller.php new file mode 100644 index 00000000000..0ccd5150b62 --- /dev/null +++ b/includes/v2/class-wc-rest-network-orders-v2-controller.php @@ -0,0 +1,174 @@ +namespace, + '/' . $this->rest_base . '/network', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'network_orders' ), + 'permission_callback' => array( $this, 'network_orders_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + } + + /** + * Retrieves the item's schema for display / public consumption purposes. + * + * @return array Public item schema data. + */ + public function get_public_item_schema() { + $schema = parent::get_public_item_schema(); + + $schema['properties']['blog'] = array( + 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['edit_url'] = array( + 'description' => __( 'URL to edit the order', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['customer'][] = array( + 'description' => __( 'Name of the customer for the order', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['status_name'][] = array( + 'description' => __( 'Order Status', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['formatted_total'][] = array( + 'description' => __( 'Order total formatted for locale', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + + return $schema; + } + + /** + * Does a permissions check for the proper requested blog + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool $permission + */ + public function network_orders_permissions_check( $request ) { + $blog_id = $request->get_param( 'blog_id' ); + $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); + + switch_to_blog( $blog_id ); + + $permission = $this->get_items_permissions_check( $request ); + + restore_current_blog(); + + return $permission; + } + + /** + * Get a collection of orders from the requested blog id + * + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_REST_Response + */ + public function network_orders( $request ) { + $blog_id = $request->get_param( 'blog_id' ); + $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); + $active_plugins = get_blog_option( $blog_id, 'active_plugins', array() ); + $network_active_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + + $plugins = array_merge( $active_plugins, $network_active_plugins ); + $wc_active = false; + foreach ( $plugins as $plugin ) { + if ( substr_compare( $plugin, '/woocommerce.php', strlen( $plugin ) - strlen( '/woocommerce.php' ), strlen( '/woocommerce.php' ) ) === 0 ) { + $wc_active = true; + } + } + + // If WooCommerce not active for site, return an empty response. + if ( ! $wc_active ) { + $response = rest_ensure_response( array() ); + return $response; + } + + switch_to_blog( $blog_id ); + add_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); + $items = $this->get_items( $request ); + remove_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); + + foreach ( $items->data as &$current_order ) { + $order = wc_get_order( $current_order['id'] ); + + $current_order['blog'] = get_blog_details( get_current_blog_id() ); + $current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' ); + /* translators: 1: first name 2: last name */ + $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); + $current_order['status_name'] = wc_get_order_status_name( $order->get_status() ); + $current_order['formatted_total'] = $order->get_formatted_order_total(); + } + + restore_current_blog(); + + return $items; + } + + /** + * Filters the post statuses to on hold and processing for the network order query. + * + * @param array $args Query args. + * + * @return array + */ + public function network_orders_filter_args( $args ) { + $args['post_status'] = array( + 'wc-on-hold', + 'wc-processing', + ); + + return $args; + } +} diff --git a/includes/v2/class-wc-rest-order-notes-v2-controller.php b/includes/v2/class-wc-rest-order-notes-v2-controller.php new file mode 100644 index 00000000000..b7f31d1ea79 --- /dev/null +++ b/includes/v2/class-wc-rest-order-notes-v2-controller.php @@ -0,0 +1,182 @@ +/notes endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Order Notes controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Order_Notes_V1_Controller + */ +class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Get order notes from an order. + * + * @param WP_REST_Request $request Request data. + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $args = array( + 'post_id' => $order->get_id(), + 'approve' => 'approve', + 'type' => 'order_note', + ); + + // Allow filter by order note type. + if ( 'customer' === $request['type'] ) { + $args['meta_query'] = array( // WPCS: slow query ok. + array( + 'key' => 'is_customer_note', + 'value' => 1, + 'compare' => '=', + ), + ); + } elseif ( 'internal' === $request['type'] ) { + $args['meta_query'] = array( // WPCS: slow query ok. + array( + 'key' => 'is_customer_note', + 'compare' => 'NOT EXISTS', + ), + ); + } + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $data = array(); + foreach ( $notes as $note ) { + $order_note = $this->prepare_item_for_response( $note, $request ); + $order_note = $this->prepare_response_for_collection( $order_note ); + $data[] = $order_note; + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a single order note output for response. + * + * @param WP_Comment $note Order note object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $note, $request ) { + $data = array( + 'id' => (int) $note->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + $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( $note ) ); + + /** + * Filter order note object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $note Order note object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); + } + + /** + * Get the Order Notes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'order_note', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'note' => array( + 'description' => __( 'Order note content.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_note' => array( + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + 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['type'] = array( + 'default' => 'any', + 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'any', 'customer', 'internal' ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v2/class-wc-rest-order-refunds-v2-controller.php b/includes/v2/class-wc-rest-order-refunds-v2-controller.php new file mode 100644 index 00000000000..3ce6e7fbf82 --- /dev/null +++ b/includes/v2/class-wc-rest-order-refunds-v2-controller.php @@ -0,0 +1,584 @@ +/refunds endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Order Refunds controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Orders_V2_Controller + */ +class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'orders/(?P[\d]+)/refunds'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'shop_order_refund'; + + /** + * Stores the request. + * + * @var array + */ + protected $request = array(); + + /** + * Order refunds actions. + */ + public function __construct() { + add_filter( "woocommerce_rest_{$this->post_type}_object_trashable", '__return_false' ); + } + + /** + * Register the routes for order refunds. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_order( $id ); + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + $format_decimal = array( 'amount' ); + $format_date = array( 'date_created' ); + $format_line_items = array( 'line_items' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format line items. + foreach ( $format_line_items as $key ) { + $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'amount' => $data['amount'], + 'reason' => $data['reason'], + 'refunded_by' => $data['refunded_by'], + 'refunded_payment' => $data['refunded_payment'], + 'meta_data' => $data['meta_data'], + 'line_items' => $data['line_items'], + ); + } + + /** + * Prepare a single order output for response. + * + * @since 3.0.0 + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @return WP_Error|WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $this->request = $request; + $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + } + + $data = $this->get_formatted_item_data( $object ); + $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( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $base = str_replace( '(?P[\d]+)', $object->get_parent_id(), $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), + ), + ); + + return $links; + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + $args['post_status'] = array_keys( wc_get_order_statuses() ); + $args['post_parent__in'] = array( absint( $request['order_id'] ) ); + + return $args; + } + + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( 0 > $request['amount'] ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + } + + // Create the refund. + $refund = wc_create_refund( + array( + 'order_id' => $order->get_id(), + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) + ); + + if ( is_wp_error( $refund ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + } + + if ( ! $refund ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + $refund->save_meta_data(); + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $coupon Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'amount' => array( + 'description' => __( 'Refund amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'reason' => array( + 'description' => __( 'Reason for refund.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'refunded_by' => array( + 'description' => __( 'User ID of user who created the refund.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'refunded_payment' => array( + 'description' => __( 'If the payment was refunded via the API.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'api_refund' => array( + 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'edit' ), + 'default' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + unset( $params['status'], $params['customer'], $params['product'] ); + + return $params; + } +} diff --git a/includes/v2/class-wc-rest-orders-v2-controller.php b/includes/v2/class-wc-rest-orders-v2-controller.php new file mode 100644 index 00000000000..50689174f9c --- /dev/null +++ b/includes/v2/class-wc-rest-orders-v2-controller.php @@ -0,0 +1,1708 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. Return false if object is not of required type. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data|bool + */ + protected function get_object( $id ) { + $order = wc_get_order( $id ); + // In case id is a refund's id (or it's not an order at all), don't expose it via /orders/ path. + if ( ! $order || 'shop_order_refund' === $order->get_type() ) { + return false; + } + + return $order; + } + + /** + * Expands an order item to get its data. + * + * @param WC_Order_item $item Order item data. + * @return array + */ + protected function get_order_item_data( $item ) { + $data = $item->get_data(); + $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + if ( isset( $data[ $key ] ) ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + } + + // Add SKU and PRICE to products. + if ( is_callable( array( $item, 'get_product' ) ) ) { + $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; + $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; + } + + // Format taxes. + if ( ! empty( $data['taxes']['total'] ) ) { + $taxes = array(); + + foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { + $taxes[] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', + ); + } + $data['taxes'] = $taxes; + } elseif ( isset( $data['taxes'] ) ) { + $data['taxes'] = array(); + } + + // Remove names for coupons, taxes and shipping. + if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { + unset( $data['name'] ); + } + + // Remove props we don't want to expose. + unset( $data['order_id'] ); + unset( $data['type'] ); + + return $data; + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + $format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' ); + $format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' ); + $format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format the order status. + $data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status']; + + // Format line items. + foreach ( $format_line_items as $key ) { + $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); + } + + // Refunds. + $data['refunds'] = array(); + foreach ( $object->get_refunds() as $refund ) { + $data['refunds'][] = array( + 'id' => $refund->get_id(), + 'reason' => $refund->get_reason() ? $refund->get_reason() : '', + 'total' => '-' . wc_format_decimal( $refund->get_amount(), $this->request['dp'] ), + ); + } + + return array( + 'id' => $object->get_id(), + 'parent_id' => $data['parent_id'], + 'number' => $data['number'], + 'order_key' => $data['order_key'], + 'created_via' => $data['created_via'], + 'version' => $data['version'], + 'status' => $data['status'], + 'currency' => $data['currency'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_total' => $data['discount_total'], + 'discount_tax' => $data['discount_tax'], + 'shipping_total' => $data['shipping_total'], + 'shipping_tax' => $data['shipping_tax'], + 'cart_tax' => $data['cart_tax'], + 'total' => $data['total'], + 'total_tax' => $data['total_tax'], + 'prices_include_tax' => $data['prices_include_tax'], + 'customer_id' => $data['customer_id'], + 'customer_ip_address' => $data['customer_ip_address'], + 'customer_user_agent' => $data['customer_user_agent'], + 'customer_note' => $data['customer_note'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'payment_method' => $data['payment_method'], + 'payment_method_title' => $data['payment_method_title'], + 'transaction_id' => $data['transaction_id'], + 'date_paid' => $data['date_paid'], + 'date_paid_gmt' => $data['date_paid_gmt'], + 'date_completed' => $data['date_completed'], + 'date_completed_gmt' => $data['date_completed_gmt'], + 'cart_hash' => $data['cart_hash'], + 'meta_data' => $data['meta_data'], + 'line_items' => $data['line_items'], + 'tax_lines' => $data['tax_lines'], + 'shipping_lines' => $data['shipping_lines'], + 'fee_lines' => $data['fee_lines'], + 'coupon_lines' => $data['coupon_lines'], + 'refunds' => $data['refunds'], + ); + } + + /** + * Prepare a single order output for response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $this->request = $request; + $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); + $data = $this->get_formatted_item_data( $object ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + if ( 0 !== (int) $object->get_customer_id() ) { + $links['customer'] = array( + 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object->get_customer_id() ) ), + ); + } + + if ( 0 !== (int) $object->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), + ); + } + + return $links; + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + global $wpdb; + + $args = parent::prepare_objects_query( $request ); + + // Set post_status. + if ( in_array( $request['status'], $this->get_order_statuses(), true ) ) { + $args['post_status'] = 'wc-' . $request['status']; + } elseif ( 'any' === $request['status'] ) { + $args['post_status'] = 'any'; + } else { + $args['post_status'] = $request['status']; + } + + if ( isset( $request['customer'] ) ) { + if ( ! empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); // WPCS: slow query ok. + } + + $args['meta_query'][] = array( + 'key' => '_customer_user', + 'value' => $request['customer'], + 'type' => 'NUMERIC', + ); + } + + // Search by product. + if ( ! empty( $request['product'] ) ) { + $order_ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item'", + $request['product'] + ) + ); + + // Force WP_Query return empty if don't found any order. + $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); + + $args['post__in'] = $order_ids; + } + + // Search. + if ( ! empty( $args['s'] ) ) { + $order_ids = wc_order_search( $args['s'] ); + + if ( ! empty( $order_ids ) ) { + unset( $args['s'] ); + $args['post__in'] = array_merge( $order_ids, array( 0 ) ); + } + } + + /** + * Filter the query arguments for a request. + * + * Enables adding extra arguments or setting defaults for an order 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_orders_prepare_object_query', $args, $request ); + + return $args; + } + + /** + * Only return writable props from schema. + * + * @param array $schema Schema. + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Prepare a single order for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $order = new WC_Order( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'status': + // Status change should be done later so transitions have new data. + break; + case 'billing': + case 'shipping': + $this->update_address( $order, $value, $key ); + break; + case 'line_items': + case 'shipping_lines': + case 'fee_lines': + case 'coupon_lines': + if ( is_array( $value ) ) { + foreach ( $value as $item ) { + if ( is_array( $item ) ) { + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $order->remove_item( $item['id'] ); + } else { + $this->set_item( $order, $key, $item ); + } + } + } + } + break; + case 'meta_data': + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + default: + if ( is_callable( array( $order, "set_{$key}" ) ) ) { + $order->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $order Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @throws WC_REST_Exception But all errors are validated before returning any data. + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + // Make sure gateways are loaded so hooks from gateways fire on save/create. + WC()->payment_gateways(); + + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { + // Make sure customer exists. + if ( false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } + } + + if ( $creating ) { + $object->set_created_via( 'rest-api' ); + $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $object->calculate_totals(); + } else { + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $object->calculate_totals( true ); + } + } + + // Set status. + if ( ! empty( $request['status'] ) ) { + $object->set_status( $request['status'] ); + } + + $object->save(); + + // Actions for after the order is saved. + if ( true === $request['set_paid'] ) { + if ( $creating || $object->needs_payment() ) { + $object->payment_complete( $request['transaction_id'] ); + } + } + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update address. + * + * @param WC_Order $order Order data. + * @param array $posted Posted data. + * @param string $type Address type. + */ + protected function update_address( $order, $posted, $type = 'billing' ) { + foreach ( $posted as $key => $value ) { + if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { + $order->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Gets the product ID from the SKU or posted ID. + * + * @throws WC_REST_Exception When SKU or ID is not valid. + * @param array $posted Request data. + * @return int + */ + protected function get_product_id( $posted ) { + if ( ! empty( $posted['sku'] ) ) { + $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); + } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['product_id']; + } elseif ( ! empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['variation_id']; + } else { + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + } + return $product_id; + } + + /** + * Maybe set an item prop if the value was posted. + * + * @param WC_Order_Item $item Order item. + * @param string $prop Order property. + * @param array $posted Request data. + */ + protected function maybe_set_item_prop( $item, $prop, $posted ) { + if ( isset( $posted[ $prop ] ) ) { + $item->{"set_$prop"}( $posted[ $prop ] ); + } + } + + /** + * Maybe set item props if the values were posted. + * + * @param WC_Order_Item $item Order item data. + * @param string[] $props Properties. + * @param array $posted Request data. + */ + protected function maybe_set_item_props( $item, $props, $posted ) { + foreach ( $props as $prop ) { + $this->maybe_set_item_prop( $item, $prop, $posted ); + } + } + + /** + * Maybe set item meta if posted. + * + * @param WC_Order_Item $item Order item data. + * @param array $posted Request data. + */ + protected function maybe_set_item_meta_data( $item, $posted ) { + if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { + foreach ( $posted['meta_data'] as $meta ) { + if ( isset( $meta['key'] ) ) { + $value = isset( $meta['value'] ) ? $meta['value'] : null; + $item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } + } + + /** + * Create or update a line item. + * + * @param array $posted Line item data. + * @param string $action 'create' to add line item or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Product + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_line_items( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + $product = wc_get_product( $this->get_product_id( $posted ) ); + + if ( $product !== $item->get_product() ) { + $item->set_product( $product ); + + if ( 'create' === $action ) { + $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; + $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); + $item->set_total( $total ); + $item->set_subtotal( $total ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Create or update an order shipping method. + * + * @param array $posted $shipping Item data. + * @param string $action 'create' to add shipping or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Shipping + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + + if ( 'create' === $action ) { + if ( empty( $posted['method_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Create or update an order fee. + * + * @param array $posted Item data. + * @param string $action 'create' to add fee or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Fee + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + + if ( 'create' === $action ) { + if ( empty( $posted['name'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Create or update an order coupon. + * + * @param array $posted Item data. + * @param string $action 'create' to add coupon or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Coupon + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + + if ( 'create' === $action ) { + if ( empty( $posted['code'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Wrapper method to create/update order items. + * When updating, the item ID provided is checked to ensure it is associated + * with the order. + * + * @param WC_Order $order order object. + * @param string $item_type The item type. + * @param array $posted item provided in the request body. + * @throws WC_REST_Exception If item ID is not associated with order. + */ + protected function set_item( $order, $item_type, $posted ) { + global $wpdb; + + if ( ! empty( $posted['id'] ) ) { + $action = 'update'; + } else { + $action = 'create'; + } + + $method = 'prepare_' . $item_type; + $item = null; + + // Verify provided line item ID is associated with order. + if ( 'update' === $action ) { + $item = $order->get_item( absint( $posted['id'] ), false ); + + if ( ! $item ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + } + } + + // Prepare item data. + $item = $this->$method( $posted, $action, $item ); + + do_action( 'woocommerce_rest_set_order_item', $item, $posted ); + + // If creating the order, add the item to it. + if ( 'create' === $action ) { + $order->add_item( $item ); + } else { + $item->save(); + } + } + + /** + * Helper method to check if the resource ID associated with the provided item is null. + * Items can be deleted by setting the resource ID to null. + * + * @param array $item Item provided in the request body. + * @return bool True if the item resource ID is null, false otherwise. + */ + protected function item_is_null( $item ) { + $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); + + foreach ( $keys as $key ) { + if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { + return true; + } + } + + return false; + } + + /** + * Get order statuses without prefixes. + * + * @return array + */ + protected function get_order_statuses() { + $order_statuses = array(); + + foreach ( array_keys( wc_get_order_statuses() ) as $status ) { + $order_statuses[] = str_replace( 'wc-', '', $status ); + } + + return $order_statuses; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + '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' => __( 'Parent order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'number' => array( + 'description' => __( 'Order number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'created_via' => array( + 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'version' => array( + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Order status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'pending', + 'enum' => $this->get_order_statuses(), + 'context' => array( 'view', 'edit' ), + ), + 'currency' => array( + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), + 'type' => 'string', + 'default' => get_woocommerce_currency(), + 'enum' => array_keys( get_woocommerce_currencies() ), + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_total' => array( + 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_tax' => array( + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_total' => array( + 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax' => array( + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_tax' => array( + 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Grand total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Sum of all taxes.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'prices_include_tax' => array( + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_id' => array( + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 0, + 'context' => array( 'view', 'edit' ), + ), + 'customer_ip_address' => array( + 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_user_agent' => array( + 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_note' => array( + 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'billing' => array( + 'description' => __( 'Billing address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'Shipping address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'payment_method' => array( + 'description' => __( 'Payment method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'payment_method_title' => array( + 'description' => __( 'Payment method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'transaction_id' => array( + 'description' => __( 'Unique transaction ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_paid' => array( + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_paid_gmt' => array( + 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_completed' => array( + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_completed_gmt' => array( + 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_hash' => array( + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tax_lines' => array( + 'description' => __( 'Tax lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_code' => array( + 'description' => __( 'Tax rate code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Tax rate label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'compound' => array( + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_total' => array( + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax_total' => array( + 'description' => __( 'Shipping tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'shipping_lines' => array( + 'description' => __( 'Shipping lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_title' => array( + 'description' => __( 'Shipping method name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'instance_id' => array( + 'description' => __( 'Shipping instance ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'fee_lines' => array( + 'description' => __( 'Fee lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Fee name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'taxable', 'none' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'coupon_lines' => array( + 'description' => __( 'Coupons line data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'discount' => array( + 'description' => __( 'Discount total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'discount_tax' => array( + 'description' => __( 'Discount total tax.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'refunds' => array( + 'description' => __( 'List of refunds.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Refund ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reason' => array( + 'description' => __( 'Refund reason.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Refund total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'set_paid' => array( + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['customer'] = array( + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['product'] = array( + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['dp'] = array( + 'default' => wc_get_price_decimals(), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v2/class-wc-rest-payment-gateways-v2-controller.php b/includes/v2/class-wc-rest-payment-gateways-v2-controller.php new file mode 100644 index 00000000000..02e71571126 --- /dev/null +++ b/includes/v2/class-wc-rest-payment-gateways-v2-controller.php @@ -0,0 +1,466 @@ + + */ + public function register_routes() { + register_rest_route( + $this->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[\w-]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view payment gateways. + * + * @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( 'payment_gateways', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to read a payment gateway. + * + * @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( 'payment_gateways', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check whether a given request has permission to edit payment gateways. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get payment gateways. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $payment_gateways = WC()->payment_gateways->payment_gateways(); + $response = array(); + foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { + $payment_gateway->id = $payment_gateway_id; + $gateway = $this->prepare_item_for_response( $payment_gateway, $request ); + $gateway = $this->prepare_response_for_collection( $gateway ); + $response[] = $gateway; + } + return rest_ensure_response( $response ); + } + + /** + * Get a single payment gateway. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $gateway = $this->get_gateway( $request ); + + if ( is_null( $gateway ) ) { + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $gateway = $this->prepare_item_for_response( $gateway, $request ); + return rest_ensure_response( $gateway ); + } + + /** + * Update A Single Payment Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_item( $request ) { + $gateway = $this->get_gateway( $request ); + + if ( is_null( $gateway ) ) { + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Get settings. + $gateway->init_form_fields(); + $settings = $gateway->settings; + + // Update settings. + if ( isset( $request['settings'] ) ) { + $errors_found = false; + foreach ( $gateway->form_fields as $key => $field ) { + if ( isset( $request['settings'][ $key ] ) ) { + if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); + } else { + $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); + } + if ( is_wp_error( $value ) ) { + $errors_found = true; + break; + } + $settings[ $key ] = $value; + } + } + + if ( $errors_found ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update if this method is enabled or not. + if ( isset( $request['enabled'] ) ) { + $settings['enabled'] = wc_bool_to_string( $request['enabled'] ); + $gateway->enabled = $settings['enabled']; + } + + // Update title. + if ( isset( $request['title'] ) ) { + $settings['title'] = $request['title']; + $gateway->title = $settings['title']; + } + + // Update description. + if ( isset( $request['description'] ) ) { + $settings['description'] = $request['description']; + $gateway->description = $settings['description']; + } + + // Update options. + $gateway->settings = $settings; + update_option( $gateway->get_option_key(), apply_filters( 'woocommerce_gateway_' . $gateway->id . '_settings_values', $settings, $gateway ) ); + + // Update order. + if ( isset( $request['order'] ) ) { + $order = (array) get_option( 'woocommerce_gateway_order' ); + $order[ $gateway->id ] = $request['order']; + update_option( 'woocommerce_gateway_order', $order ); + $gateway->order = absint( $request['order'] ); + } + + $gateway = $this->prepare_item_for_response( $gateway, $request ); + return rest_ensure_response( $gateway ); + } + + /** + * Get a gateway based on the current request object. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|null + */ + public function get_gateway( $request ) { + $gateway = null; + $payment_gateways = WC()->payment_gateways->payment_gateways(); + foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { + if ( $request['id'] !== $payment_gateway_id ) { + continue; + } + $payment_gateway->id = $payment_gateway_id; + $gateway = $payment_gateway; + } + return $gateway; + } + + /** + * Prepare a payment gateway for response. + * + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $gateway, $request ) { + $order = (array) get_option( 'woocommerce_gateway_order' ); + $item = array( + 'id' => $gateway->id, + 'title' => $gateway->title, + 'description' => $gateway->description, + 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', + 'enabled' => ( 'yes' === $gateway->enabled ), + 'method_title' => $gateway->get_method_title(), + 'method_description' => $gateway->get_method_description(), + 'settings' => $this->get_settings( $gateway ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $gateway, $request ) ); + + /** + * Filter payment gateway objects returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); + } + + /** + * Return settings associated with this payment gateway. + * + * @param WC_Payment_Gateway $gateway Gateway data. + * + * @return array + */ + public function get_settings( $gateway ) { + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type. + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + // Ignore 'title' settings/fields -- they are UI only. + if ( 'title' === $field['type'] ) { + continue; + } + // Ignore 'enabled' and 'description' which get included elsewhere. + if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { + continue; + } + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Prepare links for the request. + * + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $gateway, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $gateway->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the payment gateway schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'payment_gateway', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + ), + 'enabled' => array( + 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_title' => array( + 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'settings' => array( + 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + +} diff --git a/includes/v2/class-wc-rest-product-attribute-terms-v2-controller.php b/includes/v2/class-wc-rest-product-attribute-terms-v2-controller.php new file mode 100644 index 00000000000..23ad5e14d9c --- /dev/null +++ b/includes/v2/class-wc-rest-product-attribute-terms-v2-controller.php @@ -0,0 +1,27 @@ +/terms endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Product Attribute Terms controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Product_Attribute_Terms_V1_Controller + */ +class WC_REST_Product_Attribute_Terms_V2_Controller extends WC_REST_Product_Attribute_Terms_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; +} diff --git a/includes/v2/class-wc-rest-product-attributes-v2-controller.php b/includes/v2/class-wc-rest-product-attributes-v2-controller.php new file mode 100644 index 00000000000..59d5416b52e --- /dev/null +++ b/includes/v2/class-wc-rest-product-attributes-v2-controller.php @@ -0,0 +1,27 @@ +term_id, 'display_type', true ); + + // Get category order. + $menu_order = get_term_meta( $item->term_id, 'order', true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'parent' => (int) $item->parent, + 'description' => $item->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => null, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + // Get category image. + $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); + if ( $image_id ) { + $attachment = get_post( $image_id ); + + $data['image'] = array( + 'id' => (int) $image_id, + 'date_created' => wc_rest_prepare_date_response( $attachment->post_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), + 'src' => wp_get_attachment_url( $image_id ), + 'title' => get_the_title( $attachment ), + 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Category schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'parent' => array( + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'display' => array( + 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'default', + 'enum' => array( 'default', 'products', 'subcategories', 'both' ), + 'context' => array( 'view', 'edit' ), + ), + 'image' => array( + 'description' => __( 'Image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'title' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-product-reviews-v2-controller.php b/includes/v2/class-wc-rest-product-reviews-v2-controller.php new file mode 100644 index 00000000000..5eb6ca0ab07 --- /dev/null +++ b/includes/v2/class-wc-rest-product-reviews-v2-controller.php @@ -0,0 +1,199 @@ +/reviews. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Product Reviews Controller Class. + * + * @package WooCommerce/API + * @extends WC_REST_Product_Reviews_V1_Controller + */ +class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/(?P[\d]+)/reviews'; + + /** + * Register the routes for product reviews. + */ + public function register_routes() { + parent::register_routes(); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Check if a given request has access to batch manage product reviews. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( 'product', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Prepare a single product review output for response. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $review, $request ) { + $data = array( + 'id' => (int) $review->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $review->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $review->comment_date_gmt ), + 'review' => $review->comment_content, + 'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ), + 'name' => $review->comment_author, + 'email' => $review->comment_author_email, + 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), + ); + + $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( $review, $request ) ); + + /** + * Filter product reviews object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $review Product review object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + } + + + /** + * Bulk create, update and delete items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + $items = array_filter( $request->get_params() ); + $params = $request->get_url_params(); + $product_id = $params['product_id']; + $body_params = array(); + + foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { + if ( ! empty( $items[ $batch_type ] ) ) { + $injected_items = array(); + foreach ( $items[ $batch_type ] as $item ) { + $injected_items[] = is_array( $item ) ? array_merge( array( 'product_id' => $product_id ), $item ) : $item; + } + $body_params[ $batch_type ] = $injected_items; + } + } + + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( $body_params ); + + return parent::batch_items( $request ); + } + + /** + * Get the Product Review's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_review', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'rating' => array( + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'verified' => array( + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-product-shipping-classes-v2-controller.php b/includes/v2/class-wc-rest-product-shipping-classes-v2-controller.php new file mode 100644 index 00000000000..1eeec0041df --- /dev/null +++ b/includes/v2/class-wc-rest-product-shipping-classes-v2-controller.php @@ -0,0 +1,27 @@ +/variations endpoints. + * + * @package WooCommerce\API + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API variations controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Products_V2_Controller + */ +class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/(?P[\d]+)/variations'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'product_variation'; + + /** + * Initialize product actions (parent). + */ + public function __construct() { + add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'add_product_id' ), 9, 2 ); + parent::__construct(); + } + + /** + * Register the routes for products. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_product( $id ); + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + // Check if variation belongs to the correct parent product. + if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Prepare a single variation output for response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = array( + 'id' => $object->get_id(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), + 'description' => wc_format_content( $object->get_description() ), + 'permalink' => $object->get_permalink(), + 'sku' => $object->get_sku(), + 'price' => $object->get_price(), + 'regular_price' => $object->get_regular_price(), + 'sale_price' => $object->get_sale_price(), + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), + 'on_sale' => $object->is_on_sale(), + 'visible' => $object->is_visible(), + 'purchasable' => $object->is_purchasable(), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => $this->get_downloads( $object ), + 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, + 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, + 'tax_status' => $object->get_tax_status(), + 'tax_class' => $object->get_tax_class(), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity(), + 'in_stock' => $object->is_in_stock(), + 'backorders' => $object->get_backorders(), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'weight' => $object->get_weight(), + 'dimensions' => array( + 'length' => $object->get_length(), + 'width' => $object->get_width(), + 'height' => $object->get_height(), + ), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id(), + 'image' => current( $this->get_images( $object ) ), + 'attributes' => $this->get_attributes( $object ), + 'menu_order' => $object->get_menu_order(), + 'meta_data' => $object->get_meta_data(), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + $args['post_parent'] = $request['product_id']; + + return $args; + } + + /** + * Prepare a single variation for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + if ( isset( $request['id'] ) ) { + $variation = wc_get_product( absint( $request['id'] ) ); + } else { + $variation = new WC_Product_Variation(); + } + + // Update parent ID just once. + if ( 0 === $variation->get_parent_id() ) { + $variation->set_parent_id( absint( $request['product_id'] ) ); + } + + // Status. + if ( isset( $request['visible'] ) ) { + $variation->set_status( false === $request['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $request['sku'] ) ) { + $variation->set_sku( wc_clean( $request['sku'] ) ); + } + + // Thumbnail. + if ( isset( $request['image'] ) ) { + if ( is_array( $request['image'] ) && ! empty( $request['image'] ) ) { + $image = $request['image']; + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->set_product_images( $variation, array( $image ) ); + } else { + $variation->set_image_id( '' ); + } + } + + // Virtual variation. + if ( isset( $request['virtual'] ) ) { + $variation->set_virtual( $request['virtual'] ); + } + + // Downloadable variation. + if ( isset( $request['downloadable'] ) ) { + $variation->set_downloadable( $request['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $variation->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $variation->set_download_expiry( $request['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $request ); + + // Stock handling. + if ( isset( $request['manage_stock'] ) ) { + if ( 'parent' === $request['manage_stock'] ) { + $variation->set_manage_stock( false ); // This just indicates the variation does not manage stock, but the parent does. + } else { + $variation->set_manage_stock( wc_string_to_bool( $request['manage_stock'] ) ); + } + } + + if ( isset( $request['in_stock'] ) ) { + $variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' ); + } + + if ( isset( $request['backorders'] ) ) { + $variation->set_backorders( $request['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $request['stock_quantity'] ) ) { + $variation->set_stock_quantity( $request['stock_quantity'] ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $variation->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $variation->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + + // Tax class. + if ( isset( $request['tax_class'] ) ) { + $variation->set_tax_class( $request['tax_class'] ); + } + + // Description. + if ( isset( $request['description'] ) ) { + $variation->set_description( wp_kses_post( $request['description'] ) ); + } + + // Update taxonomies. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + $parent = wc_get_product( $variation->get_parent_id() ); + $parent_attributes = $parent->get_attributes(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $raw_attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $raw_attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $raw_attribute_name ) { + continue; + } + + $attribute_name = sanitize_title( $raw_attribute_name ); + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $raw_attribute_name ); // @codingStandardsIgnoreLine + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + // Menu order. + if ( $request['menu_order'] ) { + $variation->set_menu_order( $request['menu_order'] ); + } + + // Meta data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $variation Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); + } + + /** + * Clear caches here so in sync with any new variations. + * + * @param WC_Data $object Object data. + */ + public function clear_transients( $object ) { + wc_delete_product_transients( $object->get_parent_id() ); + wp_cache_delete( 'product-' . $object->get_parent_id(), 'products' ); + } + + /** + * Delete a variation. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( + "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( + 'status' => 404, + ) + ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( + /* translators: %s: post type */ + "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( + 'status' => rest_authorization_required_code(), + ) + ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $object->delete( true ); + $result = 0 === $object->get_id(); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( + 'status' => 501, + ) + ); + } + + // Otherwise, only trash if we haven't already. + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( + 'status' => 410, + ) + ); + } + + $object->delete(); + $result = 'trash' === $object->get_status(); + } + } + + if ( ! $result ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( + 'status' => 500, + ) + ); + } + + // Delete parent product transients. + if ( 0 !== $object->get_parent_id() ) { + wc_delete_product_transients( $object->get_parent_id() ); + } + + /** + * Fires after a single object is deleted or trashed via the REST API. + * + * @param WC_Data $object The deleted or trashed object. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); + + return $response; + } + + /** + * Bulk create, update and delete items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + $items = array_filter( $request->get_params() ); + $params = $request->get_url_params(); + $product_id = $params['product_id']; + $body_params = array(); + + foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { + if ( ! empty( $items[ $batch_type ] ) ) { + $injected_items = array(); + foreach ( $items[ $batch_type ] as $item ) { + $injected_items[] = is_array( $item ) ? array_merge( + array( + 'product_id' => $product_id, + ), $item + ) : $item; + } + $body_params[ $batch_type ] = $injected_items; + } + } + + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( $body_params ); + + return parent::batch_items( $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $product_id = (int) $request['product_id']; + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), + ), + ); + return $links; + } + + /** + * Get the Variation's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Variation description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'visible' => array( + 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'mixed', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-products-v2-controller.php b/includes/v2/class-wc-rest-products-v2-controller.php new file mode 100644 index 00000000000..d3558ded964 --- /dev/null +++ b/includes/v2/class-wc-rest-products-v2-controller.php @@ -0,0 +1,2207 @@ +post_type}_object", array( $this, 'clear_transients' ) ); + } + + /** + * Register the routes for products. + */ + public function register_routes() { + register_rest_route( + $this->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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'type' => 'boolean', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. + * + * @param int $id Object ID. + * + * @since 3.0.0 + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_product( $id ); + } + + /** + * Prepare a single product output for response. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @since 3.0.0 + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->get_product_data( $object, $context ); + + // Add variations to variable products. + if ( $object->is_type( 'variable' ) && $object->has_child() ) { + $data['variations'] = $object->get_children(); + } + + // Add grouped products data. + if ( $object->is_type( 'grouped' ) && $object->has_child() ) { + $data['grouped_products'] = $object->get_children(); + } + + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare objects query. + * + * @param WP_REST_Request $request Full details about the request. + * + * @since 3.0.0 + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + // Set post_status. + $args['post_status'] = $request['status']; + + // Taxonomy query to filter products by type, category, + // tag, shipping class, and attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies = array( + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + if ( ! empty( $tax_query ) ) { + $args['tax_query'] = $tax_query; // WPCS: slow query ok. + } + + // Filter featured. + if ( is_bool( $request['featured'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'featured', + 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', + ); + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product in stock or out of stock. + if ( is_bool( $request['in_stock'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_stock_status', + 'value' => true === $request['in_stock'] ? 'instock' : 'outofstock', + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + return $args; + } + + /** + * Get the downloads for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * + * @return array + */ + protected function get_downloads( $product ) { + $downloads = array(); + + if ( $product->is_downloadable() ) { + foreach ( $product->get_downloads() as $file_id => $file ) { + $downloads[] = array( + 'id' => $file_id, // MD5 hash. + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param string $taxonomy Taxonomy slug. + * + * @return array + */ + protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { + $terms = array(); + + foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { + $terms[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + ); + } + + return $terms; + } + + /** + * Get the images for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * + * @return array + */ + protected function get_images( $product ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( $product->get_image_id() ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $position => $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + 'position' => (int) $position, + ); + } + + // Set a placeholder image if the product has no images set. + if ( empty( $images ) ) { + $images[] = array( + 'id' => 0, + 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), // Default to now. + 'date_created_gmt' => wc_rest_prepare_date_response( current_time( 'timestamp', true ) ), // Default to now. + 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( current_time( 'timestamp', true ) ), + 'src' => wc_placeholder_img_src(), + 'name' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), + 'position' => 0, + ); + } + + return $images; + } + + /** + * Get attribute taxonomy label. + * + * @param string $name Taxonomy name. + * + * @deprecated 3.0.0 + * @return string + */ + protected function get_attribute_taxonomy_label( $name ) { + $tax = get_taxonomy( $name ); + $labels = get_taxonomy_labels( $tax ); + + return $labels->singular_name; + } + + /** + * Get product attribute taxonomy name. + * + * @param string $slug Taxonomy name. + * @param WC_Product $product Product data. + * + * @since 3.0.0 + * @return string + */ + protected function get_attribute_taxonomy_name( $slug, $product ) { + // Format slug so it matches attributes of the product. + $slug = wc_attribute_taxonomy_slug( $slug ); + $attributes = $product->get_attributes(); + $attribute = false; + + // pa_ attributes. + if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { + $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; + } elseif ( isset( $attributes[ $slug ] ) ) { + $attribute = $attributes[ $slug ]; + } + + if ( ! $attribute ) { + return $slug; + } + + // Taxonomy attribute name. + if ( $attribute->is_taxonomy() ) { + $taxonomy = $attribute->get_taxonomy_object(); + return $taxonomy->attribute_label; + } + + // Custom product attribute name. + return $attribute->get_name(); + } + + /** + * Get default attributes. + * + * @param WC_Product $product Product instance. + * + * @return array + */ + protected function get_default_attributes( $product ) { + $default = array(); + + if ( $product->is_type( 'variable' ) ) { + foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { + if ( 0 === strpos( $key, 'pa_' ) ) { + $default[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $key ), + 'name' => $this->get_attribute_taxonomy_name( $key, $product ), + 'option' => $value, + ); + } else { + $default[] = array( + 'id' => 0, + 'name' => $this->get_attribute_taxonomy_name( $key, $product ), + 'option' => $value, + ); + } + } + } + + return $default; + } + + /** + * Get attribute options. + * + * @param int $product_id Product ID. + * @param array $attribute Attribute data. + * + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( + $product_id, + $attribute['name'], + array( + 'fields' => 'names', + ) + ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * + * @return array + */ + protected function get_attributes( $product ) { + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + $_product = wc_get_product( $product->get_parent_id() ); + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + $name = str_replace( 'attribute_', '', $attribute_name ); + + if ( empty( $attribute ) && '0' !== $attribute ) { + continue; + } + + // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. + if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $name ); + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $name ), + 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), + 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), + 'option' => $attribute, + ); + } + } + } else { + foreach ( $product->get_attributes() as $attribute ) { + $attributes[] = array( + 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, + 'name' => $this->get_attribute_taxonomy_name( $attribute['name'], $product ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + + return $attributes; + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @param string $context Request context. + * Options: 'view' and 'edit'. + * + * @return array + */ + protected function get_product_data( $product, $context = 'view' ) { + $data = array( + 'id' => $product->get_id(), + 'name' => $product->get_name( $context ), + 'slug' => $product->get_slug( $context ), + 'permalink' => $product->get_permalink(), + 'date_created' => wc_rest_prepare_date_response( $product->get_date_created( $context ), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $product->get_date_created( $context ) ), + 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified( $context ), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $product->get_date_modified( $context ) ), + 'type' => $product->get_type(), + 'status' => $product->get_status( $context ), + 'featured' => $product->is_featured(), + 'catalog_visibility' => $product->get_catalog_visibility( $context ), + 'description' => 'view' === $context ? wpautop( do_shortcode( $product->get_description() ) ) : $product->get_description( $context ), + 'short_description' => 'view' === $context ? apply_filters( 'woocommerce_short_description', $product->get_short_description() ) : $product->get_short_description( $context ), + 'sku' => $product->get_sku( $context ), + 'price' => $product->get_price( $context ), + 'regular_price' => $product->get_regular_price( $context ), + 'sale_price' => $product->get_sale_price( $context ) ? $product->get_sale_price( $context ) : '', + 'date_on_sale_from' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ) ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ) ), + 'price_html' => $product->get_price_html(), + 'on_sale' => $product->is_on_sale( $context ), + 'purchasable' => $product->is_purchasable(), + 'total_sales' => $product->get_total_sales( $context ), + 'virtual' => $product->is_virtual(), + 'downloadable' => $product->is_downloadable(), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit( $context ), + 'download_expiry' => $product->get_download_expiry( $context ), + 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url( $context ) : '', + 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text( $context ) : '', + 'tax_status' => $product->get_tax_status( $context ), + 'tax_class' => $product->get_tax_class( $context ), + 'manage_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity( $context ), + 'in_stock' => $product->is_in_stock(), + 'backorders' => $product->get_backorders( $context ), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'weight' => $product->get_weight( $context ), + 'dimensions' => array( + 'length' => $product->get_length( $context ), + 'width' => $product->get_width( $context ), + 'height' => $product->get_height( $context ), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => $product->get_shipping_class_id( $context ), + 'reviews_allowed' => $product->get_reviews_allowed( $context ), + 'average_rating' => 'view' === $context ? wc_format_decimal( $product->get_average_rating(), 2 ) : $product->get_average_rating( $context ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids( $context ) ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids( $context ) ), + 'parent_id' => $product->get_parent_id( $context ), + 'purchase_note' => 'view' === $context ? wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ) : $product->get_purchase_note( $context ), + 'categories' => $this->get_taxonomy_terms( $product ), + 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), + 'images' => $this->get_images( $product ), + 'attributes' => $this->get_attributes( $product ), + 'default_attributes' => $this->get_default_attributes( $product ), + 'variations' => array(), + 'grouped_products' => array(), + 'menu_order' => $product->get_menu_order( $context ), + 'meta_data' => $product->get_meta_data(), + ); + + return $data; + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), // @codingStandardsIgnoreLine. + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), // @codingStandardsIgnoreLine. + ), + ); + + if ( $object->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $object->get_parent_id() ) ), // @codingStandardsIgnoreLine. + ); + } + + return $links; + } + + /** + * Prepare a single product for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + + // Type is the most important part here because we need to be using the correct class and methods. + if ( isset( $request['type'] ) ) { + $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + + $product = new $classname( $id ); + } elseif ( isset( $request['id'] ) ) { + $product = wc_get_product( $id ); + } else { + $product = new WC_Product_Simple(); + } + + if ( 'variation' === $product->get_type() ) { + return new WP_Error( + "woocommerce_rest_invalid_{$this->post_type}_id", + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + + // Post title. + if ( isset( $request['name'] ) ) { + $product->set_name( wp_filter_post_kses( $request['name'] ) ); + } + + // Post content. + if ( isset( $request['description'] ) ) { + $product->set_description( wp_filter_post_kses( $request['description'] ) ); + } + + // Post excerpt. + if ( isset( $request['short_description'] ) ) { + $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); + } + + // Post status. + if ( isset( $request['status'] ) ) { + $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // Post slug. + if ( isset( $request['slug'] ) ) { + $product->set_slug( $request['slug'] ); + } + + // Menu order. + if ( isset( $request['menu_order'] ) ) { + $product->set_menu_order( $request['menu_order'] ); + } + + // Comment status. + if ( isset( $request['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $request['reviews_allowed'] ); + } + + // Virtual. + if ( isset( $request['virtual'] ) ) { + $product->set_virtual( $request['virtual'] ); + } + + // Tax status. + if ( isset( $request['tax_status'] ) ) { + $product->set_tax_status( $request['tax_status'] ); + } + + // Tax Class. + if ( isset( $request['tax_class'] ) ) { + $product->set_tax_class( $request['tax_class'] ); + } + + // Catalog Visibility. + if ( isset( $request['catalog_visibility'] ) ) { + $product->set_catalog_visibility( $request['catalog_visibility'] ); + } + + // Purchase Note. + if ( isset( $request['purchase_note'] ) ) { + $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); + } + + // Featured Product. + if ( isset( $request['featured'] ) ) { + $product->set_featured( $request['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $request ); + + // SKU. + if ( isset( $request['sku'] ) ) { + $product->set_sku( wc_clean( $request['sku'] ) ); + } + + // Attributes. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + } else { + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $product->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $product->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + } + + // Product parent ID. + if ( isset( $request['parent_id'] ) ) { + $product->set_parent_id( $request['parent_id'] ); + } + + // Sold individually. + if ( isset( $request['sold_individually'] ) ) { + $product->set_sold_individually( $request['sold_individually'] ); + } + + // Stock status. + if ( isset( $request['in_stock'] ) ) { + $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; + } else { + $stock_status = $product->get_stock_status(); + } + + // Stock data. + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $request['manage_stock'] ) ) { + $product->set_manage_stock( $request['manage_stock'] ); + } + + // Backorders. + if ( isset( $request['backorders'] ) ) { + $product->set_backorders( $request['backorders'] ); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( $product->get_manage_stock() ) { + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $request['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $request['upsell_ids'] ) ) { + $upsells = array(); + $ids = $request['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + } + + $product->set_upsell_ids( $upsells ); + } + + // Cross sells. + if ( isset( $request['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $request['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + } + + $product->set_cross_sell_ids( $crosssells ); + } + + // Product categories. + if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); + } + + // Downloadable. + if ( isset( $request['downloadable'] ) ) { + $product->set_downloadable( $request['downloadable'] ); + } + + // Downloadable options. + if ( $product->get_downloadable() ) { + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $product->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $product->set_download_expiry( $request['download_expiry'] ); + } + } + + // Product url and button text for external products. + if ( $product->is_type( 'external' ) ) { + if ( isset( $request['external_url'] ) ) { + $product->set_product_url( $request['external_url'] ); + } + + if ( isset( $request['button_text'] ) ) { + $product->set_button_text( $request['button_text'] ); + } + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $request ); + } + + // Set children for a grouped product. + if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { + $product->set_children( $request['grouped_products'] ); + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + $product = $this->set_product_images( $product, $request['images'] ); + } + + // Allow set meta_data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $product Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); + } + + /** + * Set product images. + * + * @param WC_Product $product Product instance. + * @param array $images Images data. + * + * @throws WC_REST_Exception REST API exceptions. + * @return WC_Product + */ + protected function set_product_images( $product, $images ) { + $images = is_array( $images ) ? array_filter( $images ) : array(); + + if ( ! empty( $images ) ) { + $gallery_positions = array(); + + foreach ( $images as $index => $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { + throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: attachment id */ + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $gallery_positions[ $attachment_id ] = absint( isset( $image['position'] ) ? $image['position'] : $index ); + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + + // Set the image source if present, for future reference. + if ( ! empty( $image['src'] ) ) { + update_post_meta( $attachment_id, '_wc_attachment_source', esc_url_raw( $image['src'] ) ); + } + } + + // Sort images and get IDs in correct order. + asort( $gallery_positions ); + + // Get gallery in correct order. + $gallery = array_keys( $gallery_positions ); + + // Featured image is in position 0. + $image_id = array_shift( $gallery ); + + // Set images. + $product->set_image_id( $image_id ); + $product->set_gallery_image_ids( $gallery ); + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Save product shipping data. + * + * @param WC_Product $product Product instance. + * @param array $data Shipping data. + * + * @return WC_Product + */ + protected function save_product_shipping_data( $product, $data ) { + // Virtual. + if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { + $product->set_weight( '' ); + $product->set_height( '' ); + $product->set_length( '' ); + $product->set_width( '' ); + } else { + if ( isset( $data['weight'] ) ) { + $product->set_weight( $data['weight'] ); + } + + // Height. + if ( isset( $data['dimensions']['height'] ) ) { + $product->set_height( $data['dimensions']['height'] ); + } + + // Width. + if ( isset( $data['dimensions']['width'] ) ) { + $product->set_width( $data['dimensions']['width'] ); + } + + // Length. + if ( isset( $data['dimensions']['length'] ) ) { + $product->set_length( $data['dimensions']['length'] ); + } + } + + // Shipping class. + if ( isset( $data['shipping_class'] ) ) { + $data_store = $product->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + + return $product; + } + + /** + * Save downloadable files. + * + * @param WC_Product $product Product instance. + * @param array $downloads Downloads data. + * @param int $deprecated Deprecated since 3.0. + * + * @return WC_Product + */ + protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { + if ( $deprecated ) { + wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); + } + + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); + $files[] = $download; + } + $product->set_downloads( $files ); + + return $product; + } + + /** + * Save taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param array $terms Terms data. + * @param string $taxonomy Taxonomy name. + * + * @return WC_Product + */ + protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { + $term_ids = wp_list_pluck( $terms, 'id' ); + + if ( 'cat' === $taxonomy ) { + $product->set_category_ids( $term_ids ); + } elseif ( 'tag' === $taxonomy ) { + $product->set_tag_ids( $term_ids ); + } + + return $product; + } + + /** + * Save default attributes. + * + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * + * @since 3.0.0 + * @return WC_Product + */ + protected function save_default_attributes( $product, $request ) { + if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { + + $attributes = $product->get_attributes(); + $default_attributes = array(); + + foreach ( $request['default_attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( isset( $attributes[ $attribute_name ] ) ) { + $_attribute = $attributes[ $attribute_name ]; + + if ( $_attribute['is_variation'] ) { + $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( ! empty( $_attribute['is_taxonomy'] ) ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $value = $term->slug; + } else { + $value = sanitize_title( $value ); + } + } + + if ( $value ) { + $default_attributes[ $attribute_name ] = $value; + } + } + } + } + + $product->set_default_attributes( $default_attributes ); + } + + return $product; + } + + /** + * Clear caches here so in sync with any new variations/children. + * + * @param WC_Data $object Object data. + */ + public function clear_transients( $object ) { + wc_delete_product_transients( $object->get_id() ); + wp_cache_delete( 'product-' . $object->get_id(), 'products' ); + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( + "woocommerce_rest_{$this->post_type}_invalid_id", + __( 'Invalid ID.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + + if ( 'variation' === $object->get_type() ) { + return new WP_Error( + "woocommerce_rest_invalid_{$this->post_type}_id", + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( + "woocommerce_rest_user_cannot_delete_{$this->post_type}", + /* translators: %s: post type */ + sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), + array( + 'status' => rest_authorization_required_code(), + ) + ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + if ( $object->is_type( 'variable' ) ) { + foreach ( $object->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->delete( true ); + } + } + } else { + // For other product types, if the product has children, remove the relationship. + foreach ( $object->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->set_parent_id( 0 ); + $child->save(); + } + } + } + + $object->delete( true ); + $result = 0 === $object->get_id(); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + return new WP_Error( + 'woocommerce_rest_trash_not_supported', + /* translators: %s: post type */ + sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 501, + ) + ); + } + + // Otherwise, only trash if we haven't already. + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + return new WP_Error( + 'woocommerce_rest_already_trashed', + /* translators: %s: post type */ + sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 410, + ) + ); + } + + $object->delete(); + $result = 'trash' === $object->get_status(); + } + } + + if ( ! $result ) { + return new WP_Error( + 'woocommerce_rest_cannot_delete', + /* translators: %s: post type */ + sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 500, + ) + ); + } + + // Delete parent product transients. + if ( 0 !== $object->get_parent_id() ) { + wc_delete_product_transients( $object->get_parent_id() ); + } + + /** + * Fires after a single object is deleted or trashed via the REST API. + * + * @param WC_Data $object The deleted or trashed object. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); + + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + 'readonly' => true, + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['slug'] = array( + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['type'] = array( + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_types() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['sku'] = array( + 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['featured'] = array( + 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['category'] = array( + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['tag'] = array( + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['shipping_class'] = array( + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute'] = array( + 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute_term'] = array( + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + if ( wc_tax_enabled() ) { + $params['tax_class'] = array( + 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + } + + $params['in_stock'] = array( + 'description' => __( 'Limit result set to products in stock or out of stock.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['on_sale'] = array( + 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['min_price'] = array( + 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['max_price'] = array( + 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v2/class-wc-rest-report-sales-v2-controller.php b/includes/v2/class-wc-rest-report-sales-v2-controller.php new file mode 100644 index 00000000000..14b2e52077b --- /dev/null +++ b/includes/v2/class-wc-rest-report-sales-v2-controller.php @@ -0,0 +1,27 @@ +[\w-]+)'; + + /** + * Register routes. + * + * @since 3.0.0 + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Return a single setting. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $setting = $this->get_setting( $request['group_id'], $request['id'] ); + + if ( is_wp_error( $setting ) ) { + return $setting; + } + + $response = $this->prepare_item_for_response( $setting, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Return all settings in a group. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $settings = $this->get_group_settings( $request['group_id'] ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + + $data = array(); + + foreach ( $settings as $setting_obj ) { + $setting = $this->prepare_item_for_response( $setting_obj, $request ); + $setting = $this->prepare_response_for_collection( $setting ); + if ( $this->is_setting_type_valid( $setting['type'] ) ) { + $data[] = $setting; + } + } + + return rest_ensure_response( $data ); + } + + /** + * Get all settings in a group. + * + * @since 3.0.0 + * @param string $group_id Group ID. + * @return array|WP_Error + */ + public function get_group_settings( $group_id ) { + if ( empty( $group_id ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); + + if ( empty( $settings ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_settings = array(); + foreach ( $settings as $setting ) { + $option_key = $setting['option_key']; + $setting = $this->filter_setting( $setting ); + $default = isset( $setting['default'] ) ? $setting['default'] : ''; + // Get the option value. + if ( is_array( $option_key ) ) { + $option = get_option( $option_key[0] ); + $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; + } else { + $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); + $setting['value'] = $admin_setting_value; + } + + if ( 'multi_select_countries' === $setting['type'] ) { + $setting['options'] = WC()->countries->get_countries(); + $setting['type'] = 'multiselect'; + } elseif ( 'single_select_country' === $setting['type'] ) { + $setting['type'] = 'select'; + $setting['options'] = $this->get_countries_and_states(); + } + + $filtered_settings[] = $setting; + } + + return $filtered_settings; + } + + /** + * Returns a list of countries and states for use in the base location setting. + * + * @since 3.0.7 + * @return array Array of states and countries. + */ + private function get_countries_and_states() { + $countries = WC()->countries->get_countries(); + if ( ! $countries ) { + return array(); + } + + $output = array(); + + foreach ( $countries as $key => $value ) { + $states = WC()->countries->get_states( $key ); + if ( $states ) { + foreach ( $states as $state_key => $state_value ) { + $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; + } + } else { + $output[ $key ] = $value; + } + } + + return $output; + } + + /** + * Get setting data. + * + * @since 3.0.0 + * @param string $group_id Group ID. + * @param string $setting_id Setting ID. + * @return stdClass|WP_Error + */ + public function get_setting( $group_id, $setting_id ) { + if ( empty( $setting_id ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $settings = $this->get_group_settings( $group_id ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); + + if ( empty( $array_key ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $setting = $settings[ $array_key[0] ]; + + if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return $setting; + } + + /** + * Bulk create, update and delete items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + // Get the request params. + $items = array_filter( $request->get_params() ); + + /* + * Since our batch settings update is group-specific and matches based on the route, + * we inject the URL parameters (containing group) into the batch items + */ + if ( ! empty( $items['update'] ) ) { + $to_update = array(); + foreach ( $items['update'] as $item ) { + $to_update[] = array_merge( $request->get_url_params(), $item ); + } + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( array( 'update' => $to_update ) ); + } + + return parent::batch_items( $request ); + } + + /** + * Update a single setting in a group. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $setting = $this->get_setting( $request['group_id'], $request['id'] ); + + if ( is_wp_error( $setting ) ) { + return $setting; + } + + if ( is_callable( array( $this, 'validate_setting_' . $setting['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $setting['type'] . '_field'}( $request['value'], $setting ); + } else { + $value = $this->validate_setting_text_field( $request['value'], $setting ); + } + + if ( is_wp_error( $value ) ) { + return $value; + } + + if ( is_array( $setting['option_key'] ) ) { + $setting['value'] = $value; + $option_key = $setting['option_key']; + $prev = get_option( $option_key[0] ); + $prev[ $option_key[1] ] = $request['value']; + update_option( $option_key[0], $prev ); + } else { + $update_data = array(); + $update_data[ $setting['option_key'] ] = $value; + $setting['value'] = $value; + WC_Admin_Settings::save_fields( array( $setting ), $update_data ); + } + + $response = $this->prepare_item_for_response( $setting, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Prepare a single setting object for response. + * + * @since 3.0.0 + * @param object $item Setting object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + unset( $item['option_key'] ); + $data = $this->filter_setting( $item ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, empty( $request['context'] ) ? 'view' : $request['context'] ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $data['id'], $request['group_id'] ) ); + return $response; + } + + /** + * Prepare links for the request. + * + * @since 3.0.0 + * @param string $setting_id Setting ID. + * @param string $group_id Group ID. + * @return array Links for the given setting. + */ + protected function prepare_links( $setting_id, $group_id ) { + $base = str_replace( '(?P[\w-]+)', $group_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $base, $setting_id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + ); + + return $links; + } + + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Makes sure the current user has access to WRITE the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + 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; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * + * @since 3.0.0 + * @param array $setting Settings. + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + if ( 'image_width' === $setting['type'] ) { + $setting = $this->cast_image_width( $setting ); + } + + return $setting; + } + + /** + * For image_width, Crop can return "0" instead of false -- so we want + * to make sure we return these consistently the same we accept them. + * + * @todo remove in 4.0 + * @since 3.0.0 + * @param array $setting Settings. + * @return array + */ + public function cast_image_width( $setting ) { + foreach ( array( 'default', 'value' ) as $key ) { + if ( isset( $setting[ $key ] ) ) { + $setting[ $key ]['width'] = intval( $setting[ $key ]['width'] ); + $setting[ $key ]['height'] = intval( $setting[ $key ]['height'] ); + $setting[ $key ]['crop'] = (bool) $setting[ $key ]['crop']; + } + } + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * + * @since 3.0.0 + * @param string $key Key to check. + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( + $key, array( + 'id', + 'label', + 'description', + 'default', + 'tip', + 'placeholder', + 'type', + 'options', + 'value', + 'option_key', + ) + ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * + * @since 3.0.0 + * @param string $type Type. + * @return bool + */ + public function is_setting_type_valid( $type ) { + return in_array( + $type, array( + 'text', // Validates with validate_setting_text_field. + 'email', // Validates with validate_setting_text_field. + 'number', // Validates with validate_setting_text_field. + 'color', // Validates with validate_setting_text_field. + 'password', // Validates with validate_setting_text_field. + 'textarea', // Validates with validate_setting_textarea_field. + 'select', // Validates with validate_setting_select_field. + 'multiselect', // Validates with validate_setting_multiselect_field. + 'radio', // Validates with validate_setting_radio_field (-> validate_setting_select_field). + 'checkbox', // Validates with validate_setting_checkbox_field. + 'image_width', // Validates with validate_setting_image_width_field. + 'thumbnail_cropping', // Validates with validate_setting_text_field. + ) + ); + } + + /** + * Get the settings schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox', 'thumbnail_cropping' ), + 'readonly' => true, + ), + 'options' => array( + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-settings-v2-controller.php b/includes/v2/class-wc-rest-settings-v2-controller.php new file mode 100644 index 00000000000..f8f33f2e4bc --- /dev/null +++ b/includes/v2/class-wc-rest-settings-v2-controller.php @@ -0,0 +1,232 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get all settings groups items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $defaults = $this->group_defaults(); + $filtered_groups = array(); + foreach ( $groups as $group ) { + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $group['sub_groups'] = $sub_groups; + + $group = wp_parse_args( $group, $defaults ); + if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { + $group_obj = $this->filter_group( $group ); + $group_data = $this->prepare_item_for_response( $group_obj, $request ); + $group_data = $this->prepare_response_for_collection( $group_data ); + + $filtered_groups[] = $group_data; + } + } + + $response = rest_ensure_response( $filtered_groups ); + return $response; + } + + /** + * Prepare links for the request. + * + * @param string $group_id Group ID. + * @return array Links for the given group. + */ + protected function prepare_links( $group_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'options' => array( + 'href' => rest_url( trailingslashit( $base ) . $group_id ), + ), + ); + + return $links; + } + + /** + * Prepare a report sales object for serialization. + * + * @since 3.0.0 + * @param array $item Group object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item['id'] ) ); + + return $response; + } + + /** + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * + * @since 3.0.0 + * @param array $group Group. + * @return array + */ + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) + ); + } + + /** + * Callback for allowed keys for each group response. + * + * @since 3.0.0 + * @param string $key Key to check. + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * + * @since 3.0.0 + * @return array + */ + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + 'sub_groups' => array(), + ); + } + + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get the groups schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting_group', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-shipping-methods-v2-controller.php b/includes/v2/class-wc-rest-shipping-methods-v2-controller.php new file mode 100644 index 00000000000..78df57ece6e --- /dev/null +++ b/includes/v2/class-wc-rest-shipping-methods-v2-controller.php @@ -0,0 +1,231 @@ + + */ + public function register_routes() { + register_rest_route( + $this->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[\w-]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view shipping methods. + * + * @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( 'shipping_methods', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to read a shipping method. + * + * @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( 'shipping_methods', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get shipping methods. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $wc_shipping = WC_Shipping::instance(); + $response = array(); + foreach ( $wc_shipping->get_shipping_methods() as $id => $shipping_method ) { + $method = $this->prepare_item_for_response( $shipping_method, $request ); + $method = $this->prepare_response_for_collection( $method ); + $response[] = $method; + } + return rest_ensure_response( $response ); + } + + /** + * Get a single Shipping Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $wc_shipping = WC_Shipping::instance(); + $methods = $wc_shipping->get_shipping_methods(); + if ( empty( $methods[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $methods[ $request['id'] ]; + $response = $this->prepare_item_for_response( $method, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Prepare a shipping method for response. + * + * @param WC_Shipping_Method $method Shipping method object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $method, $request ) { + $data = array( + 'id' => $method->id, + 'title' => $method->method_title, + 'description' => $method->method_description, + ); + + $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( $method, $request ) ); + + /** + * Filter shipping methods object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Shipping_Method $method Shipping method object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_shipping_method', $response, $method, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Shipping_Method $method Shipping method object. + * @param WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $method, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $method->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the shipping method schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_method', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/includes/v2/class-wc-rest-shipping-zone-locations-v2-controller.php b/includes/v2/class-wc-rest-shipping-zone-locations-v2-controller.php new file mode 100644 index 00000000000..77d85143209 --- /dev/null +++ b/includes/v2/class-wc-rest-shipping-zone-locations-v2-controller.php @@ -0,0 +1,190 @@ +/locations endpoint. + * + * @package WooCommerce/API + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Locations class. + * + * @package WooCommerce/API + * @extends WC_REST_Shipping_Zones_Controller_Base + */ +class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { + + /** + * Register the routes for Shipping Zone Locations. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/locations', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get all Shipping Zone Locations. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $zone = $this->get_zone( (int) $request['id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $locations = $zone->get_zone_locations(); + $data = array(); + + foreach ( $locations as $location_obj ) { + $location = $this->prepare_item_for_response( $location_obj, $request ); + $location = $this->prepare_response_for_collection( $location ); + $data[] = $location; + } + + return rest_ensure_response( $data ); + } + + /** + * Update all Shipping Zone Locations. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_items( $request ) { + $zone = $this->get_zone( (int) $request['id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + if ( 0 === $zone->get_id() ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + } + + $raw_locations = $request->get_json_params(); + $locations = array(); + + foreach ( (array) $raw_locations as $raw_location ) { + if ( empty( $raw_location['code'] ) ) { + continue; + } + + $type = ! empty( $raw_location['type'] ) ? sanitize_text_field( $raw_location['type'] ) : 'country'; + + if ( ! in_array( $type, array( 'postcode', 'state', 'country', 'continent' ), true ) ) { + continue; + } + + $locations[] = array( + 'code' => sanitize_text_field( $raw_location['code'] ), + 'type' => sanitize_text_field( $type ), + ); + } + + $zone->set_locations( $locations ); + $zone->save(); + + return $this->get_items( $request ); + } + + /** + * Prepare the Shipping Zone Location for the REST response. + * + * @param array $item Shipping Zone Location. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $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( (int) $request['id'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @return array Links for the given Shipping Zone Location. + */ + protected function prepare_links( $zone_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + $links = array( + 'collection' => array( + 'href' => rest_url( $base . '/locations' ), + ), + 'describes' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zone Locations schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_location', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'description' => __( 'Shipping zone location code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'type' => array( + 'description' => __( 'Shipping zone location type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'country', + 'enum' => array( + 'postcode', + 'state', + 'country', + 'continent', + ), + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-shipping-zone-methods-v2-controller.php b/includes/v2/class-wc-rest-shipping-zone-methods-v2-controller.php new file mode 100644 index 00000000000..69fdc4b87db --- /dev/null +++ b/includes/v2/class-wc-rest-shipping-zone-methods-v2-controller.php @@ -0,0 +1,541 @@ +/methods endpoint. + * + * @package WooCommerce/API + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Methods class. + * + * @package WooCommerce/API + * @extends WC_REST_Shipping_Zones_Controller_Base + */ +class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { + + /** + * Register the routes for Shipping Zone Methods. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods', array( + 'args' => array( + 'zone_id' => array( + 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'method_id' => array( + 'required' => true, + 'readonly' => false, + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', array( + 'args' => array( + 'zone_id' => array( + 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'type' => 'integer', + ), + 'instance_id' => array( + 'description' => __( 'Unique ID for the instance.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_items_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a single Shipping Zone Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $method, $request ); + + return rest_ensure_response( $data ); + } + + /** + * Get all Shipping Zone Methods. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $methods = $zone->get_shipping_methods(); + $data = array(); + + foreach ( $methods as $method_obj ) { + $method = $this->prepare_item_for_response( $method_obj, $request ); + $data[] = $method; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a new shipping zone method instance. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $method_id = $request['method_id']; + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = $zone->add_shipping_method( $method_id ); + $methods = $zone->get_shipping_methods(); + $method = false; + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $data = $this->prepare_item_for_response( $method, $request ); + return rest_ensure_response( $data ); + } + + /** + * Delete a shipping method instance. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $force = $request['force']; + + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $request->set_param( 'context', 'view' ); + $response = $this->prepare_item_for_response( $method, $request ); + + // Actually delete. + if ( $force ) { + $zone->delete_shipping_method( $instance_id ); + } else { + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + /** + * Fires after a product review is deleted via the REST API. + * + * @param object $method + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'rest_delete_product_review', $method, $response, $request ); + + return $response; + } + + /** + * Update A Single Shipping Zone Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $data = $this->prepare_item_for_response( $method, $request ); + return rest_ensure_response( $data ); + } + + /** + * Updates settings, order, and enabled status on create. + * + * @param int $instance_id Instance ID. + * @param WC_Shipping_Method $method Shipping method data. + * @param WP_REST_Request $request Request data. + * + * @return WC_Shipping_Method + */ + public function update_fields( $instance_id, $method, $request ) { + global $wpdb; + + // Update settings if present. + if ( isset( $request['settings'] ) ) { + $method->init_instance_settings(); + $instance_settings = $method->instance_settings; + $errors_found = false; + foreach ( $method->get_instance_form_fields() as $key => $field ) { + if ( isset( $request['settings'][ $key ] ) ) { + if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); + } else { + $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); + } + if ( is_wp_error( $value ) ) { + $errors_found = true; + break; + } + $instance_settings[ $key ] = $value; + } + } + + if ( $errors_found ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); + } + + // Update order. + if ( isset( $request['order'] ) ) { + $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'method_order' => absint( $request['order'] ) ), array( 'instance_id' => absint( $instance_id ) ) ); + $method->method_order = absint( $request['order'] ); + } + + // Update if this method is enabled or not. + if ( isset( $request['enabled'] ) ) { + if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'is_enabled' => $request['enabled'] ), array( 'instance_id' => absint( $instance_id ) ) ) ) { + do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method->id, $request['zone_id'], $request['enabled'] ); + $method->enabled = ( true === $request['enabled'] ? 'yes' : 'no' ); + } + } + + return $method; + } + + /** + * Prepare the Shipping Zone Method for the REST response. + * + * @param array $item Shipping Zone Method. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $method = array( + 'id' => $item->instance_id, + 'instance_id' => $item->instance_id, + 'title' => $item->instance_settings['title'], + 'order' => $item->method_order, + 'enabled' => ( 'yes' === $item->enabled ), + 'method_id' => $item->id, + 'method_title' => $item->method_title, + 'method_description' => $item->method_description, + 'settings' => $this->get_settings( $item ), + ); + + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $method, $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( $request['zone_id'], $item->instance_id ) ); + + $response = $this->prepare_response_for_collection( $response ); + + return $response; + } + + /** + * Return settings associated with this shipping zone method instance. + * + * @param WC_Shipping_Method $item Shipping method data. + * + * @return array + */ + public function get_settings( $item ) { + $item->init_instance_settings(); + $settings = array(); + foreach ( $item->get_instance_form_fields() as $id => $field ) { + $data = array( + 'id' => $id, + 'label' => $field['title'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => $item->instance_settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @param int $instance_id Given Shipping Zone Method Instance ID. + * @return array Links for the given Shipping Zone Method. + */ + protected function prepare_links( $zone_id, $instance_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + $links = array( + 'self' => array( + 'href' => rest_url( $base . '/methods/' . $instance_id ), + ), + 'collection' => array( + 'href' => rest_url( $base . '/methods' ), + ), + 'describes' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zone Methods schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_method', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'instance_id' => array( + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Shipping method customer facing title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order' => array( + 'description' => __( 'Shipping method sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'enabled' => array( + 'description' => __( 'Shipping method enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_title' => array( + 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'settings' => array( + 'description' => __( 'Shipping method settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-shipping-zones-v2-controller.php b/includes/v2/class-wc-rest-shipping-zones-v2-controller.php new file mode 100644 index 00000000000..6071f6edb26 --- /dev/null +++ b/includes/v2/class-wc-rest-shipping-zones-v2-controller.php @@ -0,0 +1,304 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Shipping zone name.', 'woocommerce' ), + ), + ) + ), + ), + '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_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_items_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a single Shipping Zone. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $data = $zone->get_data(); + $data = $this->prepare_item_for_response( $data, $request ); + $data = $this->prepare_response_for_collection( $data ); + + return rest_ensure_response( $data ); + } + + /** + * Get all Shipping Zones. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response + */ + public function get_items( $request ) { + $rest_of_the_world = WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); + + $zones = WC_Shipping_Zones::get_zones(); + array_unshift( $zones, $rest_of_the_world->get_data() ); + $data = array(); + + foreach ( $zones as $zone_obj ) { + $zone = $this->prepare_item_for_response( $zone_obj, $request ); + $zone = $this->prepare_response_for_collection( $zone ); + $data[] = $zone; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $zone = new WC_Shipping_Zone( null ); + + if ( ! is_null( $request->get_param( 'name' ) ) ) { + $zone->set_zone_name( $request->get_param( 'name' ) ); + } + + if ( ! is_null( $request->get_param( 'order' ) ) ) { + $zone->set_zone_order( $request->get_param( 'order' ) ); + } + + $zone->save(); + + if ( $zone->get_id() !== 0 ) { + $request->set_param( 'id', $zone->get_id() ); + $response = $this->get_item( $request ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); + return $response; + } else { + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); + } + } + + /** + * Update a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + if ( 0 === $zone->get_id() ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + } + + $zone_changed = false; + + if ( ! is_null( $request->get_param( 'name' ) ) ) { + $zone->set_zone_name( $request->get_param( 'name' ) ); + $zone_changed = true; + } + + if ( ! is_null( $request->get_param( 'order' ) ) ) { + $zone->set_zone_order( $request->get_param( 'order' ) ); + $zone_changed = true; + } + + if ( $zone_changed ) { + $zone->save(); + } + + return $this->get_item( $request ); + } + + /** + * Delete a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function delete_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $force = $request['force']; + + $response = $this->get_item( $request ); + + if ( $force ) { + $zone->delete(); + } else { + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + return $response; + } + + /** + * Prepare the Shipping Zone for the REST response. + * + * @param array $item Shipping Zone. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $data = array( + 'id' => (int) $item['id'], + 'name' => $item['zone_name'], + 'order' => (int) $item['zone_order'], + ); + + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $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( $data['id'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @return array Links for the given Shipping Zone. + */ + protected function prepare_links( $zone_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $zone_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + 'describedby' => array( + 'href' => rest_url( trailingslashit( $base ) . $zone_id . '/locations' ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zones schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Shipping zone name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'order' => array( + 'description' => __( 'Shipping zone order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-system-status-tools-v2-controller.php b/includes/v2/class-wc-rest-system-status-tools-v2-controller.php new file mode 100644 index 00000000000..f73d9702063 --- /dev/null +++ b/includes/v2/class-wc-rest-system-status-tools-v2-controller.php @@ -0,0 +1,563 @@ +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[\w-]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + 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_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view system status tools. + * + * @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; + } + + /** + * Check whether a given request has permission to view a specific system status tool. + * + * @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 view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check whether a given request has permission to execute a specific system status tool. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * A list of available tools for use in the system status section. + * 'button' becomes 'action' in the API. + * + * @return array + */ + public function get_tools() { + $tools = array( + 'clear_transients' => array( + 'name' => __( 'WooCommerce transients', 'woocommerce' ), + 'button' => __( 'Clear transients', 'woocommerce' ), + 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ), + ), + 'clear_expired_transients' => array( + 'name' => __( 'Expired transients', 'woocommerce' ), + 'button' => __( 'Clear transients', 'woocommerce' ), + 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce' ), + ), + 'delete_orphaned_variations' => array( + 'name' => __( 'Orphaned variations', 'woocommerce' ), + 'button' => __( 'Delete orphaned variations', 'woocommerce' ), + 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce' ), + ), + 'clear_expired_download_permissions' => array( + 'name' => __( 'Used-up download permissions', 'woocommerce' ), + 'button' => __( 'Clean up download permissions', 'woocommerce' ), + 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ), + ), + 'regenerate_product_lookup_tables' => array( + 'name' => __( 'Product lookup tables', 'woocommerce' ), + 'button' => __( 'Regenerate', 'woocommerce' ), + 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce' ), + ), + 'recount_terms' => array( + 'name' => __( 'Term counts', 'woocommerce' ), + 'button' => __( 'Recount terms', 'woocommerce' ), + 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ), + ), + 'reset_roles' => array( + 'name' => __( 'Capabilities', 'woocommerce' ), + 'button' => __( 'Reset capabilities', 'woocommerce' ), + 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ), + ), + 'clear_sessions' => array( + 'name' => __( 'Clear customer sessions', 'woocommerce' ), + 'button' => __( 'Clear', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce' ) + ), + ), + 'install_pages' => array( + 'name' => __( 'Create default WooCommerce pages', 'woocommerce' ), + 'button' => __( 'Create pages', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce' ) + ), + ), + 'delete_taxes' => array( + 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce' ), + 'button' => __( 'Delete tax rates', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce' ) + ), + ), + 'regenerate_thumbnails' => array( + 'name' => __( 'Regenerate shop thumbnails', 'woocommerce' ), + 'button' => __( 'Regenerate', 'woocommerce' ), + 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce' ), + ), + 'db_update_routine' => array( + 'name' => __( 'Update database', 'woocommerce' ), + 'button' => __( 'Update database', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce' ) + ), + ), + ); + + // Jetpack does the image resizing heavy lifting so you don't have to. + if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) { + unset( $tools['regenerate_thumbnails'] ); + } + + return apply_filters( 'woocommerce_debug_tools', $tools ); + } + + /** + * Get a list of system status tools. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $tools = array(); + foreach ( $this->get_tools() as $id => $tool ) { + $tools[] = $this->prepare_response_for_collection( + $this->prepare_item_for_response( + array( + 'id' => $id, + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ), + $request + ) + ); + } + + $response = rest_ensure_response( $tools ); + return $response; + } + + /** + * Return a single tool. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $tools = $this->get_tools(); + if ( empty( $tools[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + $tool = $tools[ $request['id'] ]; + return rest_ensure_response( + $this->prepare_item_for_response( + array( + 'id' => $request['id'], + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ), + $request + ) + ); + } + + /** + * Update (execute) a tool. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $tools = $this->get_tools(); + if ( empty( $tools[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tool = $tools[ $request['id'] ]; + $tool = array( + 'id' => $request['id'], + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ); + + $execute_return = $this->execute_tool( $request['id'] ); + $tool = array_merge( $tool, $execute_return ); + + /** + * Fires after a WooCommerce REST system status tool has been executed. + * + * @param array $tool Details about the tool that has been executed. + * @param WP_REST_Request $request The current WP_REST_Request object. + */ + do_action( 'woocommerce_rest_insert_system_status_tool', $tool, $request ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tool, $request ); + return rest_ensure_response( $response ); + } + + /** + * Prepare a tool item for serialization. + * + * @param array $item Object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item['id'] ) ); + + return $response; + } + + /** + * Get the system status tools schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'system_status_tool', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the tool.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'name' => array( + 'description' => __( 'Tool name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'action' => array( + 'description' => __( 'What running the tool will do.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'Tool description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'success' => array( + 'description' => __( 'Did the tool run successfully?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'edit' ), + ), + 'message' => array( + 'description' => __( 'Tool return message.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Prepare links for the request. + * + * @param string $id ID. + * @return array + */ + protected function prepare_links( $id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'item' => array( + 'href' => rest_url( trailingslashit( $base ) . $id ), + 'embeddable' => true, + ), + ); + + return $links; + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + + /** + * Actually executes a tool. + * + * @param string $tool Tool. + * @return array + */ + public function execute_tool( $tool ) { + global $wpdb; + $ran = true; + switch ( $tool ) { + case 'clear_transients': + wc_delete_product_transients(); + wc_delete_shop_order_transients(); + delete_transient( 'wc_count_comments' ); + + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( $attribute_taxonomies ) { + foreach ( $attribute_taxonomies as $attribute ) { + delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name ); + } + } + + WC_Cache_Helper::get_transient_version( 'shipping', true ); + $message = __( 'Product transients cleared', 'woocommerce' ); + break; + + case 'clear_expired_transients': + /* translators: %d: amount of expired transients */ + $message = sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() ); + break; + + case 'delete_orphaned_variations': + // Delete orphans. + $result = absint( + $wpdb->query( + "DELETE products + FROM {$wpdb->posts} products + LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent + WHERE wp.ID IS NULL AND products.post_type = 'product_variation';" + ) + ); + /* translators: %d: amount of orphaned variations */ + $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result ); + break; + + case 'clear_expired_download_permissions': + // Delete expired download permissions and ones with 0 downloads remaining. + $result = absint( + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )", + date( 'Y-m-d', current_time( 'timestamp' ) ) + ) + ) + ); + /* translators: %d: amount of permissions */ + $message = sprintf( __( '%d permissions deleted', 'woocommerce' ), $result ); + break; + + case 'regenerate_product_lookup_tables': + if ( ! wc_update_product_lookup_tables_is_running() ) { + wc_update_product_lookup_tables(); + } + $message = __( 'Lookup tables are regenerating', 'woocommerce' ); + break; + case 'reset_roles': + // Remove then re-add caps and roles. + WC_Install::remove_roles(); + WC_Install::create_roles(); + $message = __( 'Roles successfully reset', 'woocommerce' ); + break; + + case 'recount_terms': + $product_cats = get_terms( + 'product_cat', + array( + 'hide_empty' => false, + 'fields' => 'id=>parent', + ) + ); + _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false ); + $product_tags = get_terms( + 'product_tag', + array( + 'hide_empty' => false, + 'fields' => 'id=>parent', + ) + ); + _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); + $message = __( 'Terms successfully recounted', 'woocommerce' ); + break; + + case 'clear_sessions': + $wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" ); + $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. + wp_cache_flush(); + /* translators: %d: amount of sessions */ + $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) ); + break; + + case 'install_pages': + WC_Install::create_pages(); + $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); + break; + + case 'delete_taxes': + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); + WC_Cache_Helper::incr_cache_prefix( 'taxes' ); + $message = __( 'Tax rates successfully deleted', 'woocommerce' ); + break; + + case 'regenerate_thumbnails': + WC_Regenerate_Images::queue_image_regeneration(); + $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); + break; + + case 'db_update_routine': + $blog_id = get_current_blog_id(); + // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). + // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. + do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); + $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' ); + break; + + default: + $tools = $this->get_tools(); + if ( isset( $tools[ $tool ]['callback'] ) ) { + $callback = $tools[ $tool ]['callback']; + $return = call_user_func( $callback ); + if ( is_string( $return ) ) { + $message = $return; + } elseif ( false === $return ) { + $callback_string = is_array( $callback ) ? get_class( $callback[0] ) . '::' . $callback[1] : $callback; + $ran = false; + /* translators: %s: callback string */ + $message = sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback_string ); + } else { + $message = __( 'Tool ran.', 'woocommerce' ); + } + } else { + $ran = false; + $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ); + } + break; + } + + return array( + 'success' => $ran, + 'message' => $message, + ); + } +} diff --git a/includes/v2/class-wc-rest-system-status-v2-controller.php b/includes/v2/class-wc-rest-system-status-v2-controller.php new file mode 100644 index 00000000000..f12588dd089 --- /dev/null +++ b/includes/v2/class-wc-rest-system-status-v2-controller.php @@ -0,0 +1,1180 @@ +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' ), + ) + ); + } + + /** + * Check whether a given request has permission to view system status. + * + * @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; + } + + /** + * Get a system status info, by section. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $schema = $this->get_item_schema(); + $mappings = $this->get_item_mappings(); + $response = array(); + + foreach ( $mappings as $section => $values ) { + foreach ( $values as $key => $value ) { + if ( isset( $schema['properties'][ $section ]['properties'][ $key ]['type'] ) ) { + settype( $values[ $key ], $schema['properties'][ $section ]['properties'][ $key ]['type'] ); + } + } + settype( $values, $schema['properties'][ $section ]['type'] ); + $response[ $section ] = $values; + } + + $response = $this->prepare_item_for_response( $response, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Get the system status schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'system_status', + 'type' => 'object', + 'properties' => array( + 'environment' => array( + 'description' => __( 'Environment.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'home_url' => array( + 'description' => __( 'Home URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'site_url' => array( + 'description' => __( 'Site URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wc_version' => array( + 'description' => __( 'WooCommerce version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'log_directory' => array( + 'description' => __( 'Log directory.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'log_directory_writable' => array( + 'description' => __( 'Is log directory writable?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_version' => array( + 'description' => __( 'WordPress version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_multisite' => array( + 'description' => __( 'Is WordPress multisite?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_memory_limit' => array( + 'description' => __( 'WordPress memory limit.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_debug_mode' => array( + 'description' => __( 'Is WordPress debug mode active?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_cron' => array( + 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'language' => array( + 'description' => __( 'WordPress language.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'server_info' => array( + 'description' => __( 'Server info.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_version' => array( + 'description' => __( 'PHP version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_post_max_size' => array( + 'description' => __( 'PHP post max size.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_max_execution_time' => array( + 'description' => __( 'PHP max execution time.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_max_input_vars' => array( + 'description' => __( 'PHP max input vars.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'curl_version' => array( + 'description' => __( 'cURL version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'suhosin_installed' => array( + 'description' => __( 'Is SUHOSIN installed?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'max_upload_size' => array( + 'description' => __( 'Max upload size.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mysql_version' => array( + 'description' => __( 'MySQL version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mysql_version_string' => array( + 'description' => __( 'MySQL version string.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'default_timezone' => array( + 'description' => __( 'Default timezone.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'fsockopen_or_curl_enabled' => array( + 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'soapclient_enabled' => array( + 'description' => __( 'Is SoapClient class enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'domdocument_enabled' => array( + 'description' => __( 'Is DomDocument class enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'gzip_enabled' => array( + 'description' => __( 'Is GZip enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mbstring_enabled' => array( + 'description' => __( 'Is mbstring enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_post_successful' => array( + 'description' => __( 'Remote POST successful?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_post_response' => array( + 'description' => __( 'Remote POST response.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_get_successful' => array( + 'description' => __( 'Remote GET successful?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_get_response' => array( + 'description' => __( 'Remote GET response.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'database' => array( + 'description' => __( 'Database.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'wc_database_version' => array( + 'description' => __( 'WC database version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'database_prefix' => array( + 'description' => __( 'Database prefix.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'maxmind_geoip_database' => array( + 'description' => __( 'MaxMind GeoIP database.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'database_tables' => array( + 'description' => __( 'Database tables.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ), + 'active_plugins' => array( + 'description' => __( 'Active plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'inactive_plugins' => array( + 'description' => __( 'Inactive plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'dropins_mu_plugins' => array( + 'description' => __( 'Dropins & MU plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'theme' => array( + 'description' => __( 'Theme.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'name' => array( + 'description' => __( 'Theme name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'version' => array( + 'description' => __( 'Theme version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'version_latest' => array( + 'description' => __( 'Latest version of theme.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'author_url' => array( + 'description' => __( 'Theme author URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'is_child_theme' => array( + 'description' => __( 'Is this theme a child theme?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_woocommerce_support' => array( + 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_woocommerce_file' => array( + 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_outdated_templates' => array( + 'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'overrides' => array( + 'description' => __( 'Template overrides.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'parent_name' => array( + 'description' => __( 'Parent theme name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_version' => array( + 'description' => __( 'Parent theme version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_author_url' => array( + 'description' => __( 'Parent theme author URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'settings' => array( + 'description' => __( 'Settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'api_enabled' => array( + 'description' => __( 'REST API enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'force_ssl' => array( + 'description' => __( 'SSL forced?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency' => array( + 'description' => __( 'Currency.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_symbol' => array( + 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_position' => array( + 'description' => __( 'Currency position.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'thousand_separator' => array( + 'description' => __( 'Thousand separator.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'decimal_separator' => array( + 'description' => __( 'Decimal separator.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'number_of_decimals' => array( + 'description' => __( 'Number of decimals.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'geolocation_enabled' => array( + 'description' => __( 'Geolocation enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'taxonomies' => array( + 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'product_visibility_terms' => array( + 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ), + 'security' => array( + 'description' => __( 'Security.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'secure_connection' => array( + 'description' => __( 'Is the connection to your store secure?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'hide_errors' => array( + 'description' => __( 'Hide errors from visitors?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'pages' => array( + 'description' => __( 'WooCommerce pages.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Return an array of sections and the data associated with each. + * + * @return array + */ + public function get_item_mappings() { + return array( + 'environment' => $this->get_environment_info(), + 'database' => $this->get_database_info(), + 'active_plugins' => $this->get_active_plugins(), + 'inactive_plugins' => $this->get_inactive_plugins(), + 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(), + 'theme' => $this->get_theme_info(), + 'settings' => $this->get_settings(), + 'security' => $this->get_security_info(), + 'pages' => $this->get_pages(), + ); + } + + /** + * Get array of environment information. Includes thing like software + * versions, and various server settings. + * + * @return array + */ + public function get_environment_info() { + global $wpdb; + + // Figure out cURL version, if installed. + $curl_version = ''; + if ( function_exists( 'curl_version' ) ) { + $curl_version = curl_version(); + $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; + } elseif ( extension_loaded( 'curl' ) ) { + $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); + } + + // WP memory limit. + $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); + if ( function_exists( 'memory_get_usage' ) ) { + $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); + } + + // Test POST requests. + $post_response_code = get_transient( 'woocommerce_test_remote_post' ); + + if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { + $response = wp_safe_remote_post( + 'https://www.paypal.com/cgi-bin/webscr', + array( + 'timeout' => 10, + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', + 'body' => array( + 'cmd' => '_notify-validate', + ), + ) + ); + if ( ! is_wp_error( $response ) ) { + $post_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); + } + + $post_response_successful = ! is_wp_error( $post_response_code ) && $post_response_code >= 200 && $post_response_code < 300; + + // Test GET requests. + $get_response_code = get_transient( 'woocommerce_test_remote_get' ); + + if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { + $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); + if ( ! is_wp_error( $response ) ) { + $get_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); + } + + $get_response_successful = ! is_wp_error( $get_response_code ) && $get_response_code >= 200 && $get_response_code < 300; + + $database_version = wc_get_server_database_version(); + + // Return all environment info. Described by JSON Schema. + return array( + 'home_url' => get_option( 'home' ), + 'site_url' => get_option( 'siteurl' ), + 'version' => WC()->version, + 'log_directory' => WC_LOG_DIR, + 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), + 'wp_version' => get_bloginfo( 'version' ), + 'wp_multisite' => is_multisite(), + 'wp_memory_limit' => $wp_memory_limit, + 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), + 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ), + 'language' => get_locale(), + 'external_object_cache' => wp_using_ext_object_cache(), + 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '', + 'php_version' => phpversion(), + 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), + 'php_max_execution_time' => ini_get( 'max_execution_time' ), + 'php_max_input_vars' => ini_get( 'max_input_vars' ), + 'curl_version' => $curl_version, + 'suhosin_installed' => extension_loaded( 'suhosin' ), + 'max_upload_size' => wp_max_upload_size(), + 'mysql_version' => $database_version['number'], + 'mysql_version_string' => $database_version['string'], + 'default_timezone' => date_default_timezone_get(), + 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ), + 'soapclient_enabled' => class_exists( 'SoapClient' ), + 'domdocument_enabled' => class_exists( 'DOMDocument' ), + 'gzip_enabled' => is_callable( 'gzopen' ), + 'mbstring_enabled' => extension_loaded( 'mbstring' ), + 'remote_post_successful' => $post_response_successful, + 'remote_post_response' => is_wp_error( $post_response_code ) ? $post_response_code->get_error_message() : $post_response_code, + 'remote_get_successful' => $get_response_successful, + 'remote_get_response' => is_wp_error( $get_response_code ) ? $get_response_code->get_error_message() : $get_response_code, + ); + } + + /** + * Add prefix to table. + * + * @param string $table Table name. + * @return stromg + */ + protected function add_db_table_prefix( $table ) { + global $wpdb; + return $wpdb->prefix . $table; + } + + /** + * Get array of database information. Version, prefix, and table existence. + * + * @return array + */ + public function get_database_info() { + global $wpdb; + + $database_table_information = $wpdb->get_results( + $wpdb->prepare( + "SELECT + table_name AS 'name', + engine, + round( ( data_length / 1024 / 1024 ), 2 ) 'data', + round( ( index_length / 1024 / 1024 ), 2 ) 'index' + FROM information_schema.TABLES + WHERE table_schema = %s + ORDER BY name ASC;", + DB_NAME + ) + ); + + // WC Core tables to check existence of. + $core_tables = apply_filters( + 'woocommerce_database_tables', + array( + 'woocommerce_sessions', + 'woocommerce_api_keys', + 'woocommerce_attribute_taxonomies', + 'woocommerce_downloadable_product_permissions', + 'woocommerce_order_items', + 'woocommerce_order_itemmeta', + 'woocommerce_tax_rates', + 'woocommerce_tax_rate_locations', + 'woocommerce_shipping_zones', + 'woocommerce_shipping_zone_locations', + 'woocommerce_shipping_zone_methods', + 'woocommerce_payment_tokens', + 'woocommerce_payment_tokenmeta', + 'woocommerce_log', + ) + ); + + /** + * Adding the prefix to the tables array, for backwards compatibility. + * + * If we changed the tables above to include the prefix, then any filters against that table could break. + */ + $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); + + /** + * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. + * + * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. + */ + $tables = array( + 'woocommerce' => array_fill_keys( $core_tables, false ), + 'other' => array(), + ); + + $database_size = array( + 'data' => 0, + 'index' => 0, + ); + + $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); + $global_tables = $wpdb->tables( 'global', true ); + foreach ( $database_table_information as $table ) { + // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. + if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { + continue; + } + $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce' : 'other'; + + $tables[ $table_type ][ $table->name ] = array( + 'data' => $table->data, + 'index' => $table->index, + 'engine' => $table->engine, + ); + + $database_size['data'] += $table->data; + $database_size['index'] += $table->index; + } + + // Return all database info. Described by JSON Schema. + return array( + 'wc_database_version' => get_option( 'woocommerce_db_version' ), + 'database_prefix' => $wpdb->prefix, + 'maxmind_geoip_database' => WC_Geolocation::get_local_database_path(), + 'database_tables' => $tables, + 'database_size' => $database_size, + ); + } + + /** + * Get array of counts of objects. Orders, products, etc. + * + * @return array + */ + public function get_post_type_counts() { + global $wpdb; + + $post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" ); + + return is_array( $post_type_counts ) ? $post_type_counts : array(); + } + + /** + * Get a list of plugins active on the site. + * + * @return array + */ + public function get_active_plugins() { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + if ( ! function_exists( 'get_plugin_data' ) ) { + return array(); + } + + $active_plugins = (array) get_option( 'active_plugins', array() ); + if ( is_multisite() ) { + $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); + } + + $active_plugins_data = array(); + + foreach ( $active_plugins as $plugin ) { + $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + $active_plugins_data[] = $this->format_plugin_data( $plugin, $data ); + } + + return $active_plugins_data; + } + + /** + * Get a list of inplugins active on the site. + * + * @return array + */ + public function get_inactive_plugins() { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + if ( ! function_exists( 'get_plugins' ) ) { + return array(); + } + + $plugins = get_plugins(); + $active_plugins = (array) get_option( 'active_plugins', array() ); + + if ( is_multisite() ) { + $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); + } + + $plugins_data = array(); + + foreach ( $plugins as $plugin => $data ) { + if ( in_array( $plugin, $active_plugins, true ) ) { + continue; + } + $plugins_data[] = $this->format_plugin_data( $plugin, $data ); + } + + return $plugins_data; + } + + /** + * Format plugin data, including data on updates, into a standard format. + * + * @since 3.6.0 + * @param string $plugin Plugin directory/file. + * @param array $data Plugin data from WP. + * @return array Formatted data. + */ + protected function format_plugin_data( $plugin, $data ) { + require_once ABSPATH . 'wp-admin/includes/update.php'; + + if ( ! function_exists( 'get_plugin_updates' ) ) { + return array(); + } + + // Use WP API to lookup latest updates for plugins. WC_Helper injects updates for premium plugins. + if ( empty( $this->available_updates ) ) { + $this->available_updates = get_plugin_updates(); + } + + $version_latest = $data['Version']; + + // Find latest version. + if ( isset( $this->available_updates[ $plugin ]->update->new_version ) ) { + $version_latest = $this->available_updates[ $plugin ]->update->new_version; + } + + return array( + 'plugin' => $plugin, + 'name' => $data['Name'], + 'version' => $data['Version'], + 'version_latest' => $version_latest, + 'url' => $data['PluginURI'], + 'author_name' => $data['AuthorName'], + 'author_url' => esc_url_raw( $data['AuthorURI'] ), + 'network_activated' => $data['Network'], + ); + } + + /** + * Get a list of Dropins and MU plugins. + * + * @since 3.6.0 + * @return array + */ + public function get_dropins_mu_plugins() { + $dropins = get_dropins(); + $plugins = array( + 'dropins' => array(), + 'mu_plugins' => array(), + ); + foreach ( $dropins as $key => $dropin ) { + $plugins['dropins'][] = array( + 'plugin' => $key, + 'name' => $dropin['Name'], + ); + } + + $mu_plugins = get_mu_plugins(); + foreach ( $mu_plugins as $plugin => $mu_plugin ) { + $plugins['mu_plugins'][] = array( + 'plugin' => $plugin, + 'name' => $mu_plugin['Name'], + 'version' => $mu_plugin['Version'], + 'url' => $mu_plugin['PluginURI'], + 'author_name' => $mu_plugin['AuthorName'], + 'author_url' => esc_url_raw( $mu_plugin['AuthorURI'] ), + ); + } + return $plugins; + } + + /** + * Get info on the current active theme, info on parent theme (if presnet) + * and a list of template overrides. + * + * @return array + */ + public function get_theme_info() { + $active_theme = wp_get_theme(); + + // Get parent theme info if this theme is a child theme, otherwise + // pass empty info in the response. + if ( is_child_theme() ) { + $parent_theme = wp_get_theme( $active_theme->template ); + $parent_theme_info = array( + 'parent_name' => $parent_theme->name, + 'parent_version' => $parent_theme->version, + 'parent_version_latest' => WC_Admin_Status::get_latest_theme_version( $parent_theme ), + 'parent_author_url' => $parent_theme->{'Author URI'}, + ); + } else { + $parent_theme_info = array( + 'parent_name' => '', + 'parent_version' => '', + 'parent_version_latest' => '', + 'parent_author_url' => '', + ); + } + + /** + * Scan the theme directory for all WC templates to see if our theme + * overrides any of them. + */ + $override_files = array(); + $outdated_templates = false; + $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); + foreach ( $scan_files as $file ) { + $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' ); + + if ( file_exists( $located ) ) { + $theme_file = $located; + } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . $file; + } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; + } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { + $theme_file = get_template_directory() . '/' . $file; + } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; + } else { + $theme_file = false; + } + + if ( ! empty( $theme_file ) ) { + $core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); + $theme_version = WC_Admin_Status::get_file_version( $theme_file ); + if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { + if ( ! $outdated_templates ) { + $outdated_templates = true; + } + } + $override_files[] = array( + 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), + 'version' => $theme_version, + 'core_version' => $core_version, + ); + } + } + + $active_theme_info = array( + 'name' => $active_theme->name, + 'version' => $active_theme->version, + 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ), + 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), + 'is_child_theme' => is_child_theme(), + 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), + 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), + 'has_outdated_templates' => $outdated_templates, + 'overrides' => $override_files, + ); + + return array_merge( $active_theme_info, $parent_theme_info ); + } + + /** + * Get some setting values for the site that are useful for debugging + * purposes. For full settings access, use the settings api. + * + * @return array + */ + public function get_settings() { + // Get a list of terms used for product/order taxonomies. + $term_response = array(); + $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + // Get a list of terms used for product visibility. + $product_visibility_terms = array(); + $terms = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $product_visibility_terms[ $term->slug ] = strtolower( $term->name ); + } + + // Check if WooCommerce.com account is connected. + $woo_com_connected = 'no'; + $helper_options = get_option( 'woocommerce_helper_data', array() ); + if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) { + $woo_com_connected = 'yes'; + } + + // Return array of useful settings for debugging. + return array( + 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ), + 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ), + 'currency' => get_woocommerce_currency(), + 'currency_symbol' => get_woocommerce_currency_symbol(), + 'currency_position' => get_option( 'woocommerce_currency_pos' ), + 'thousand_separator' => wc_get_price_thousand_separator(), + 'decimal_separator' => wc_get_price_decimal_separator(), + 'number_of_decimals' => wc_get_price_decimals(), + 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ), + 'taxonomies' => $term_response, + 'product_visibility_terms' => $product_visibility_terms, + 'woocommerce_com_connected' => $woo_com_connected, + ); + } + + /** + * Returns security tips. + * + * @return array + */ + public function get_security_info() { + $check_page = wc_get_page_permalink( 'shop' ); + return array( + 'secure_connection' => 'https' === substr( $check_page, 0, 5 ), + 'hide_errors' => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), + ); + } + + /** + * Returns a mini-report on WC pages and if they are configured correctly: + * Present, visible, and including the correct shortcode. + * + * @return array + */ + public function get_pages() { + // WC pages to check against. + $check_pages = array( + _x( 'Shop base', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_shop_page_id', + 'shortcode' => '', + ), + _x( 'Cart', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_cart_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', + ), + _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_checkout_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', + ), + _x( 'My account', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_myaccount_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', + ), + _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_terms_page_id', + 'shortcode' => '', + ), + ); + + $pages_output = array(); + foreach ( $check_pages as $page_name => $values ) { + $page_id = get_option( $values['option'] ); + $page_set = false; + $page_exists = false; + $page_visible = false; + $shortcode_present = false; + $shortcode_required = false; + + // Page checks. + if ( $page_id ) { + $page_set = true; + } + if ( get_post( $page_id ) ) { + $page_exists = true; + } + if ( 'publish' === get_post_status( $page_id ) ) { + $page_visible = true; + } + + // Shortcode checks. + if ( $values['shortcode'] && get_post( $page_id ) ) { + $shortcode_required = true; + $page = get_post( $page_id ); + if ( strstr( $page->post_content, $values['shortcode'] ) ) { + $shortcode_present = true; + } + } + + // Wrap up our findings into an output array. + $pages_output[] = array( + 'page_name' => $page_name, + 'page_id' => $page_id, + 'page_set' => $page_set, + 'page_exists' => $page_exists, + 'page_visible' => $page_visible, + 'shortcode' => $values['shortcode'], + 'shortcode_required' => $shortcode_required, + 'shortcode_present' => $shortcode_present, + ); + } + + return $pages_output; + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + + /** + * Prepare the system status response + * + * @param array $system_status System status data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $system_status, $request ) { + $data = $this->add_additional_fields_to_object( $system_status, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + + $response = rest_ensure_response( $data ); + + /** + * Filter the system status returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param mixed $system_status System status + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_system_status', $response, $system_status, $request ); + } +} diff --git a/includes/v2/class-wc-rest-tax-classes-v2-controller.php b/includes/v2/class-wc-rest-tax-classes-v2-controller.php new file mode 100644 index 00000000000..cab4ad800ba --- /dev/null +++ b/includes/v2/class-wc-rest-tax-classes-v2-controller.php @@ -0,0 +1,27 @@ +/deliveries endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Webhook Deliveries controller class. + * + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @package WooCommerce/API + * @extends WC_REST_Webhook_Deliveries_V1_Controller + */ +class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliveries_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Prepare a single webhook delivery output for response. + * + * @param stdClass $log Delivery log object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $log, $request ) { + $data = (array) $log; + + $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( $log ) ); + + /** + * Filter webhook delivery object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $log Delivery log object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request ); + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook_delivery', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'duration' => array( + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'summary' => array( + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_url' => array( + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_headers' => array( + 'description' => __( 'Request headers.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'request_body' => array( + 'description' => __( 'Request body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_code' => array( + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_message' => array( + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_headers' => array( + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'response_body' => array( + 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the webhook delivery was logged, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v2/class-wc-rest-webhooks-v2-controller.php b/includes/v2/class-wc-rest-webhooks-v2-controller.php new file mode 100644 index 00000000000..746d17e938e --- /dev/null +++ b/includes/v2/class-wc-rest-webhooks-v2-controller.php @@ -0,0 +1,182 @@ +post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $data = array( + 'id' => $webhook->get_id(), + 'name' => $webhook->get_name(), + 'status' => $webhook->get_status(), + 'topic' => $webhook->get_topic(), + 'resource' => $webhook->get_resource(), + 'event' => $webhook->get_event(), + 'hooks' => $webhook->get_hooks(), + 'delivery_url' => $webhook->get_delivery_url(), + 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $webhook->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), + ); + + $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( $webhook->get_id(), $request ) ); + + /** + * Filter webhook object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Webhook $webhook Webhook object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); + } + + /** + * Get the default REST API version. + * + * @since 3.0.0 + * @return string + */ + protected function get_default_api_version() { + return 'wp_api_v2'; + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Webhook status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'active', + 'enum' => array_keys( wc_get_webhook_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'topic' => array( + 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'resource' => array( + 'description' => __( 'Webhook resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'event' => array( + 'description' => __( 'Webhook event.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'hooks' => array( + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'delivery_url' => array( + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'secret' => array( + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-api-v3.php b/includes/v3/class-wc-rest-api-v3.php new file mode 100644 index 00000000000..18a7e2728d9 --- /dev/null +++ b/includes/v3/class-wc-rest-api-v3.php @@ -0,0 +1,113 @@ +/downloads endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Customers controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Customer_Downloads_V2_Controller + */ +class WC_REST_Customer_Downloads_Controller extends WC_REST_Customer_Downloads_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/includes/v3/class-wc-rest-customers-controller.php b/includes/v3/class-wc-rest-customers-controller.php new file mode 100644 index 00000000000..05c45a9196c --- /dev/null +++ b/includes/v3/class-wc-rest-customers-controller.php @@ -0,0 +1,307 @@ +get_data(); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + // Date created is stored UTC, date modified is stored WP local time. + $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => $data['email'], + 'first_name' => $data['first_name'], + 'last_name' => $data['last_name'], + 'role' => $data['role'], + 'username' => $data['username'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'is_paying_customer' => $data['is_paying_customer'], + 'avatar_url' => $object->get_avatar_url(), + 'meta_data' => $data['meta_data'], + ); + } + + /** + * Get the Customer's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'email' => array( + 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'first_name' => array( + 'description' => __( 'Customer first name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'last_name' => array( + 'description' => __( 'Customer last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'role' => array( + 'description' => __( 'Customer role.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'username' => array( + 'description' => __( 'Customer login name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_user', + ), + ), + 'password' => array( + 'description' => __( 'Customer password.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'billing' => array( + 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'is_paying_customer' => array( + 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), + 'type' => 'bool', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avatar_url' => array( + 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-data-continents-controller.php b/includes/v3/class-wc-rest-data-continents-controller.php new file mode 100644 index 00000000000..56c82fcb2f3 --- /dev/null +++ b/includes/v3/class-wc-rest-data-continents-controller.php @@ -0,0 +1,357 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => array( + 'continent' => array( + 'description' => __( '2 character continent code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Return the list of countries and states for a given continent. + * + * @since 3.5.0 + * @param string $continent_code Continent code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_continent( $continent_code = false, $request ) { + $continents = WC()->countries->get_continents(); + $countries = WC()->countries->get_countries(); + $states = WC()->countries->get_states(); + $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php'; + $data = array(); + + if ( ! array_key_exists( $continent_code, $continents ) ) { + return false; + } + + $continent_list = $continents[ $continent_code ]; + + $continent = array( + 'code' => $continent_code, + 'name' => $continent_list['name'], + ); + + $local_countries = array(); + foreach ( $continent_list['countries'] as $country_code ) { + if ( isset( $countries[ $country_code ] ) ) { + $country = array( + 'code' => $country_code, + 'name' => $countries[ $country_code ], + ); + + // If we have detailed locale information include that in the response. + if ( array_key_exists( $country_code, $locale_info ) ) { + // Defensive programming against unexpected changes in locale-info.php. + $country_data = wp_parse_args( + $locale_info[ $country_code ], array( + 'currency_code' => 'USD', + 'currency_pos' => 'left', + 'decimal_sep' => '.', + 'dimension_unit' => 'in', + 'num_decimals' => 2, + 'thousand_sep' => ',', + 'weight_unit' => 'lbs', + ) + ); + + $country = array_merge( $country, $country_data ); + } + + $local_states = array(); + if ( isset( $states[ $country_code ] ) ) { + foreach ( $states[ $country_code ] as $state_code => $state_name ) { + $local_states[] = array( + 'code' => $state_code, + 'name' => $state_name, + ); + } + } + $country['states'] = $local_states; + + // Allow only desired keys (e.g. filter out tax rates). + $allowed = array( + 'code', + 'currency_code', + 'currency_pos', + 'decimal_sep', + 'dimension_unit', + 'name', + 'num_decimals', + 'states', + 'thousand_sep', + 'weight_unit', + ); + $country = array_intersect_key( $country, array_flip( $allowed ) ); + + $local_countries[] = $country; + } + } + + $continent['countries'] = $local_countries; + return $continent; + } + + /** + * Return the list of states for all continents. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $continents = WC()->countries->get_continents(); + $data = array(); + + foreach ( array_keys( $continents ) as $continent_code ) { + $continent = $this->get_continent( $continent_code, $request ); + $response = $this->prepare_item_for_response( $continent, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return the list of locations for a given continent. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_continent( strtoupper( $request['location'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Prepare the data object for response. + * + * @since 3.5.0 + * @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 ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter the location list returned from the API. + * + * Allows modification of the loction data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param array $item The original list of continent(s), countries, and states. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_continent', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given continent. + */ + protected function prepare_links( $item ) { + $continent_code = strtolower( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $continent_code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + return $links; + } + + /** + * Get the location schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_continents', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( '2 character continent code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of continent.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'countries' => array( + 'type' => 'array', + 'description' => __( 'List of countries on this continent.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_code' => array( + 'type' => 'string', + 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_pos' => array( + 'type' => 'string', + 'description' => __( 'Currency symbol position for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'decimal_sep' => array( + 'type' => 'string', + 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'dimension_unit' => array( + 'type' => 'string', + 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'num_decimals' => array( + 'type' => 'integer', + 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'states' => array( + 'type' => 'array', + 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'State code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of state.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + 'thousand_sep' => array( + 'type' => 'string', + 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'weight_unit' => array( + 'type' => 'string', + 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-data-controller.php b/includes/v3/class-wc-rest-data-controller.php new file mode 100644 index 00000000000..216586510e6 --- /dev/null +++ b/includes/v3/class-wc-rest-data-controller.php @@ -0,0 +1,184 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to read site data. + * + * @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( 'settings', '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 site settings. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Return the list of data resources. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $data = array(); + $resources = array( + array( + 'slug' => 'continents', + 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce' ), + ), + array( + 'slug' => 'countries', + 'description' => __( 'List of supported states in a given country.', 'woocommerce' ), + ), + array( + 'slug' => 'currencies', + 'description' => __( 'List of supported currencies.', 'woocommerce' ), + ), + ); + + foreach ( $resources as $resource ) { + $item = $this->prepare_item_for_response( (object) $resource, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a data resource object for serialization. + * + * @param stdClass $resource Resource data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $resource, $request ) { + $data = array( + 'slug' => $resource->slug, + 'description' => $resource->description, + ); + + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $resource ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given country. + */ + protected function prepare_links( $item ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->slug ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the data index schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_index', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'Data resource ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Data resource description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-data-countries-controller.php b/includes/v3/class-wc-rest-data-countries-controller.php new file mode 100644 index 00000000000..3bc7cb65762 --- /dev/null +++ b/includes/v3/class-wc-rest-data-countries-controller.php @@ -0,0 +1,240 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => array( + 'location' => array( + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a list of countries and states. + * + * @param string $country_code Country code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_country( $country_code = false, $request ) { + $countries = WC()->countries->get_countries(); + $states = WC()->countries->get_states(); + $data = array(); + + if ( ! array_key_exists( $country_code, $countries ) ) { + return false; + } + + $country = array( + 'code' => $country_code, + 'name' => $countries[ $country_code ], + ); + + $local_states = array(); + if ( isset( $states[ $country_code ] ) ) { + foreach ( $states[ $country_code ] as $state_code => $state_name ) { + $local_states[] = array( + 'code' => $state_code, + 'name' => $state_name, + ); + } + } + $country['states'] = $local_states; + return $country; + } + + /** + * Return the list of states for all countries. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $countries = WC()->countries->get_countries(); + $data = array(); + + foreach ( array_keys( $countries ) as $country_code ) { + $country = $this->get_country( $country_code, $request ); + $response = $this->prepare_item_for_response( $country, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return the list of states for a given country. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_country( strtoupper( $request['location'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Prepare the data object for response. + * + * @since 3.5.0 + * @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 ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter the states list for a country returned from the API. + * + * Allows modification of the loction data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param array $data The original country's states list. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_country', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given country. + */ + protected function prepare_links( $item ) { + $country_code = strtolower( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $country_code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + + /** + * Get the location schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_countries', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'states' => array( + 'type' => 'array', + 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'State code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of state.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-data-currencies-controller.php b/includes/v3/class-wc-rest-data-currencies-controller.php new file mode 100644 index 00000000000..1b589c297fa --- /dev/null +++ b/includes/v3/class-wc-rest-data-currencies-controller.php @@ -0,0 +1,221 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/current', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_current_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]{3})', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'location' => array( + 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get currency information. + * + * @param string $code Currency code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_currency( $code = false, $request ) { + $currencies = get_woocommerce_currencies(); + $data = array(); + + if ( ! array_key_exists( $code, $currencies ) ) { + return false; + } + + $currency = array( + 'code' => $code, + 'name' => $currencies[ $code ], + 'symbol' => get_woocommerce_currency_symbol( $code ), + ); + + return $currency; + } + + /** + * Return the list of currencies. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $currencies = get_woocommerce_currencies(); + foreach ( array_keys( $currencies ) as $code ) { + $currency = $this->get_currency( $code, $request ); + $response = $this->prepare_item_for_response( $currency, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return information for a specific currency. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Return information for the current site currency. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_current_item( $request ) { + $currency = get_option( 'woocommerce_currency' ); + return $this->prepare_item_for_response( $this->get_currency( $currency, $request ), $request ); + } + + /** + * 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 ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter currency returned from the API. + * + * @param WP_REST_Response $response The response object. + * @param array $item Currency data. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_currency', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given currency. + */ + protected function prepare_links( $item ) { + $code = strtoupper( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + + /** + * Get the currency schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_currencies', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of currency.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'symbol' => array( + 'type' => 'string', + 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-network-orders-controller.php b/includes/v3/class-wc-rest-network-orders-controller.php new file mode 100644 index 00000000000..070f95b0555 --- /dev/null +++ b/includes/v3/class-wc-rest-network-orders-controller.php @@ -0,0 +1,27 @@ +/notes endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Order Notes controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Order_Notes_V2_Controller + */ +class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; + + /** + * Prepare a single order note output for response. + * + * @param WP_Comment $note Order note object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $note, $request ) { + $data = array( + 'id' => (int) $note->comment_ID, + 'author' => __( 'WooCommerce', 'woocommerce' ) === $note->comment_author ? 'system' : $note->comment_author, + 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + $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( $note ) ); + + /** + * Filter order note object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $note Order note object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); + } + + /** + * Create a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Create the note. + $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); + + if ( ! $note_id ) { + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $note = get_comment( $note_id ); + $this->update_additional_fields_for_object( $note, $request ); + + /** + * Fires after a order note is created or updated via the REST API. + * + * @param WP_Comment $note New order note object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $note, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); + + return $response; + } + + /** + * Get the Order Notes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'order_note', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'author' => array( + 'description' => __( 'Order note author.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'note' => array( + 'description' => __( 'Order note content.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_note' => array( + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'added_by_user' => array( + 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-order-refunds-controller.php b/includes/v3/class-wc-rest-order-refunds-controller.php new file mode 100644 index 00000000000..0834a2b9f04 --- /dev/null +++ b/includes/v3/class-wc-rest-order-refunds-controller.php @@ -0,0 +1,86 @@ +/refunds endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Order Refunds controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Order_Refunds_V2_Controller + */ +class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; + + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( 0 > $request['amount'] ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + } + + // Create the refund. + $refund = wc_create_refund( + array( + 'order_id' => $order->get_id(), + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'line_items' => empty( $request['line_items'] ) ? array() : $request['line_items'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) + ); + + if ( is_wp_error( $refund ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + } + + if ( ! $refund ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + $refund->save_meta_data(); + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $coupon Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); + } +} diff --git a/includes/v3/class-wc-rest-orders-controller.php b/includes/v3/class-wc-rest-orders-controller.php new file mode 100644 index 00000000000..d2bb6f06663 --- /dev/null +++ b/includes/v3/class-wc-rest-orders-controller.php @@ -0,0 +1,271 @@ +get_items( 'coupon' ) as $coupon ) { + $order->remove_coupon( $coupon->get_code() ); + } + + foreach ( $request['coupon_lines'] as $item ) { + if ( is_array( $item ) ) { + if ( empty( $item['id'] ) ) { + if ( empty( $item['code'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + + $results = $order->apply_coupon( wc_clean( $item['code'] ) ); + + if ( is_wp_error( $results ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); + } + } + } + } + + return true; + } + + /** + * Prepare a single order for create or update. + * + * @throws WC_REST_Exception When fails to set any item. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $order = new WC_Order( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'coupon_lines': + case 'status': + // Change should be done later so transitions have new data. + break; + case 'billing': + case 'shipping': + $this->update_address( $order, $value, $key ); + break; + case 'line_items': + case 'shipping_lines': + case 'fee_lines': + if ( is_array( $value ) ) { + foreach ( $value as $item ) { + if ( is_array( $item ) ) { + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $order->remove_item( $item['id'] ); + } else { + $this->set_item( $order, $key, $item ); + } + } + } + } + break; + case 'meta_data': + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + default: + if ( is_callable( array( $order, "set_{$key}" ) ) ) { + $order->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $order Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @throws WC_REST_Exception But all errors are validated before returning any data. + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + // Make sure gateways are loaded so hooks from gateways fire on save/create. + WC()->payment_gateways(); + + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { + // Make sure customer exists. + if ( false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } + } + + if ( $creating ) { + $object->set_created_via( 'rest-api' ); + $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $object->calculate_totals(); + } else { + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $object->calculate_totals( true ); + } + } + + // Set coupons. + $this->calculate_coupons( $request, $object ); + + // Set status. + if ( ! empty( $request['status'] ) ) { + $object->set_status( $request['status'] ); + } + + $object->save(); + + // Actions for after the order is saved. + if ( true === $request['set_paid'] ) { + if ( $creating || $object->needs_payment() ) { + $object->payment_complete( $request['transaction_id'] ); + } + } + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + // This is needed to get around an array to string notice in WC_REST_Orders_V2_Controller::prepare_objects_query. + $statuses = $request['status']; + unset( $request['status'] ); + $args = parent::prepare_objects_query( $request ); + + $args['post_status'] = array(); + foreach ( $statuses as $status ) { + if ( in_array( $status, $this->get_order_statuses(), true ) ) { + $args['post_status'][] = 'wc-' . $status; + } elseif ( 'any' === $status ) { + // Set status to "any" and short-circuit out. + $args['post_status'] = 'any'; + break; + } else { + $args['post_status'][] = $status; + } + } + + // Put the statuses back for further processing (next/prev links, etc). + $request['status'] = $statuses; + + return $args; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = parent::get_item_schema(); + + $schema['properties']['coupon_lines']['items']['properties']['discount']['readonly'] = true; + + return $schema; + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v3/class-wc-rest-payment-gateways-controller.php b/includes/v3/class-wc-rest-payment-gateways-controller.php new file mode 100644 index 00000000000..88f09312425 --- /dev/null +++ b/includes/v3/class-wc-rest-payment-gateways-controller.php @@ -0,0 +1,226 @@ + $gateway->id, + 'title' => $gateway->title, + 'description' => $gateway->description, + 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', + 'enabled' => ( 'yes' === $gateway->enabled ), + 'method_title' => $gateway->get_method_title(), + 'method_description' => $gateway->get_method_description(), + 'method_supports' => $gateway->supports, + 'settings' => $this->get_settings( $gateway ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $gateway, $request ) ); + + /** + * Filter payment gateway objects returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); + } + + /** + * Return settings associated with this payment gateway. + * + * @param WC_Payment_Gateway $gateway Gateway instance. + * + * @return array + */ + public function get_settings( $gateway ) { + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type. + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + + // Ignore 'enabled' and 'description' which get included elsewhere. + if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { + continue; + } + + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Get the payment gateway schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'payment_gateway', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + ), + 'enabled' => array( + 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_title' => array( + 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_supports' => array( + 'description' => __( 'Supported features for this payment gateway.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'settings' => array( + 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-product-attribute-terms-controller.php b/includes/v3/class-wc-rest-product-attribute-terms-controller.php new file mode 100644 index 00000000000..3e652894d69 --- /dev/null +++ b/includes/v3/class-wc-rest-product-attribute-terms-controller.php @@ -0,0 +1,27 @@ +/terms endpoint. + * + * @package WooCommerce/API + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Product Attribute Terms controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Product_Attribute_Terms_V2_Controller + */ +class WC_REST_Product_Attribute_Terms_Controller extends WC_REST_Product_Attribute_Terms_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/includes/v3/class-wc-rest-product-attributes-controller.php b/includes/v3/class-wc-rest-product-attributes-controller.php new file mode 100644 index 00000000000..047e6e4e257 --- /dev/null +++ b/includes/v3/class-wc-rest-product-attributes-controller.php @@ -0,0 +1,27 @@ +term_id, 'display_type', true ); + + // Get category order. + $menu_order = get_term_meta( $item->term_id, 'order', true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'parent' => (int) $item->parent, + 'description' => $item->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => null, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + // Get category image. + $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); + if ( $image_id ) { + $attachment = get_post( $image_id ); + + $data['image'] = array( + 'id' => (int) $image_id, + 'date_created' => wc_rest_prepare_date_response( $attachment->post_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), + 'src' => wp_get_attachment_url( $image_id ), + 'name' => get_the_title( $attachment ), + 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Category schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'parent' => array( + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'display' => array( + 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'default', + 'enum' => array( 'default', 'products', 'subcategories', 'both' ), + 'context' => array( 'view', 'edit' ), + ), + 'image' => array( + 'description' => __( 'Image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Update term meta fields. + * + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Request instance. + * @return bool|WP_Error + * + * @since 3.5.5 + */ + protected function update_term_meta_fields( $term, $request ) { + $id = (int) $term->term_id; + + if ( isset( $request['display'] ) ) { + update_term_meta( $id, 'display_type', 'default' === $request['display'] ? '' : $request['display'] ); + } + + if ( isset( $request['menu_order'] ) ) { + update_term_meta( $id, 'order', $request['menu_order'] ); + } + + if ( isset( $request['image'] ) ) { + if ( empty( $request['image']['id'] ) && ! empty( $request['image']['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $request['image']['src'] ) ); + + if ( is_wp_error( $upload ) ) { + return $upload; + } + + $image_id = wc_rest_set_uploaded_image_as_attachment( $upload ); + } else { + $image_id = isset( $request['image']['id'] ) ? absint( $request['image']['id'] ) : 0; + } + + // Check if image_id is a valid image attachment before updating the term meta. + if ( $image_id && wp_attachment_is_image( $image_id ) ) { + update_term_meta( $id, 'thumbnail_id', $image_id ); + + // Set the image alt. + if ( ! empty( $request['image']['alt'] ) ) { + update_post_meta( $image_id, '_wp_attachment_image_alt', wc_clean( $request['image']['alt'] ) ); + } + + // Set the image title. + if ( ! empty( $request['image']['name'] ) ) { + wp_update_post( + array( + 'ID' => $image_id, + 'post_title' => wc_clean( $request['image']['name'] ), + ) + ); + } + } else { + delete_term_meta( $id, 'thumbnail_id' ); + } + } + + return true; + } +} diff --git a/includes/v3/class-wc-rest-product-reviews-controller.php b/includes/v3/class-wc-rest-product-reviews-controller.php new file mode 100644 index 00000000000..602b1b5f8dd --- /dev/null +++ b/includes/v3/class-wc-rest-product-reviews-controller.php @@ -0,0 +1,1164 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'product_id' => array( + 'required' => true, + 'description' => __( 'Unique identifier for the product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'review' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Review content.', 'woocommerce' ), + ), + 'reviewer' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + ), + 'reviewer_email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to read webhook deliveries. + * + * @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_product_reviews_permissions( 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a new product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'edit', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'delete', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all reviews. + * + * @param WP_REST_Request $request Full details about the request. + * @return array|WP_Error + */ + public function get_items( $request ) { + // Retrieve the list of registered collection query parameters. + $registered = $this->get_collection_params(); + + /* + * This array defines mappings between public API query parameters whose + * values are accepted as-passed, and their internal WP_Query parameter + * name equivalents (some are the same). Only values which are also + * present in $registered will be set. + */ + $parameter_mappings = array( + 'reviewer' => 'author__in', + 'reviewer_email' => 'author_email', + 'reviewer_exclude' => 'author__not_in', + 'exclude' => 'comment__not_in', + 'include' => 'comment__in', + 'offset' => 'offset', + 'order' => 'order', + 'per_page' => 'number', + 'product' => 'post__in', + 'search' => 'search', + 'status' => 'status', + ); + + $prepared_args = array(); + + /* + * For each known parameter which is both registered and present in the request, + * set the parameter's value on the query $prepared_args. + */ + foreach ( $parameter_mappings as $api_param => $wp_param ) { + if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { + $prepared_args[ $wp_param ] = $request[ $api_param ]; + } + } + + // Ensure certain parameter values default to empty strings. + foreach ( array( 'author_email', 'search' ) as $param ) { + if ( ! isset( $prepared_args[ $param ] ) ) { + $prepared_args[ $param ] = ''; + } + } + + if ( isset( $registered['orderby'] ) ) { + $prepared_args['orderby'] = $this->normalize_query_param( $request['orderby'] ); + } + + if ( isset( $prepared_args['status'] ) ) { + $prepared_args['status'] = 'approved' === $prepared_args['status'] ? 'approve' : $prepared_args['status']; + } + + $prepared_args['no_found_rows'] = false; + $prepared_args['date_query'] = array(); + + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $registered['before'], $request['before'] ) ) { + $prepared_args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $registered['after'], $request['after'] ) ) { + $prepared_args['date_query'][0]['after'] = $request['after']; + } + + if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { + $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); + } + + /** + * Filters arguments, before passing to WP_Comment_Query, when querying reviews via the REST API. + * + * @since 3.5.0 + * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ + * @param array $prepared_args Array of arguments for WP_Comment_Query. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_product_review_query', $prepared_args, $request ); + + // Make sure that returns only reviews. + $prepared_args['type'] = 'review'; + + // Query reviews. + $query = new WP_Comment_Query(); + $query_result = $query->query( $prepared_args ); + $reviews = array(); + + foreach ( $query_result as $review ) { + if ( ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { + continue; + } + + $data = $this->prepare_item_for_response( $review, $request ); + $reviews[] = $this->prepare_response_for_collection( $data ); + } + + $total_reviews = (int) $query->found_comments; + $max_pages = (int) $query->max_num_pages; + + if ( $total_reviews < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $prepared_args['number'], $prepared_args['offset'] ); + + $query = new WP_Comment_Query(); + $prepared_args['count'] = true; + + $total_reviews = $query->query( $prepared_args ); + $max_pages = ceil( $total_reviews / $request['per_page'] ); + } + + $response = rest_ensure_response( $reviews ); + $response->header( 'X-WP-Total', $total_reviews ); + $response->header( 'X-WP-TotalPages', $max_pages ); + + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); + + if ( $request['page'] > 1 ) { + $prev_page = $request['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 > $request['page'] ) { + $next_page = $request['page'] + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Create a single review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $prepared_review ) ) { + return $prepared_review; + } + + $prepared_review['comment_type'] = 'review'; + + /* + * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). + */ + if ( empty( $prepared_review['comment_content'] ) ) { + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). + if ( ! isset( $prepared_review['comment_date_gmt'] ) ) { + $prepared_review['comment_date_gmt'] = current_time( 'mysql', true ); + } + + if ( ! empty( $_SERVER['REMOTE_ADDR'] ) && rest_is_ip_address( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) ) { // WPCS: input var ok, sanitization ok. + $prepared_review['comment_author_IP'] = wc_clean( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // WPCS: input var ok. + } else { + $prepared_review['comment_author_IP'] = '127.0.0.1'; + } + + if ( ! empty( $request['author_user_agent'] ) ) { + $prepared_review['comment_agent'] = $request['author_user_agent']; + } elseif ( $request->get_header( 'user_agent' ) ) { + $prepared_review['comment_agent'] = $request->get_header( 'user_agent' ); + } else { + $prepared_review['comment_agent'] = ''; + } + + $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); + if ( is_wp_error( $check_comment_lengths ) ) { + $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $prepared_review['comment_parent'] = 0; + $prepared_review['comment_author_url'] = ''; + $prepared_review['comment_approved'] = wp_allow_comment( $prepared_review, true ); + + if ( is_wp_error( $prepared_review['comment_approved'] ) ) { + $error_code = $prepared_review['comment_approved']->get_error_code(); + $error_message = $prepared_review['comment_approved']->get_error_message(); + + if ( 'comment_duplicate' === $error_code ) { + return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 409 ) ); + } + + if ( 'comment_flood' === $error_code ) { + return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 400 ) ); + } + + return $prepared_review['comment_approved']; + } + + /** + * Filters a review before it is inserted via the REST API. + * + * Allows modification of the review right before it is inserted via wp_insert_comment(). + * Returning a WP_Error value from the filter will shortcircuit insertion and allow + * skipping further processing. + * + * @since 3.5.0 + * @param array|WP_Error $prepared_review The prepared review data for wp_insert_comment(). + * @param WP_REST_Request $request Request used to insert the review. + */ + $prepared_review = apply_filters( 'woocommerce_rest_pre_insert_product_review', $prepared_review, $request ); + if ( is_wp_error( $prepared_review ) ) { + return $prepared_review; + } + + $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); + + if ( ! $review_id ) { + return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( isset( $request['status'] ) ) { + $this->handle_status_param( $request['status'], $review_id ); + } + + update_comment_meta( $review_id, 'rating', ! empty( $request['rating'] ) ? $request['rating'] : '0' ); + + $review = get_comment( $review_id ); + + /** + * Fires after a comment is created or updated via the REST API. + * + * @param WP_Comment $review Inserted or updated comment object. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating a comment, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_review', $review, $request, true ); + + $fields_update = $this->update_additional_fields_for_object( $review, $request ); + if ( is_wp_error( $fields_update ) ) { + return $fields_update; + } + + $context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view'; + $request->set_param( 'context', $context ); + + $response = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $response ); + + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $review_id ) ) ); + + return $response; + } + + /** + * Get a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $data = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $data ); + + return $response; + } + + /** + * Updates a review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. + */ + public function update_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $id = (int) $review->comment_ID; + + if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { + return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_args = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $prepared_args ) ) { + return $prepared_args; + } + + if ( ! empty( $prepared_args['comment_post_ID'] ) ) { + if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + if ( empty( $prepared_args ) && isset( $request['status'] ) ) { + // Only the comment status is being changed. + $change = $this->handle_status_param( $request['status'], $id ); + + if ( ! $change ) { + return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + } elseif ( ! empty( $prepared_args ) ) { + if ( is_wp_error( $prepared_args ) ) { + return $prepared_args; + } + + if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $prepared_args['comment_ID'] = $id; + + $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); + if ( is_wp_error( $check_comment_lengths ) ) { + $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); + + if ( false === $updated ) { + return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( isset( $request['status'] ) ) { + $this->handle_status_param( $request['status'], $id ); + } + } + + if ( ! empty( $request['rating'] ) ) { + update_comment_meta( $id, 'rating', $request['rating'] ); + } + + $review = get_comment( $id ); + + /** This action is documented in includes/api/class-wc-rest-product-reviews-controller.php */ + do_action( 'woocommerce_rest_insert_product_review', $review, $request, false ); + + $fields_update = $this->update_additional_fields_for_object( $review, $request ); + + if ( is_wp_error( $fields_update ) ) { + return $fields_update; + } + + $request->set_param( 'context', 'edit' ); + + $response = $this->prepare_item_for_response( $review, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Deletes a review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. + */ + public function delete_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + /** + * Filters whether a review can be trashed. + * + * Return false to disable trash support for the post. + * + * @since 3.5.0 + * @param bool $supports_trash Whether the post type support trashing. + * @param WP_Comment $review The review object being considered for trashing support. + */ + $supports_trash = apply_filters( 'woocommerce_rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $review ); + + $request->set_param( 'context', 'edit' ); + + if ( $force ) { + $previous = $this->prepare_item_for_response( $review, $request ); + $result = wp_delete_comment( $review->comment_ID, true ); + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); + } else { + // If this type doesn't support trashing, error out. + if ( ! $supports_trash ) { + /* translators: %s: force=true */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce' ), 'force=true' ), array( 'status' => 501 ) ); + } + + if ( 'trash' === $review->comment_approved ) { + return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + } + + $result = wp_trash_comment( $review->comment_ID ); + $review = get_comment( $review->comment_ID ); + $response = $this->prepare_item_for_response( $review, $request ); + } + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a review is deleted via the REST API. + * + * @param WP_Comment $review The deleted review data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_review', $review, $response, $request ); + + return $response; + } + + /** + * Prepare a single product review output for response. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $review, $request ) { + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $fields = $this->get_fields_for_response( $request ); + $data = array(); + + if ( in_array( 'id', $fields, true ) ) { + $data['id'] = (int) $review->comment_ID; + } + if ( in_array( 'date_created', $fields, true ) ) { + $data['date_created'] = wc_rest_prepare_date_response( $review->comment_date ); + } + if ( in_array( 'date_created_gmt', $fields, true ) ) { + $data['date_created_gmt'] = wc_rest_prepare_date_response( $review->comment_date_gmt ); + } + if ( in_array( 'product_id', $fields, true ) ) { + $data['product_id'] = (int) $review->comment_post_ID; + } + if ( in_array( 'status', $fields, true ) ) { + $data['status'] = $this->prepare_status_response( (string) $review->comment_approved ); + } + if ( in_array( 'reviewer', $fields, true ) ) { + $data['reviewer'] = $review->comment_author; + } + if ( in_array( 'reviewer_email', $fields, true ) ) { + $data['reviewer_email'] = $review->comment_author_email; + } + if ( in_array( 'review', $fields, true ) ) { + $data['review'] = 'view' === $context ? wpautop( $review->comment_content ) : $review->comment_content; + } + if ( in_array( 'rating', $fields, true ) ) { + $data['rating'] = (int) get_comment_meta( $review->comment_ID, 'rating', true ); + } + if ( in_array( 'verified', $fields, true ) ) { + $data['verified'] = wc_review_is_from_verified_owner( $review->comment_ID ); + } + if ( in_array( 'reviewer_avatar_urls', $fields, true ) ) { + $data['reviewer_avatar_urls'] = rest_get_avatar_urls( $review->comment_author_email ); + } + + $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( $review ) ); + + /** + * Filter product reviews object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $review Product review object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + } + + /** + * Prepare a single product review to be inserted into the database. + * + * @param WP_REST_Request $request Request object. + * @return array|WP_Error $prepared_review + */ + protected function prepare_item_for_database( $request ) { + if ( isset( $request['id'] ) ) { + $prepared_review['comment_ID'] = (int) $request['id']; + } + + if ( isset( $request['review'] ) ) { + $prepared_review['comment_content'] = $request['review']; + } + + if ( isset( $request['product_id'] ) ) { + $prepared_review['comment_post_ID'] = (int) $request['product_id']; + } + + if ( isset( $request['reviewer'] ) ) { + $prepared_review['comment_author'] = $request['reviewer']; + } + + if ( isset( $request['reviewer_email'] ) ) { + $prepared_review['comment_author_email'] = $request['reviewer_email']; + } + + if ( ! empty( $request['date_created'] ) ) { + $date_data = rest_get_date_with_gmt( $request['date_created'] ); + + if ( ! empty( $date_data ) ) { + list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; + } + } elseif ( ! empty( $request['date_created_gmt'] ) ) { + $date_data = rest_get_date_with_gmt( $request['date_created_gmt'], true ); + + if ( ! empty( $date_data ) ) { + list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; + } + } + + /** + * Filters a review after it is prepared for the database. + * + * Allows modification of the review right after it is prepared for the database. + * + * @since 3.5.0 + * @param array $prepared_review The prepared review data for `wp_insert_comment`. + * @param WP_REST_Request $request The current request. + */ + return apply_filters( 'woocommerce_rest_preprocess_product_review', $prepared_review, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $review Product review object. + * @return array Links for the given product review. + */ + protected function prepare_links( $review ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $review->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + if ( 0 !== (int) $review->comment_post_ID ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $review->comment_post_ID ) ), + ); + } + + if ( 0 !== (int) $review->user_id ) { + $links['reviewer'] = array( + 'href' => rest_url( 'wp/v2/users/' . $review->user_id ), + 'embeddable' => true, + ); + } + + return $links; + } + + /** + * Get the Product Review's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_review', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Status of the review.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'approved', + 'enum' => array( 'approved', 'hold', 'spam', 'unspam', 'trash', 'untrash' ), + 'context' => array( 'view', 'edit' ), + ), + 'reviewer' => array( + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'reviewer_email' => array( + 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'rating' => array( + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'verified' => array( + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + if ( get_option( 'show_avatars' ) ) { + $avatar_properties = array(); + $avatar_sizes = rest_get_avatar_sizes(); + + foreach ( $avatar_sizes as $size ) { + $avatar_properties[ $size ] = array( + /* translators: %d: avatar image size in pixels */ + 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce' ), $size ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'embed', 'view', 'edit' ), + ); + } + $schema['properties']['reviewer_avatar_urls'] = array( + 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $avatar_properties, + ); + } + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + ); + $params['before'] = array( + 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + ); + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + ); + $params['include'] = array( + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + ); + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( + 'asc', + 'desc', + ), + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date_gmt', + 'enum' => array( + 'date', + 'date_gmt', + 'id', + 'include', + 'product', + ), + ); + $params['reviewer'] = array( + 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['reviewer_exclude'] = array( + 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['reviewer_email'] = array( + 'default' => null, + 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce' ), + 'format' => 'email', + 'type' => 'string', + ); + $params['product'] = array( + 'default' => array(), + 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['status'] = array( + 'default' => 'approved', + 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'enum' => array( + 'all', + 'hold', + 'approved', + 'spam', + 'trash', + ), + ); + + /** + * Filter collection parameters for the reviews controller. + * + * This filter registers the collection parameter, but does not map the + * collection parameter to an internal WP_Comment_Query parameter. Use the + * `wc_rest_review_query` filter to set WP_Comment_Query parameters. + * + * @since 3.5.0 + * @param array $params JSON Schema-formatted collection parameters. + */ + return apply_filters( 'woocommerce_rest_product_review_collection_params', $params ); + } + + /** + * Get the reivew, if the ID is valid. + * + * @since 3.5.0 + * @param int $id Supplied ID. + * @return WP_Comment|WP_Error Comment object if ID is valid, WP_Error otherwise. + */ + protected function get_review( $id ) { + $id = (int) $id; + $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + + if ( 0 >= $id ) { + return $error; + } + + $review = get_comment( $id ); + if ( empty( $review ) ) { + return $error; + } + + if ( ! empty( $review->comment_post_ID ) ) { + $post = get_post( (int) $review->comment_post_ID ); + + if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + return $review; + } + + /** + * Prepends internal property prefix to query parameters to match our response fields. + * + * @since 3.5.0 + * @param string $query_param Query parameter. + * @return string + */ + protected function normalize_query_param( $query_param ) { + $prefix = 'comment_'; + + switch ( $query_param ) { + case 'id': + $normalized = $prefix . 'ID'; + break; + case 'product': + $normalized = $prefix . 'post_ID'; + break; + case 'include': + $normalized = 'comment__in'; + break; + default: + $normalized = $prefix . $query_param; + break; + } + + return $normalized; + } + + /** + * Checks comment_approved to set comment status for single comment output. + * + * @since 3.5.0 + * @param string|int $comment_approved comment status. + * @return string Comment status. + */ + protected function prepare_status_response( $comment_approved ) { + switch ( $comment_approved ) { + case 'hold': + case '0': + $status = 'hold'; + break; + case 'approve': + case '1': + $status = 'approved'; + break; + case 'spam': + case 'trash': + default: + $status = $comment_approved; + break; + } + + return $status; + } + + /** + * Sets the comment_status of a given review object when creating or updating a review. + * + * @since 3.5.0 + * @param string|int $new_status New review status. + * @param int $id Review ID. + * @return bool Whether the status was changed. + */ + protected function handle_status_param( $new_status, $id ) { + $old_status = wp_get_comment_status( $id ); + + if ( $new_status === $old_status ) { + return false; + } + + switch ( $new_status ) { + case 'approved': + case 'approve': + case '1': + $changed = wp_set_comment_status( $id, 'approve' ); + break; + case 'hold': + case '0': + $changed = wp_set_comment_status( $id, 'hold' ); + break; + case 'spam': + $changed = wp_spam_comment( $id ); + break; + case 'unspam': + $changed = wp_unspam_comment( $id ); + break; + case 'trash': + $changed = wp_trash_comment( $id ); + break; + case 'untrash': + $changed = wp_untrash_comment( $id ); + break; + default: + $changed = false; + break; + } + + return $changed; + } +} diff --git a/includes/v3/class-wc-rest-product-shipping-classes-controller.php b/includes/v3/class-wc-rest-product-shipping-classes-controller.php new file mode 100644 index 00000000000..3a3aa7c0444 --- /dev/null +++ b/includes/v3/class-wc-rest-product-shipping-classes-controller.php @@ -0,0 +1,27 @@ +/variations endpoints. + * + * @package WooCommerce\API + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API variations controller class. + * + * @package WooCommerce/API + * @extends WC_REST_Product_Variations_V2_Controller + */ +class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; + + /** + * Prepare a single variation output for response. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = array( + 'id' => $object->get_id(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), + 'description' => wc_format_content( $object->get_description() ), + 'permalink' => $object->get_permalink(), + 'sku' => $object->get_sku(), + 'price' => $object->get_price(), + 'regular_price' => $object->get_regular_price(), + 'sale_price' => $object->get_sale_price(), + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), + 'on_sale' => $object->is_on_sale(), + 'status' => $object->get_status(), + 'purchasable' => $object->is_purchasable(), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => $this->get_downloads( $object ), + 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, + 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, + 'tax_status' => $object->get_tax_status(), + 'tax_class' => $object->get_tax_class(), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity(), + 'stock_status' => $object->get_stock_status(), + 'backorders' => $object->get_backorders(), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'weight' => $object->get_weight(), + 'dimensions' => array( + 'length' => $object->get_length(), + 'width' => $object->get_width(), + 'height' => $object->get_height(), + ), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id(), + 'image' => $this->get_image( $object ), + 'attributes' => $this->get_attributes( $object ), + 'menu_order' => $object->get_menu_order(), + 'meta_data' => $object->get_meta_data(), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare a single variation for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + if ( isset( $request['id'] ) ) { + $variation = wc_get_product( absint( $request['id'] ) ); + } else { + $variation = new WC_Product_Variation(); + } + + $variation->set_parent_id( absint( $request['product_id'] ) ); + + // Status. + if ( isset( $request['status'] ) ) { + $variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // SKU. + if ( isset( $request['sku'] ) ) { + $variation->set_sku( wc_clean( $request['sku'] ) ); + } + + // Thumbnail. + if ( isset( $request['image'] ) ) { + if ( is_array( $request['image'] ) ) { + $variation = $this->set_variation_image( $variation, $request['image'] ); + } else { + $variation->set_image_id( '' ); + } + } + + // Virtual variation. + if ( isset( $request['virtual'] ) ) { + $variation->set_virtual( $request['virtual'] ); + } + + // Downloadable variation. + if ( isset( $request['downloadable'] ) ) { + $variation->set_downloadable( $request['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $variation->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $variation->set_download_expiry( $request['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $request ); + + // Stock handling. + if ( isset( $request['manage_stock'] ) ) { + $variation->set_manage_stock( $request['manage_stock'] ); + } + + if ( isset( $request['stock_status'] ) ) { + $variation->set_stock_status( $request['stock_status'] ); + } + + if ( isset( $request['backorders'] ) ) { + $variation->set_backorders( $request['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $request['stock_quantity'] ) ) { + $variation->set_stock_quantity( $request['stock_quantity'] ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $variation->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $variation->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + + // Tax class. + if ( isset( $request['tax_class'] ) ) { + $variation->set_tax_class( $request['tax_class'] ); + } + + // Description. + if ( isset( $request['description'] ) ) { + $variation->set_description( wp_kses_post( $request['description'] ) ); + } + + // Update taxonomies. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + $parent = wc_get_product( $variation->get_parent_id() ); + + if ( ! $parent ) { + return new WP_Error( + // Translators: %d parent ID. + "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $variation->get_parent_id() ), array( + 'status' => 404, + ) + ); + } + + $parent_attributes = $parent->get_attributes(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + // Menu order. + if ( $request['menu_order'] ) { + $variation->set_menu_order( $request['menu_order'] ); + } + + // Meta data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $variation Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); + } + + /** + * Get the image for a product variation. + * + * @param WC_Product_Variation $variation Variation data. + * @return array + */ + protected function get_image( $variation ) { + if ( ! $variation->get_image_id() ) { + return; + } + + $attachment_id = $variation->get_image_id(); + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + return; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + return; + } + + if ( ! isset( $image ) ) { + return array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + } + + /** + * Set variation image. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product_Variation $variation Variation instance. + * @param array $image Image data. + * @return WC_Product_Variation + */ + protected function set_variation_image( $variation, $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $variation->get_id(), array( $image ) ) ) { + throw new WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $variation->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: attachment ID */ + throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $variation->set_image_id( $attachment_id ); + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + + return $variation; + } + + /** + * Get the Variation's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Variation description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Variation status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_keys( get_post_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); + + // Set post_status. + $args['post_status'] = $request['status']; + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product based on stock_status. + if ( ! empty( $request['stock_status'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_stock_status', + 'value' => $request['stock_status'], + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + $args['post_parent'] = $request['product_id']; + + return $args; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + unset( + $params['in_stock'], + $params['type'], + $params['featured'], + $params['category'], + $params['tag'], + $params['shipping_class'], + $params['attribute'], + $params['attribute_term'] + ); + + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/includes/v3/class-wc-rest-products-controller.php b/includes/v3/class-wc-rest-products-controller.php new file mode 100644 index 00000000000..8b79b823604 --- /dev/null +++ b/includes/v3/class-wc-rest-products-controller.php @@ -0,0 +1,1341 @@ +get_image_id() ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + + return $images; + } + + /** + * Make extra product orderby features supported by WooCommerce available to the WC API. + * This includes 'price', 'popularity', and 'rating'. + * + * @param WP_REST_Request $request Request data. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); + + // Set post_status. + $args['post_status'] = $request['status']; + + // Taxonomy query to filter products by type, category, + // tag, shipping class, and attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies = array( + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + // Build tax_query if taxonomies are set. + if ( ! empty( $tax_query ) ) { + if ( ! empty( $args['tax_query'] ) ) { + $args['tax_query'] = array_merge( $tax_query, $args['tax_query'] ); // WPCS: slow query ok. + } else { + $args['tax_query'] = $tax_query; // WPCS: slow query ok. + } + } + + // Filter featured. + if ( is_bool( $request['featured'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'featured', + 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', + ); + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product by stock_status. + if ( ! empty( $request['stock_status'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, array( + 'key' => '_stock_status', + 'value' => $request['stock_status'], + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + $orderby = $request->get_param( 'orderby' ); + $order = $request->get_param( 'order' ); + + $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); + $args['orderby'] = $ordering_args['orderby']; + $args['order'] = $ordering_args['order']; + if ( $ordering_args['meta_key'] ) { + $args['meta_key'] = $ordering_args['meta_key']; // WPCS: slow query ok. + } + + return $args; + } + + /** + * Set product images. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param array $images Images data. + * @return WC_Product + */ + protected function set_product_images( $product, $images ) { + $images = is_array( $images ) ? array_filter( $images ) : array(); + + if ( ! empty( $images ) ) { + $gallery = array(); + + foreach ( $images as $index => $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { + throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: image ID */ + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $featured_image = $product->get_image_id(); + + if ( 0 === $index ) { + $product->set_image_id( $attachment_id ); + } else { + $gallery[] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + } + + $product->set_gallery_image_ids( $gallery ); + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Prepare a single product for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + + // Type is the most important part here because we need to be using the correct class and methods. + if ( isset( $request['type'] ) ) { + $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + + $product = new $classname( $id ); + } elseif ( isset( $request['id'] ) ) { + $product = wc_get_product( $id ); + } else { + $product = new WC_Product_Simple(); + } + + if ( 'variation' === $product->get_type() ) { + return new WP_Error( + "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( + 'status' => 404, + ) + ); + } + + // Post title. + if ( isset( $request['name'] ) ) { + $product->set_name( wp_filter_post_kses( $request['name'] ) ); + } + + // Post content. + if ( isset( $request['description'] ) ) { + $product->set_description( wp_filter_post_kses( $request['description'] ) ); + } + + // Post excerpt. + if ( isset( $request['short_description'] ) ) { + $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); + } + + // Post status. + if ( isset( $request['status'] ) ) { + $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // Post slug. + if ( isset( $request['slug'] ) ) { + $product->set_slug( $request['slug'] ); + } + + // Menu order. + if ( isset( $request['menu_order'] ) ) { + $product->set_menu_order( $request['menu_order'] ); + } + + // Comment status. + if ( isset( $request['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $request['reviews_allowed'] ); + } + + // Virtual. + if ( isset( $request['virtual'] ) ) { + $product->set_virtual( $request['virtual'] ); + } + + // Tax status. + if ( isset( $request['tax_status'] ) ) { + $product->set_tax_status( $request['tax_status'] ); + } + + // Tax Class. + if ( isset( $request['tax_class'] ) ) { + $product->set_tax_class( $request['tax_class'] ); + } + + // Catalog Visibility. + if ( isset( $request['catalog_visibility'] ) ) { + $product->set_catalog_visibility( $request['catalog_visibility'] ); + } + + // Purchase Note. + if ( isset( $request['purchase_note'] ) ) { + $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); + } + + // Featured Product. + if ( isset( $request['featured'] ) ) { + $product->set_featured( $request['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $request ); + + // SKU. + if ( isset( $request['sku'] ) ) { + $product->set_sku( wc_clean( $request['sku'] ) ); + } + + // Attributes. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + } else { + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $product->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $product->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + } + + // Product parent ID. + if ( isset( $request['parent_id'] ) ) { + $product->set_parent_id( $request['parent_id'] ); + } + + // Sold individually. + if ( isset( $request['sold_individually'] ) ) { + $product->set_sold_individually( $request['sold_individually'] ); + } + + // Stock status; stock_status has priority over in_stock. + if ( isset( $request['stock_status'] ) ) { + $stock_status = $request['stock_status']; + } else { + $stock_status = $product->get_stock_status(); + } + + // Stock data. + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $request['manage_stock'] ) ) { + $product->set_manage_stock( $request['manage_stock'] ); + } + + // Backorders. + if ( isset( $request['backorders'] ) ) { + $product->set_backorders( $request['backorders'] ); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( $product->get_manage_stock() ) { + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $request['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $request['upsell_ids'] ) ) { + $upsells = array(); + $ids = $request['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + } + + $product->set_upsell_ids( $upsells ); + } + + // Cross sells. + if ( isset( $request['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $request['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + } + + $product->set_cross_sell_ids( $crosssells ); + } + + // Product categories. + if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); + } + + // Downloadable. + if ( isset( $request['downloadable'] ) ) { + $product->set_downloadable( $request['downloadable'] ); + } + + // Downloadable options. + if ( $product->get_downloadable() ) { + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $product->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $product->set_download_expiry( $request['download_expiry'] ); + } + } + + // Product url and button text for external products. + if ( $product->is_type( 'external' ) ) { + if ( isset( $request['external_url'] ) ) { + $product->set_product_url( $request['external_url'] ); + } + + if ( isset( $request['button_text'] ) ) { + $product->set_button_text( $request['button_text'] ); + } + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $request ); + } + + // Set children for a grouped product. + if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { + $product->set_children( $request['grouped_products'] ); + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + $product = $this->set_product_images( $product, $request['images'] ); + } + + // Allow set meta_data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + if ( ! empty( $request['date_created'] ) ) { + $date = rest_parse_date( $request['date_created'] ); + + if ( $date ) { + $product->set_date_created( $date ); + } + } + + if ( ! empty( $request['date_created_gmt'] ) ) { + $date = rest_parse_date( $request['date_created_gmt'], true ); + + if ( $date ) { + $product->set_date_created( $date ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $product Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + 'readonly' => true, + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Add new options for 'orderby' to the collection params. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); + + unset( $params['in_stock'] ); + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @param string $context Request context. + * Options: 'view' and 'edit'. + * @return array + */ + protected function get_product_data( $product, $context = 'view' ) { + $data = parent::get_product_data( $product, $context ); + + // Replace in_stock with stock_status. + $pos = array_search( 'in_stock', array_keys( $data ), true ); + $array_section_1 = array_slice( $data, 0, $pos, true ); + $array_section_2 = array_slice( $data, $pos + 1, null, true ); + + return $array_section_1 + array( 'stock_status' => $product->get_stock_status( $context ) ) + $array_section_2; + } +} diff --git a/includes/v3/class-wc-rest-report-coupons-totals-controller.php b/includes/v3/class-wc-rest-report-coupons-totals-controller.php new file mode 100644 index 00000000000..fa73796e3fe --- /dev/null +++ b/includes/v3/class-wc-rest-report-coupons-totals-controller.php @@ -0,0 +1,143 @@ + $name ) { + $results = $wpdb->get_results( + $wpdb->prepare( " + SELECT count(meta_id) AS total + FROM $wpdb->postmeta + WHERE meta_key = 'discount_type' + AND meta_value = %s + ", $slug ) + ); + + $total = isset( $results[0] ) ? (int) $results[0]->total : 0; + + $data[] = array( + 'slug' => $slug, + 'name' => $name, + 'total' => $total, + ); + } + + set_transient( 'rest_api_coupons_type_count', $data, YEAR_IN_SECONDS ); + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_count', $response, $report, $request ); + } + + /** + * 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_coupon_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Coupon type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of coupons.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-report-customers-totals-controller.php b/includes/v3/class-wc-rest-report-customers-totals-controller.php new file mode 100644 index 00000000000..e5459728414 --- /dev/null +++ b/includes/v3/class-wc-rest-report-customers-totals-controller.php @@ -0,0 +1,154 @@ + $total ) { + if ( in_array( $role, array( 'administrator', 'shop_manager' ), true ) ) { + continue; + } + + $total_customers += (int) $total; + } + + $customers_query = new WP_User_Query( + array( + 'role__not_in' => array( 'administrator', 'shop_manager' ), + 'number' => 0, + 'fields' => 'ID', + 'count_total' => true, + 'meta_query' => array( // WPCS: slow query ok. + array( + 'key' => 'paying_customer', + 'value' => 1, + 'compare' => '=', + ), + ), + ) + ); + + $total_paying = (int) $customers_query->get_total(); + + $data = array( + array( + 'slug' => 'paying', + 'name' => __( 'Paying customer', 'woocommerce' ), + 'total' => $total_paying, + ), + array( + 'slug' => 'non_paying', + 'name' => __( 'Non-paying customer', 'woocommerce' ), + 'total' => $total_customers - $total_paying, + ), + ); + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_count', $response, $report, $request ); + } + + /** + * 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_customer_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Customer type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of customers.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-report-orders-totals-controller.php b/includes/v3/class-wc-rest-report-orders-totals-controller.php new file mode 100644 index 00000000000..4bfb773ba76 --- /dev/null +++ b/includes/v3/class-wc-rest-report-orders-totals-controller.php @@ -0,0 +1,127 @@ + $name ) { + if ( ! isset( $totals->$slug ) ) { + continue; + } + + $data[] = array( + 'slug' => str_replace( 'wc-', '', $slug ), + 'name' => $name, + 'total' => (int) $totals->$slug, + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_count', $response, $report, $request ); + } + + /** + * 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_order_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Order status name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of orders.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-report-products-totals-controller.php b/includes/v3/class-wc-rest-report-products-totals-controller.php new file mode 100644 index 00000000000..63812219260 --- /dev/null +++ b/includes/v3/class-wc-rest-report-products-totals-controller.php @@ -0,0 +1,133 @@ + 'product_type', + 'hide_empty' => false, + ) + ); + $data = array(); + + foreach ( $terms as $product_type ) { + if ( ! isset( $types[ $product_type->name ] ) ) { + continue; + } + + $data[] = array( + 'slug' => $product_type->name, + 'name' => $types[ $product_type->name ], + 'total' => (int) $product_type->count, + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_count', $response, $report, $request ); + } + + /** + * 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_product_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-report-reviews-totals-controller.php b/includes/v3/class-wc-rest-report-reviews-totals-controller.php new file mode 100644 index 00000000000..4bff520ee3d --- /dev/null +++ b/includes/v3/class-wc-rest-report-reviews-totals-controller.php @@ -0,0 +1,132 @@ + true, + 'post_type' => 'product', + 'meta_key' => 'rating', // WPCS: slow query ok. + 'meta_value' => '', // WPCS: slow query ok. + ); + + for ( $i = 1; $i <= 5; $i++ ) { + $query_data['meta_value'] = $i; + + $data[] = array( + 'slug' => 'rated_' . $i . '_out_of_5', + /* translators: %s: average rating */ + 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $i ), + 'total' => (int) get_comments( $query_data ), + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_reviews_count', $response, $report, $request ); + } + + /** + * 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_review_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Review type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of reviews.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-report-sales-controller.php b/includes/v3/class-wc-rest-report-sales-controller.php new file mode 100644 index 00000000000..165add54796 --- /dev/null +++ b/includes/v3/class-wc-rest-report-sales-controller.php @@ -0,0 +1,27 @@ + 'orders/totals', + 'description' => __( 'Orders totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'products/totals', + 'description' => __( 'Products totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'customers/totals', + 'description' => __( 'Customers totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'coupons/totals', + 'description' => __( 'Coupons totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'reviews/totals', + 'description' => __( 'Reviews totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'categories/totals', + 'description' => __( 'Categories totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'tags/totals', + 'description' => __( 'Tags totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'attributes/totals', + 'description' => __( 'Attributes totals.', 'woocommerce' ), + ); + + return $reports; + } +} diff --git a/includes/v3/class-wc-rest-setting-options-controller.php b/includes/v3/class-wc-rest-setting-options-controller.php new file mode 100644 index 00000000000..9613ce818eb --- /dev/null +++ b/includes/v3/class-wc-rest-setting-options-controller.php @@ -0,0 +1,250 @@ + 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + + if ( empty( $settings ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_settings = array(); + foreach ( $settings as $setting ) { + $option_key = $setting['option_key']; + $setting = $this->filter_setting( $setting ); + $default = isset( $setting['default'] ) ? $setting['default'] : ''; + // Get the option value. + if ( is_array( $option_key ) ) { + $option = get_option( $option_key[0] ); + $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; + } else { + $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); + $setting['value'] = $admin_setting_value; + } + + if ( 'multi_select_countries' === $setting['type'] ) { + $setting['options'] = WC()->countries->get_countries(); + $setting['type'] = 'multiselect'; + } elseif ( 'single_select_country' === $setting['type'] ) { + $setting['type'] = 'select'; + $setting['options'] = $this->get_countries_and_states(); + } elseif ( 'single_select_page' === $setting['type'] ) { + $pages = get_pages( + array( + 'sort_column' => 'menu_order', + 'sort_order' => 'ASC', + 'hierarchical' => 0, + ) + ); + $options = array(); + foreach ( $pages as $page ) { + $options[ $page->ID ] = ! empty( $page->post_title ) ? $page->post_title : '#' . $page->ID; + } + $setting['type'] = 'select'; + $setting['options'] = $options; + } + + $filtered_settings[] = $setting; + } + + return $filtered_settings; + } + + /** + * Returns a list of countries and states for use in the base location setting. + * + * @since 3.0.7 + * @return array Array of states and countries. + */ + private function get_countries_and_states() { + $countries = WC()->countries->get_countries(); + if ( ! $countries ) { + return array(); + } + $output = array(); + foreach ( $countries as $key => $value ) { + $states = WC()->countries->get_states( $key ); + + if ( $states ) { + foreach ( $states as $state_key => $state_value ) { + $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; + } + } else { + $output[ $key ] = $value; + } + } + return $output; + } + + /** + * Get the settings schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'group_id' => array( + 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'options' => array( + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-settings-controller.php b/includes/v3/class-wc-rest-settings-controller.php new file mode 100644 index 00000000000..f3ad622e467 --- /dev/null +++ b/includes/v3/class-wc-rest-settings-controller.php @@ -0,0 +1,112 @@ +namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_batch_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 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; + } + + /** + * Update a setting. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $options_controller = new WC_REST_Setting_Options_Controller(); + $response = $options_controller->update_item( $request ); + + return $response; + } + + /** + * Get the groups schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting_group', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/v3/class-wc-rest-shipping-methods-controller.php b/includes/v3/class-wc-rest-shipping-methods-controller.php new file mode 100644 index 00000000000..075e4f777cd --- /dev/null +++ b/includes/v3/class-wc-rest-shipping-methods-controller.php @@ -0,0 +1,27 @@ +/locations endpoint. + * + * @package WooCommerce/API + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Locations class. + * + * @package WooCommerce/API + * @extends WC_REST_Shipping_Zone_Locations_V2_Controller + */ +class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zone_Locations_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/includes/v3/class-wc-rest-shipping-zone-methods-controller.php b/includes/v3/class-wc-rest-shipping-zone-methods-controller.php new file mode 100644 index 00000000000..6058e95baaf --- /dev/null +++ b/includes/v3/class-wc-rest-shipping-zone-methods-controller.php @@ -0,0 +1,27 @@ +/methods endpoint. + * + * @package WooCommerce/API + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Methods class. + * + * @package WooCommerce/API + * @extends WC_REST_Shipping_Zone_Methods_V2_Controller + */ +class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zone_Methods_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/includes/v3/class-wc-rest-shipping-zones-controller.php b/includes/v3/class-wc-rest-shipping-zones-controller.php new file mode 100644 index 00000000000..dd766a3291c --- /dev/null +++ b/includes/v3/class-wc-rest-shipping-zones-controller.php @@ -0,0 +1,27 @@ +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 identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check permissions. + * + * @param WP_REST_Request $request Full details about the request. + * @param string $context Request context. + * @return bool|WP_Error + */ + protected function check_permissions( $request, $context = 'read' ) { + // Get taxonomy. + $taxonomy = $this->get_taxonomy( $request ); + if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Check permissions for a single term. + $id = intval( $request['id'] ); + if ( $id ) { + $term = get_term( $id, $taxonomy ); + + if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { + return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + return current_user_can( 'edit_posts' ); + } + + /** + * Prepare a single product category output for response. + * + * @param WP_Term $item Term object. + * @param WP_REST_Request $request Request instance. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $item, $request ) { + // Get the attribute slug. + $attribute_id = absint( $request->get_param( 'attribute_id' ) ); + $attribute = wc_get_attribute( $attribute_id ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'count' => (int) $item->count, + 'attribute' => array( + 'id' => $attribute->id, + 'name' => $attribute->name, + 'slug' => $attribute->slug, + ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $raw_schema = parent::get_item_schema(); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_attribute_term', + 'type' => 'object', + 'properties' => array(), + ); + + $schema['properties']['id'] = $raw_schema['properties']['id']; + $schema['properties']['name'] = $raw_schema['properties']['name']; + $schema['properties']['slug'] = $raw_schema['properties']['slug']; + $schema['properties']['count'] = $raw_schema['properties']['count']; + $schema['properties']['attribute'] = array( + 'description' => __( 'Attribute.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Attribute slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php b/includes/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php new file mode 100644 index 00000000000..b2ef3606c96 --- /dev/null +++ b/includes/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php @@ -0,0 +1,188 @@ +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 identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check if a given request has access to read the attributes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! current_user_can( 'edit_posts' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + /** + * Check if a given request has access to read a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + + if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! current_user_can( 'edit_posts' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check permissions. + * + * @param WP_REST_Request $request Full details about the request. + * @param string $context Request context. + * @return bool|WP_Error + */ + protected function check_permissions( $request, $context = 'read' ) { + // Get taxonomy. + $taxonomy = $this->get_taxonomy( $request ); + if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Check permissions for a single term. + $id = intval( $request['id'] ); + if ( $id ) { + $term = get_term( $id, $taxonomy ); + + if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { + return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + return current_user_can( 'edit_posts' ); + } + + /** + * Prepare a single product category output for response. + * + * @param WP_Term $item Term object. + * @param WP_REST_Request $request Request instance. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $item, $request ) { + $taxonomy = wc_attribute_taxonomy_name( $item->attribute_name ); + $data = array( + 'id' => (int) $item->attribute_id, + 'name' => $item->attribute_label, + 'slug' => $taxonomy, + 'count' => wp_count_terms( $taxonomy ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); + $response->add_links( $this->prepare_links( $item ) ); + + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $raw_schema = parent::get_item_schema(); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_block_attribute', + 'type' => 'object', + 'properties' => array(), + ); + + $schema['properties']['id'] = $raw_schema['properties']['id']; + $schema['properties']['name'] = $raw_schema['properties']['name']; + $schema['properties']['slug'] = $raw_schema['properties']['slug']; + $schema['properties']['count'] = array( + 'description' => __( 'Number of terms in the attribute taxonomy.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/wc-blocks/class-wc-rest-blocks-product-categories-controller.php b/includes/wc-blocks/class-wc-rest-blocks-product-categories-controller.php new file mode 100644 index 00000000000..dd69428a50d --- /dev/null +++ b/includes/wc-blocks/class-wc-rest-blocks-product-categories-controller.php @@ -0,0 +1,151 @@ +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 identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check permissions. + * + * @param WP_REST_Request $request Full details about the request. + * @param string $context Request context. + * @return bool|WP_Error + */ + protected function check_permissions( $request, $context = 'read' ) { + // Get taxonomy. + $taxonomy = $this->get_taxonomy( $request ); + if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Check permissions for a single term. + $id = intval( $request['id'] ); + if ( $id ) { + $term = get_term( $id, $taxonomy ); + + if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { + return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + return current_user_can( 'edit_posts' ); + } + + /** + * Prepare a single product category output for response. + * + * @param WP_Term $item Term object. + * @param WP_REST_Request $request Request instance. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $item, $request ) { + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'parent' => (int) $item->parent, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); + + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $raw_schema = parent::get_item_schema(); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_block_category', + 'type' => 'object', + 'properties' => array(), + ); + + $schema['properties']['id'] = $raw_schema['properties']['id']; + $schema['properties']['name'] = $raw_schema['properties']['name']; + $schema['properties']['slug'] = $raw_schema['properties']['slug']; + $schema['properties']['parent'] = $raw_schema['properties']['parent']; + $schema['properties']['count'] = $raw_schema['properties']['count']; + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/includes/wc-blocks/class-wc-rest-blocks-products-controller.php b/includes/wc-blocks/class-wc-rest-blocks-products-controller.php new file mode 100644 index 00000000000..41cd9b7b629 --- /dev/null +++ b/includes/wc-blocks/class-wc-rest-blocks-products-controller.php @@ -0,0 +1,390 @@ +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 identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check if a given request has access to read items. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! current_user_can( 'edit_posts' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! current_user_can( 'edit_posts' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get a collection of posts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $query_args = $this->prepare_objects_query( $request ); + $query_results = $this->get_objects( $query_args ); + + $objects = array(); + foreach ( $query_results['objects'] as $object ) { + $data = $this->prepare_object_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 ); + $response->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); + + $base = $this->rest_base; + $attrib_prefix = '(?P<'; + if ( strpos( $base, $attrib_prefix ) !== false ) { + $attrib_names = array(); + preg_match( '/\(\?P<[^>]+>.*\)/', $base, $attrib_names, PREG_OFFSET_CAPTURE ); + foreach ( $attrib_names as $attrib_name_match ) { + $beginning_offset = strlen( $attrib_prefix ); + $attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] ); + $attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset ); + if ( isset( $request[ $attrib_name ] ) ) { + $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); + } + } + } + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $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; + } + + /** + * Get the images for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_images( $product ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( has_post_thumbnail( $product->get_id() ) ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + + return $images; + } + + /** + * Prepare a single product output for response. + * + * @deprecated 3.0.0 + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $post, $request ) { + $product = wc_get_product( $post ); + $data = $this->get_product_data( $product ); + + $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->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); + $response->add_links( $this->prepare_links( $product, $request ) ); + + return $response; + } + + /** + * Make extra product orderby features supported by WooCommerce available to the WC API. + * This includes 'price', 'popularity', and 'rating'. + * + * @param WP_REST_Request $request Request data. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + $operator_mapping = array( + 'in' => 'IN', + 'not_in' => 'NOT IN', + 'and' => 'AND', + ); + + $orderby = $request->get_param( 'orderby' ); + $order = $request->get_param( 'order' ); + $category_operator = $operator_mapping[ $request->get_param( 'category_operator' ) ]; + $attribute_operator = $operator_mapping[ $request->get_param( 'attribute_operator' ) ]; + $catalog_visibility = $request->get_param( 'catalog_visibility' ); + + $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); + $args['orderby'] = $ordering_args['orderby']; + $args['order'] = $ordering_args['order']; + if ( $ordering_args['meta_key'] ) { + $args['meta_key'] = $ordering_args['meta_key']; // WPCS: slow query ok. + } + + if ( $category_operator && isset( $args['tax_query'] ) ) { + foreach ( $args['tax_query'] as $i => $tax_query ) { + if ( 'product_cat' === $tax_query['taxonomy'] ) { + $args['tax_query'][ $i ]['operator'] = $category_operator; + $args['tax_query'][ $i ]['include_children'] = 'AND' === $category_operator ? false : true; + } + } + } + + if ( $attribute_operator && isset( $args['tax_query'] ) ) { + foreach ( $args['tax_query'] as $i => $tax_query ) { + if ( in_array( $tax_query['taxonomy'], wc_get_attribute_taxonomy_names(), true ) ) { + $args['tax_query'][ $i ]['operator'] = $attribute_operator; + } + } + } + + if ( in_array( $catalog_visibility, array_keys( wc_get_product_visibility_options() ), true ) ) { + $exclude_from_catalog = 'search' === $catalog_visibility ? '' : 'exclude-from-catalog'; + $exclude_from_search = 'catalog' === $catalog_visibility ? '' : 'exclude-from-search'; + + $args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => array( $exclude_from_catalog, $exclude_from_search ), + 'operator' => 'hidden' === $catalog_visibility ? 'AND' : 'NOT IN', + ); + } + + return $args; + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @param string $context Request context. + * Options: 'view' and 'edit'. + * @return array + */ + protected function get_product_data( $product, $context = 'view' ) { + $raw_data = parent::get_product_data( $product, $context ); + $data = array(); + + $data['id'] = $raw_data['id']; + $data['name'] = $raw_data['name']; + $data['permalink'] = $raw_data['permalink']; + $data['sku'] = $raw_data['sku']; + $data['description'] = $raw_data['description']; + $data['short_description'] = $raw_data['short_description']; + $data['price'] = $raw_data['price']; + $data['price_html'] = $raw_data['price_html']; + $data['images'] = $raw_data['images']; + $data['average_rating'] = $raw_data['average_rating']; + + return $data; + } + + /** + * Update the collection params. + * + * Adds new options for 'orderby', and new parameters 'category_operator', 'attribute_operator'. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating', 'menu_order' ) ); + $params['category_operator'] = array( + 'description' => __( 'Operator to compare product category terms.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'in', 'not_in', 'and' ), + 'default' => 'in', + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute_operator'] = array( + 'description' => __( 'Operator to compare product attribute terms.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'in', 'not_in', 'and' ), + 'default' => 'in', + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['catalog_visibility'] = array( + 'description' => __( 'Determines if hidden or visible catalog products are shown.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $raw_schema = parent::get_item_schema(); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_block_product', + 'type' => 'object', + 'properties' => array(), + ); + + $schema['properties']['id'] = $raw_schema['properties']['id']; + $schema['properties']['name'] = $raw_schema['properties']['name']; + $schema['properties']['permalink'] = $raw_schema['properties']['permalink']; + $schema['properties']['sku'] = $raw_schema['properties']['sku']; + $schema['properties']['description'] = $raw_schema['properties']['description']; + $schema['properties']['short_description'] = $raw_schema['properties']['short_description']; + $schema['properties']['price'] = $raw_schema['properties']['price']; + $schema['properties']['price_html'] = $raw_schema['properties']['price_html']; + $schema['properties']['average_rating'] = $raw_schema['properties']['average_rating']; + $schema['properties']['images'] = array( + 'description' => $raw_schema['properties']['images']['description'], + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array(), + ), + ); + + $images_schema = $raw_schema['properties']['images']['items']['properties']; + + $schema['properties']['images']['items']['properties']['id'] = $images_schema['id']; + $schema['properties']['images']['items']['properties']['src'] = $images_schema['src']; + $schema['properties']['images']['items']['properties']['name'] = $images_schema['name']; + $schema['properties']['images']['items']['properties']['alt'] = $images_schema['alt']; + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 00000000000..4932ea11140 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,50 @@ + + + WooCommerce dev PHP_CodeSniffer ruleset. + + + tests/cli/ + apigen/ + includes/libraries/ + includes/legacy/ + includes/api/legacy/ + includes/api/v1/ + includes/class-wc-geo-ip.php + includes/wc-deprecated-functions.php + */node_modules/* + */vendor/* + + + + + + + + + + + + + + + + tests/ + + + + includes/**/abstract-*.php + tests/* + + + + tests/ + + + + tests/e2e-tests/ + + + + i18n/ + + diff --git a/readme.txt b/readme.txt new file mode 100644 index 00000000000..1333ed77b7e --- /dev/null +++ b/readme.txt @@ -0,0 +1 @@ +TODO diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php new file mode 100644 index 00000000000..c6f91e7ef07 --- /dev/null +++ b/woocommerce-rest-api.php @@ -0,0 +1,41 @@ +init(); + } +} + +add_action( + 'woocommerce_loaded', + function() { + if ( is_callable( array( wc()->api, 'register' ) ) ) { + // @internal When bumping the version remember to update the function names below. + wc()->api->register( '1.1.0', 'wc_rest_api_1_dot_1_dot_0' ); + } + } +); From 6077ef0fd8bd46fc5f1a2fde3c1a985431c69243 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 10 May 2019 17:59:17 +0100 Subject: [PATCH 002/440] Tweak paths --- CHANGELOG.txt | 4 ---- includes/RestApi.php => RestApi.php | 16 ++++++++-------- woocommerce-rest-api.php | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) delete mode 100644 CHANGELOG.txt rename includes/RestApi.php => RestApi.php (84%) diff --git a/CHANGELOG.txt b/CHANGELOG.txt deleted file mode 100644 index 2edac50f70c..00000000000 --- a/CHANGELOG.txt +++ /dev/null @@ -1,4 +0,0 @@ -== Changelog == - -= 0.0.1 = -TODO diff --git a/includes/RestApi.php b/RestApi.php similarity index 84% rename from includes/RestApi.php rename to RestApi.php index 59d6bb9c93f..e0817eb89d2 100644 --- a/includes/RestApi.php +++ b/RestApi.php @@ -87,13 +87,13 @@ class RestApi { // Non-namespaced files. if ( stristr( $class, 'WC_REST_' ) ) { if ( stristr( $class, '_V1_' ) ) { - $dir = dirname( __FILE__ ) . '/v1/'; + $dir = dirname( __FILE__ ) . '/includes/v1/'; } elseif ( stristr( $class, '_V2_' ) ) { - $dir = dirname( __FILE__ ) . '/v2/'; + $dir = dirname( __FILE__ ) . '/includes/v2/'; } elseif ( stristr( $class, 'WC_REST_Blocks' ) ) { - $dir = dirname( __FILE__ ) . '/wc-blocks/'; + $dir = dirname( __FILE__ ) . '/includes/wc-blocks/'; } else { - $dir = dirname( __FILE__ ) . '/v3/'; + $dir = dirname( __FILE__ ) . '/includes/v3/'; } $file = $this->get_file_name_from_class( $class ); @@ -105,14 +105,14 @@ class RestApi { $file = $this->get_file_name_from_class( $class, 'abstract-' ); - if ( file_exists( dirname( __FILE__ ) . "/abstracts/{$file}" ) ) { - include dirname( __FILE__ ) . "/abstracts/{$file}"; + if ( file_exists( dirname( __FILE__ ) . "/includes/abstracts/{$file}" ) ) { + include dirname( __FILE__ ) . "/includes/abstracts/{$file}"; return; } } - if ( file_exists( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . "{$class}.php" ) ) { - include dirname( __FILE__ ) . DIRECTORY_SEPARATOR . "{$class}.php"; + if ( file_exists( dirname( __FILE__ ) . "/includes/{$class}.php" ) ) { + include dirname( __FILE__ ) . "/includes/{$class}.php"; return; } } diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index c6f91e7ef07..e82177b4ecf 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -25,7 +25,7 @@ if ( ! function_exists( 'wc_rest_api_1_dot_1_dot_0' ) ) { * @internal Never call manually - this function will change between versions. */ function wc_rest_api_1_dot_1_dot_0() { - require_once dirname( __FILE__ ) . '/includes/RestApi.php'; + require_once dirname( __FILE__ ) . '/RestApi.php'; \WC\RestAPI\RestApi::instance()->init(); } } From f5768bfd251c3569b6854df07e1d9e291d0df94c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 10 May 2019 23:33:12 +0100 Subject: [PATCH 003/440] Naming improvements --- README.md | 35 +++- RestApi.php | 146 -------------- includes/v1/class-wc-rest-api-v1.php | 75 ------- includes/v2/class-wc-rest-api-v2.php | 97 --------- includes/v3/class-wc-rest-api-v3.php | 113 ----------- .../wc-blocks/class-wc-rest-api-blocks-v1.php | 43 ---- phpcs.xml | 15 +- readme.txt | 1 - src/class-autoload.php | 75 +++++++ src/class-server.php | 184 ++++++++++++++++++ src/class-singleton.php | 51 +++++ .../class-wc-rest-controller.php | 0 .../class-wc-rest-crud-controller.php | 0 .../class-wc-rest-posts-controller.php | 0 ...wc-rest-shipping-zones-controller-base.php | 0 .../class-wc-rest-terms-controller.php | 0 .../class-wc-rest-coupons-v1-controller.php | 0 ...-rest-customer-downloads-v1-controller.php | 0 .../class-wc-rest-customers-v1-controller.php | 0 ...lass-wc-rest-order-notes-v1-controller.php | 0 ...ss-wc-rest-order-refunds-v1-controller.php | 0 .../v1/class-wc-rest-orders-v1-controller.php | 0 ...-product-attribute-terms-v1-controller.php | 0 ...-rest-product-attributes-v1-controller.php | 0 ...-rest-product-categories-v1-controller.php | 0 ...-wc-rest-product-reviews-v1-controller.php | 0 ...product-shipping-classes-v1-controller.php | 0 ...ass-wc-rest-product-tags-v1-controller.php | 0 .../class-wc-rest-products-v1-controller.php | 0 ...ass-wc-rest-report-sales-v1-controller.php | 0 ...-rest-report-top-sellers-v1-controller.php | 0 .../class-wc-rest-reports-v1-controller.php | 0 ...lass-wc-rest-tax-classes-v1-controller.php | 0 .../v1/class-wc-rest-taxes-v1-controller.php | 0 ...-rest-webhook-deliveries-v1-controller.php | 0 .../class-wc-rest-webhooks-v1-controller.php | 0 .../class-wc-rest-coupons-v2-controller.php | 0 ...-rest-customer-downloads-v2-controller.php | 0 .../class-wc-rest-customers-v2-controller.php | 0 ...s-wc-rest-network-orders-v2-controller.php | 0 ...lass-wc-rest-order-notes-v2-controller.php | 0 ...ss-wc-rest-order-refunds-v2-controller.php | 0 .../v2/class-wc-rest-orders-v2-controller.php | 0 ...wc-rest-payment-gateways-v2-controller.php | 0 ...-product-attribute-terms-v2-controller.php | 0 ...-rest-product-attributes-v2-controller.php | 0 ...-rest-product-categories-v2-controller.php | 0 ...-wc-rest-product-reviews-v2-controller.php | 0 ...product-shipping-classes-v2-controller.php | 0 ...ass-wc-rest-product-tags-v2-controller.php | 0 ...-rest-product-variations-v2-controller.php | 0 .../class-wc-rest-products-v2-controller.php | 0 ...ass-wc-rest-report-sales-v2-controller.php | 0 ...-rest-report-top-sellers-v2-controller.php | 0 .../class-wc-rest-reports-v2-controller.php | 0 ...-wc-rest-setting-options-v2-controller.php | 0 .../class-wc-rest-settings-v2-controller.php | 0 ...wc-rest-shipping-methods-v2-controller.php | 0 ...-shipping-zone-locations-v2-controller.php | 0 ...st-shipping-zone-methods-v2-controller.php | 0 ...s-wc-rest-shipping-zones-v2-controller.php | 0 ...rest-system-status-tools-v2-controller.php | 0 ...ss-wc-rest-system-status-v2-controller.php | 0 ...lass-wc-rest-tax-classes-v2-controller.php | 0 .../v2/class-wc-rest-taxes-v2-controller.php | 0 ...-rest-webhook-deliveries-v2-controller.php | 0 .../class-wc-rest-webhooks-v2-controller.php | 0 .../v3/class-wc-rest-coupons-controller.php | 0 ...-wc-rest-customer-downloads-controller.php | 0 .../v3/class-wc-rest-customers-controller.php | 0 ...ass-wc-rest-data-continents-controller.php | 0 .../v3/class-wc-rest-data-controller.php | 0 ...lass-wc-rest-data-countries-controller.php | 0 ...ass-wc-rest-data-currencies-controller.php | 0 ...lass-wc-rest-network-orders-controller.php | 0 .../class-wc-rest-order-notes-controller.php | 0 ...class-wc-rest-order-refunds-controller.php | 0 .../v3/class-wc-rest-orders-controller.php | 0 ...ss-wc-rest-payment-gateways-controller.php | 0 ...est-product-attribute-terms-controller.php | 0 ...-wc-rest-product-attributes-controller.php | 0 ...-wc-rest-product-categories-controller.php | 0 ...ass-wc-rest-product-reviews-controller.php | 0 ...st-product-shipping-classes-controller.php | 0 .../class-wc-rest-product-tags-controller.php | 0 ...-wc-rest-product-variations-controller.php | 0 .../v3/class-wc-rest-products-controller.php | 0 ...-rest-report-coupons-totals-controller.php | 0 ...est-report-customers-totals-controller.php | 0 ...c-rest-report-orders-totals-controller.php | 0 ...rest-report-products-totals-controller.php | 0 ...-rest-report-reviews-totals-controller.php | 0 .../class-wc-rest-report-sales-controller.php | 0 ...-wc-rest-report-top-sellers-controller.php | 0 .../v3/class-wc-rest-reports-controller.php | 0 ...ass-wc-rest-setting-options-controller.php | 0 .../v3/class-wc-rest-settings-controller.php | 0 ...ss-wc-rest-shipping-methods-controller.php | 0 ...est-shipping-zone-locations-controller.php | 0 ...-rest-shipping-zone-methods-controller.php | 0 ...lass-wc-rest-shipping-zones-controller.php | 0 ...class-wc-rest-system-status-controller.php | 0 ...wc-rest-system-status-tools-controller.php | 0 .../class-wc-rest-tax-classes-controller.php | 0 .../v3/class-wc-rest-taxes-controller.php | 0 .../v3/class-wc-rest-webhooks-controller.php | 0 ...cks-product-attribute-terms-controller.php | 0 ...t-blocks-product-attributes-controller.php | 0 ...t-blocks-product-categories-controller.php | 0 ...ass-wc-rest-blocks-products-controller.php | 0 woocommerce-rest-api.php | 12 +- 111 files changed, 352 insertions(+), 495 deletions(-) delete mode 100644 RestApi.php delete mode 100644 includes/v1/class-wc-rest-api-v1.php delete mode 100644 includes/v2/class-wc-rest-api-v2.php delete mode 100644 includes/v3/class-wc-rest-api-v3.php delete mode 100644 includes/wc-blocks/class-wc-rest-api-blocks-v1.php delete mode 100644 readme.txt create mode 100644 src/class-autoload.php create mode 100644 src/class-server.php create mode 100644 src/class-singleton.php rename includes/abstracts/abstract-wc-rest-controller.php => src/class-wc-rest-controller.php (100%) rename includes/abstracts/abstract-wc-rest-crud-controller.php => src/class-wc-rest-crud-controller.php (100%) rename includes/abstracts/abstract-wc-rest-posts-controller.php => src/class-wc-rest-posts-controller.php (100%) rename includes/abstracts/abstract-wc-rest-shipping-zones-controller.php => src/class-wc-rest-shipping-zones-controller-base.php (100%) rename includes/abstracts/abstract-wc-rest-terms-controller.php => src/class-wc-rest-terms-controller.php (100%) rename {includes => src}/v1/class-wc-rest-coupons-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-customer-downloads-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-customers-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-order-notes-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-order-refunds-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-orders-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-product-attribute-terms-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-product-attributes-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-product-categories-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-product-reviews-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-product-shipping-classes-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-product-tags-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-products-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-report-sales-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-report-top-sellers-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-reports-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-tax-classes-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-taxes-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-webhook-deliveries-v1-controller.php (100%) rename {includes => src}/v1/class-wc-rest-webhooks-v1-controller.php (100%) rename {includes => src}/v2/class-wc-rest-coupons-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-customer-downloads-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-customers-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-network-orders-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-order-notes-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-order-refunds-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-orders-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-payment-gateways-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-product-attribute-terms-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-product-attributes-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-product-categories-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-product-reviews-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-product-shipping-classes-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-product-tags-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-product-variations-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-products-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-report-sales-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-report-top-sellers-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-reports-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-setting-options-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-settings-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-shipping-methods-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-shipping-zone-locations-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-shipping-zone-methods-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-shipping-zones-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-system-status-tools-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-system-status-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-tax-classes-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-taxes-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-webhook-deliveries-v2-controller.php (100%) rename {includes => src}/v2/class-wc-rest-webhooks-v2-controller.php (100%) rename {includes => src}/v3/class-wc-rest-coupons-controller.php (100%) rename {includes => src}/v3/class-wc-rest-customer-downloads-controller.php (100%) rename {includes => src}/v3/class-wc-rest-customers-controller.php (100%) rename {includes => src}/v3/class-wc-rest-data-continents-controller.php (100%) rename {includes => src}/v3/class-wc-rest-data-controller.php (100%) rename {includes => src}/v3/class-wc-rest-data-countries-controller.php (100%) rename {includes => src}/v3/class-wc-rest-data-currencies-controller.php (100%) rename {includes => src}/v3/class-wc-rest-network-orders-controller.php (100%) rename {includes => src}/v3/class-wc-rest-order-notes-controller.php (100%) rename {includes => src}/v3/class-wc-rest-order-refunds-controller.php (100%) rename {includes => src}/v3/class-wc-rest-orders-controller.php (100%) rename {includes => src}/v3/class-wc-rest-payment-gateways-controller.php (100%) rename {includes => src}/v3/class-wc-rest-product-attribute-terms-controller.php (100%) rename {includes => src}/v3/class-wc-rest-product-attributes-controller.php (100%) rename {includes => src}/v3/class-wc-rest-product-categories-controller.php (100%) rename {includes => src}/v3/class-wc-rest-product-reviews-controller.php (100%) rename {includes => src}/v3/class-wc-rest-product-shipping-classes-controller.php (100%) rename {includes => src}/v3/class-wc-rest-product-tags-controller.php (100%) rename {includes => src}/v3/class-wc-rest-product-variations-controller.php (100%) rename {includes => src}/v3/class-wc-rest-products-controller.php (100%) rename {includes => src}/v3/class-wc-rest-report-coupons-totals-controller.php (100%) rename {includes => src}/v3/class-wc-rest-report-customers-totals-controller.php (100%) rename {includes => src}/v3/class-wc-rest-report-orders-totals-controller.php (100%) rename {includes => src}/v3/class-wc-rest-report-products-totals-controller.php (100%) rename {includes => src}/v3/class-wc-rest-report-reviews-totals-controller.php (100%) rename {includes => src}/v3/class-wc-rest-report-sales-controller.php (100%) rename {includes => src}/v3/class-wc-rest-report-top-sellers-controller.php (100%) rename {includes => src}/v3/class-wc-rest-reports-controller.php (100%) rename {includes => src}/v3/class-wc-rest-setting-options-controller.php (100%) rename {includes => src}/v3/class-wc-rest-settings-controller.php (100%) rename {includes => src}/v3/class-wc-rest-shipping-methods-controller.php (100%) rename {includes => src}/v3/class-wc-rest-shipping-zone-locations-controller.php (100%) rename {includes => src}/v3/class-wc-rest-shipping-zone-methods-controller.php (100%) rename {includes => src}/v3/class-wc-rest-shipping-zones-controller.php (100%) rename {includes => src}/v3/class-wc-rest-system-status-controller.php (100%) rename {includes => src}/v3/class-wc-rest-system-status-tools-controller.php (100%) rename {includes => src}/v3/class-wc-rest-tax-classes-controller.php (100%) rename {includes => src}/v3/class-wc-rest-taxes-controller.php (100%) rename {includes => src}/v3/class-wc-rest-webhooks-controller.php (100%) rename {includes => src}/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php (100%) rename {includes => src}/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php (100%) rename {includes => src}/wc-blocks/class-wc-rest-blocks-product-categories-controller.php (100%) rename {includes => src}/wc-blocks/class-wc-rest-blocks-products-controller.php (100%) diff --git a/README.md b/README.md index 1333ed77b7e..dd792585a9c 100644 --- a/README.md +++ b/README.md @@ -1 +1,34 @@ -TODO +--- +title: 'WooCommerce REST API' +--- + +WooCommerce REST API +=== + +This repository houses the WooCommerce REST API found in the core WooCommerce plugin. + +It can also be used as a standalone plugin (it still requires WooCommerce!), or can be pulled into other projects and feature plugins that need new API features that are not yet in the core release. + +Once stable, changes in woocommerce-rest-api are brought over to [WooCommerce core](https://github.com/woocommerce/woocommerce) when they are ready for release. + +## Endpoint namespaces + +* Current stable WC REST API version: **wc/v3** - **[Docs](https://woocommerce.github.io/woocommerce-rest-api-docs/)** +* WC Blocks REST API version (internal use only): **wc-blocks/v1** +* Older versions: + * **wc/v1** - **[Docs](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v1.html)** + * **wc/v2** - **[Docs](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v2.html)** + +## Contributing + +Please read the [WooCommerce contributor guidelines](https://github.com/woocommerce/woocommerce/blob/master/.github/CONTRIBUTING.md) for more information how you can contribute. + +Endpoints are located in the `includes/` directory. Endpoints currently inherit from the stable version of the endpoint. If you need to change the behavior of an endpoint, you can do so in these classes. + +phpunit tests for the API are located in the `tests/unit-tests/` folder and are also merged and shipped with WooCommerce core. You can use the same helpers/framework files that core uses, or introduce new ones. + +Run tests using `phpunit` in the root of this folder. Code coverage reports can be ran with `phpunit --coverage-html /tmp/coverage`. + +## Translation + +For strings located in API endpoints, use `woocommerce` as your text-domain. These endpoints will at some point be merged back into WooCommerce Core. diff --git a/RestApi.php b/RestApi.php deleted file mode 100644 index e0817eb89d2..00000000000 --- a/RestApi.php +++ /dev/null @@ -1,146 +0,0 @@ -get_file_name_from_class( $class ); - - if ( file_exists( "{$dir}{$file}" ) ) { - include "{$dir}{$file}"; - return; - } - - $file = $this->get_file_name_from_class( $class, 'abstract-' ); - - if ( file_exists( dirname( __FILE__ ) . "/includes/abstracts/{$file}" ) ) { - include dirname( __FILE__ ) . "/includes/abstracts/{$file}"; - return; - } - } - - if ( file_exists( dirname( __FILE__ ) . "/includes/{$class}.php" ) ) { - include dirname( __FILE__ ) . "/includes/{$class}.php"; - return; - } - } - - /** - * Get API namespaces. - */ - protected function get_namespaces() { - return array( - 'wc/v1' => 'WC_Rest_API_V1', - 'wc/v2' => 'WC_Rest_API_V2', - 'wc/v3' => 'WC_Rest_API_V3', - 'wc-blocks/v1' => 'WC_Rest_API_Blocks_V1', - ); - } - - /** - * Register REST API routes. - */ - public function register_rest_routes() { - foreach ( $this->get_namespaces() as $namespace => $classname ) { - $api = new $classname(); - $api->includes(); - - foreach ( $api->get_controllers() as $controller ) { - $this->$controller = new $controller(); - $this->$controller->register_routes(); - } - } - } -} diff --git a/includes/v1/class-wc-rest-api-v1.php b/includes/v1/class-wc-rest-api-v1.php deleted file mode 100644 index b5038186261..00000000000 --- a/includes/v1/class-wc-rest-api-v1.php +++ /dev/null @@ -1,75 +0,0 @@ -WooCommerce dev PHP_CodeSniffer ruleset. - tests/cli/ + tests/ apigen/ - includes/libraries/ - includes/legacy/ - includes/api/legacy/ - includes/api/v1/ - includes/class-wc-geo-ip.php - includes/wc-deprecated-functions.php */node_modules/* */vendor/* - + @@ -32,7 +26,6 @@ - includes/**/abstract-*.php tests/* @@ -40,10 +33,6 @@ tests/ - - tests/e2e-tests/ - - i18n/ diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 1333ed77b7e..00000000000 --- a/readme.txt +++ /dev/null @@ -1 +0,0 @@ -TODO diff --git a/src/class-autoload.php b/src/class-autoload.php new file mode 100644 index 00000000000..8c0c2d1ab72 --- /dev/null +++ b/src/class-autoload.php @@ -0,0 +1,75 @@ +get_file_name_from_class( $class ); + $dir = trailingslashit( dirname( __FILE__ ) ); + + // Non-namespaced files. + if ( stristr( $class, 'WC_REST_' ) ) { + if ( stristr( $class, 'WC_REST_Blocks' ) ) { + $subdir = 'wc-blocks/'; + } elseif ( stristr( $class, '_V1_' ) ) { + $subdir = 'v1/'; + } elseif ( stristr( $class, '_V2_' ) ) { + $subdir = 'v2/'; + } else { + $subdir = 'v3/'; + } + + if ( file_exists( $dir . $subdir . $file ) ) { + include $dir . $subdir . $file; + return; + } + } + + if ( file_exists( $dir . $class . '.php' ) ) { + include $dir . $class . '.php'; + return; + } + + if ( file_exists( $dir . $file ) ) { + include $dir . $file; + return; + } + } +} diff --git a/src/class-server.php b/src/class-server.php new file mode 100644 index 00000000000..da232e7475c --- /dev/null +++ b/src/class-server.php @@ -0,0 +1,184 @@ +init(); + add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); + } + + /** + * Register REST API routes. + */ + public function register_rest_routes() { + foreach ( $this->get_namespaces() as $namespace ) { + $this->endpoints[ $namespace ] = array(); + + foreach ( $this->get_controllers( $namespace ) as $name => $class ) { + $this->endpoints[ $namespace ][ $class ] = new $class(); + $this->endpoints[ $namespace ][ $class ]->register_routes(); + } + } + } + + /** + * Get API namespaces - new namespaces should be registered here. + * + * @return array + */ + protected function get_namespaces() { + return array( + 'wc/v1', + 'wc/v2', + 'wc/v3', + 'wc-blocks/v1', + ); + } + + /** + * Get API controllers - new controllers/endpoints should be registered here. + * + * @param string $namespace Namespace to get controllers for. + * @return array + */ + protected function get_controllers( $namespace ) { + switch ( $namespace ) { + case 'wc/v1': + return array( + 'WC_REST_Coupons_V1_Controller', + 'WC_REST_Customer_Downloads_V1_Controller', + 'WC_REST_Customers_V1_Controller', + 'WC_REST_Order_Notes_V1_Controller', + 'WC_REST_Order_Refunds_V1_Controller', + 'WC_REST_Orders_V1_Controller', + 'WC_REST_Product_Attribute_Terms_V1_Controller', + 'WC_REST_Product_Attributes_V1_Controller', + 'WC_REST_Product_Categories_V1_Controller', + 'WC_REST_Product_Reviews_V1_Controller', + 'WC_REST_Product_Shipping_Classes_V1_Controller', + 'WC_REST_Product_Tags_V1_Controller', + 'WC_REST_Products_V1_Controller', + 'WC_REST_Report_Sales_V1_Controller', + 'WC_REST_Report_Top_Sellers_V1_Controller', + 'WC_REST_Reports_V1_Controller', + 'WC_REST_Tax_Classes_V1_Controller', + 'WC_REST_Taxes_V1_Controller', + 'WC_REST_Webhook_Deliveries_V1_Controller', + 'WC_REST_Webhooks_V1_Controller', + ); + case 'wc/v2': + return array( + 'WC_REST_Coupons_V2_Controller', + 'WC_REST_Customer_Downloads_V2_Controller', + 'WC_REST_Customers_V2_Controller', + 'WC_REST_Network_Orders_V2_Controller', + 'WC_REST_Order_Notes_V2_Controller', + 'WC_REST_Order_Refunds_V2_Controller', + 'WC_REST_Orders_V2_Controller', + 'WC_REST_Product_Attribute_Terms_V2_Controller', + 'WC_REST_Product_Attributes_V2_Controller', + 'WC_REST_Product_Categories_V2_Controller', + 'WC_REST_Product_Reviews_V2_Controller', + 'WC_REST_Product_Shipping_Classes_V2_Controller', + 'WC_REST_Product_Tags_V2_Controller', + 'WC_REST_Products_V2_Controller', + 'WC_REST_Product_Variations_V2_Controller', + 'WC_REST_Report_Sales_V2_Controller', + 'WC_REST_Report_Top_Sellers_V2_Controller', + 'WC_REST_Reports_V2_Controller', + 'WC_REST_Settings_V2_Controller', + 'WC_REST_Setting_Options_V2_Controller', + 'WC_REST_Shipping_Zones_V2_Controller', + 'WC_REST_Shipping_Zone_Locations_V2_Controller', + 'WC_REST_Shipping_Zone_Methods_V2_Controller', + 'WC_REST_Tax_Classes_V2_Controller', + 'WC_REST_Taxes_V2_Controller', + 'WC_REST_Webhook_Deliveries_V2_Controller', + 'WC_REST_Webhooks_V2_Controller', + 'WC_REST_System_Status_V2_Controller', + 'WC_REST_System_Status_Tools_V2_Controller', + 'WC_REST_Shipping_Methods_V2_Controller', + 'WC_REST_Payment_Gateways_V2_Controller', + ); + case 'wc/v3': + return array( + 'WC_REST_Coupons_Controller', + 'WC_REST_Customer_Downloads_Controller', + 'WC_REST_Customers_Controller', + 'WC_REST_Network_Orders_Controller', + 'WC_REST_Order_Notes_Controller', + 'WC_REST_Order_Refunds_Controller', + 'WC_REST_Orders_Controller', + 'WC_REST_Product_Attribute_Terms_Controller', + 'WC_REST_Product_Attributes_Controller', + 'WC_REST_Product_Categories_Controller', + 'WC_REST_Product_Reviews_Controller', + 'WC_REST_Product_Shipping_Classes_Controller', + 'WC_REST_Product_Tags_Controller', + 'WC_REST_Products_Controller', + 'WC_REST_Product_Variations_Controller', + 'WC_REST_Report_Sales_Controller', + 'WC_REST_Report_Top_Sellers_Controller', + 'WC_REST_Report_Orders_Totals_Controller', + 'WC_REST_Report_Products_Totals_Controller', + 'WC_REST_Report_Customers_Totals_Controller', + 'WC_REST_Report_Coupons_Totals_Controller', + 'WC_REST_Report_Reviews_Totals_Controller', + 'WC_REST_Reports_Controller', + 'WC_REST_Settings_Controller', + 'WC_REST_Setting_Options_Controller', + 'WC_REST_Shipping_Zones_Controller', + 'WC_REST_Shipping_Zone_Locations_Controller', + 'WC_REST_Shipping_Zone_Methods_Controller', + 'WC_REST_Tax_Classes_Controller', + 'WC_REST_Taxes_Controller', + 'WC_REST_Webhooks_Controller', + 'WC_REST_System_Status_Controller', + 'WC_REST_System_Status_Tools_Controller', + 'WC_REST_Shipping_Methods_Controller', + 'WC_REST_Payment_Gateways_Controller', + 'WC_REST_Data_Controller', + 'WC_REST_Data_Continents_Controller', + 'WC_REST_Data_Countries_Controller', + 'WC_REST_Data_Currencies_Controller', + ); + case 'wc-blocks/v1': + return array( + 'WC_REST_Blocks_Product_Attributes_Controller', + 'WC_REST_Blocks_Product_Attribute_Terms_Controller', + 'WC_REST_Blocks_Product_Categories_Controller', + 'WC_REST_Blocks_Products_Controller', + ); + } + return array(); + } +} diff --git a/src/class-singleton.php b/src/class-singleton.php new file mode 100644 index 00000000000..73a7c4f72c6 --- /dev/null +++ b/src/class-singleton.php @@ -0,0 +1,51 @@ +init(); + function wc_rest_api_1_dot_0_dot_0_dev() { + require_once dirname( __FILE__ ) . '/src/class-server.php'; + \WooCommerce\Rest_Api\Server::instance()->init(); } } @@ -35,7 +35,7 @@ add_action( function() { if ( is_callable( array( wc()->api, 'register' ) ) ) { // @internal When bumping the version remember to update the function names below. - wc()->api->register( '1.1.0', 'wc_rest_api_1_dot_1_dot_0' ); + wc()->api->register( '1.1.0', 'wc_rest_api_1_dot_0_dot_0_dev' ); } } ); From adc17a6b24070f1e3fd4eb3cb4afe681cef0fdcf Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 10 May 2019 23:33:31 +0100 Subject: [PATCH 004/440] Bump php requirement --- woocommerce-rest-api.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 5f7b287c401..52b681d0757 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -6,7 +6,7 @@ * Author: Automattic * Author URI: https://woocommerce.com * Version: 1.0.0-dev - * Requires PHP: 5.3 + * Requires PHP: 5.6 * License: GPLv3 * * @package WooCommerce/RestAPI @@ -14,7 +14,7 @@ defined( 'ABSPATH' ) || exit; -if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) { +if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) { return; } From 237d80f3f2e8abaf2bbb3c844bdc2a265cf4b367 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 May 2019 13:24:03 +0100 Subject: [PATCH 005/440] Implement autoloader with psr-4 class naming --- composer.json | 15 ++++ src/{class-server.php => RestApi.php} | 51 ++++++------- .../class-wc-rest-coupons-v1-controller.php | 4 +- ...-rest-customer-downloads-v1-controller.php | 4 +- .../class-wc-rest-customers-v1-controller.php | 4 +- ...lass-wc-rest-order-notes-v1-controller.php | 4 +- ...ss-wc-rest-order-refunds-v1-controller.php | 4 +- .../class-wc-rest-orders-v1-controller.php | 4 +- ...-product-attribute-terms-v1-controller.php | 4 +- ...-rest-product-attributes-v1-controller.php | 4 +- ...-rest-product-categories-v1-controller.php | 4 +- ...-wc-rest-product-reviews-v1-controller.php | 4 +- ...product-shipping-classes-v1-controller.php | 4 +- ...ass-wc-rest-product-tags-v1-controller.php | 4 +- .../class-wc-rest-products-v1-controller.php | 4 +- ...ass-wc-rest-report-sales-v1-controller.php | 4 +- ...-rest-report-top-sellers-v1-controller.php | 4 +- .../class-wc-rest-reports-v1-controller.php | 4 +- ...lass-wc-rest-tax-classes-v1-controller.php | 4 +- .../V1}/class-wc-rest-taxes-v1-controller.php | 4 +- ...-rest-webhook-deliveries-v1-controller.php | 4 +- .../class-wc-rest-webhooks-v1-controller.php | 4 +- .../class-wc-rest-coupons-v2-controller.php | 4 +- ...-rest-customer-downloads-v2-controller.php | 4 +- .../class-wc-rest-customers-v2-controller.php | 4 +- ...s-wc-rest-network-orders-v2-controller.php | 4 +- ...lass-wc-rest-order-notes-v2-controller.php | 4 +- ...ss-wc-rest-order-refunds-v2-controller.php | 4 +- .../class-wc-rest-orders-v2-controller.php | 4 +- ...wc-rest-payment-gateways-v2-controller.php | 4 +- ...-product-attribute-terms-v2-controller.php | 4 +- ...-rest-product-attributes-v2-controller.php | 4 +- ...-rest-product-categories-v2-controller.php | 4 +- ...-wc-rest-product-reviews-v2-controller.php | 4 +- ...product-shipping-classes-v2-controller.php | 4 +- ...ass-wc-rest-product-tags-v2-controller.php | 4 +- ...-rest-product-variations-v2-controller.php | 4 +- .../class-wc-rest-products-v2-controller.php | 4 +- ...ass-wc-rest-report-sales-v2-controller.php | 4 +- ...-rest-report-top-sellers-v2-controller.php | 4 +- .../class-wc-rest-reports-v2-controller.php | 4 +- ...-wc-rest-setting-options-v2-controller.php | 4 +- .../class-wc-rest-settings-v2-controller.php | 4 +- ...wc-rest-shipping-methods-v2-controller.php | 4 +- ...-shipping-zone-locations-v2-controller.php | 4 +- ...st-shipping-zone-methods-v2-controller.php | 4 +- ...s-wc-rest-shipping-zones-v2-controller.php | 4 +- ...rest-system-status-tools-v2-controller.php | 4 +- ...ss-wc-rest-system-status-v2-controller.php | 4 +- ...lass-wc-rest-tax-classes-v2-controller.php | 4 +- .../V2}/class-wc-rest-taxes-v2-controller.php | 4 +- ...-rest-webhook-deliveries-v2-controller.php | 4 +- .../class-wc-rest-webhooks-v2-controller.php | 4 +- .../V3}/class-wc-rest-controller.php | 4 +- .../V3}/class-wc-rest-coupons-controller.php | 4 +- .../V3}/class-wc-rest-crud-controller.php | 2 +- ...-wc-rest-customer-downloads-controller.php | 4 +- .../class-wc-rest-customers-controller.php | 4 +- ...ass-wc-rest-data-continents-controller.php | 4 +- .../V3}/class-wc-rest-data-controller.php | 4 +- ...lass-wc-rest-data-countries-controller.php | 4 +- ...ass-wc-rest-data-currencies-controller.php | 4 +- ...lass-wc-rest-network-orders-controller.php | 4 +- .../class-wc-rest-order-notes-controller.php | 4 +- ...class-wc-rest-order-refunds-controller.php | 4 +- .../V3}/class-wc-rest-orders-controller.php | 4 +- ...ss-wc-rest-payment-gateways-controller.php | 4 +- .../V3}/class-wc-rest-posts-controller.php | 4 +- ...est-product-attribute-terms-controller.php | 4 +- ...-wc-rest-product-attributes-controller.php | 4 +- ...-wc-rest-product-categories-controller.php | 4 +- ...ass-wc-rest-product-reviews-controller.php | 4 +- ...st-product-shipping-classes-controller.php | 4 +- .../class-wc-rest-product-tags-controller.php | 4 +- ...-wc-rest-product-variations-controller.php | 4 +- .../V3}/class-wc-rest-products-controller.php | 4 +- ...-rest-report-coupons-totals-controller.php | 4 +- ...est-report-customers-totals-controller.php | 4 +- ...c-rest-report-orders-totals-controller.php | 4 +- ...rest-report-products-totals-controller.php | 4 +- ...-rest-report-reviews-totals-controller.php | 4 +- .../class-wc-rest-report-sales-controller.php | 4 +- ...-wc-rest-report-top-sellers-controller.php | 4 +- .../V3}/class-wc-rest-reports-controller.php | 4 +- ...ass-wc-rest-setting-options-controller.php | 4 +- .../V3}/class-wc-rest-settings-controller.php | 4 +- ...ss-wc-rest-shipping-methods-controller.php | 4 +- ...est-shipping-zone-locations-controller.php | 4 +- ...-rest-shipping-zone-methods-controller.php | 4 +- ...wc-rest-shipping-zones-controller-base.php | 4 +- ...lass-wc-rest-shipping-zones-controller.php | 4 +- ...class-wc-rest-system-status-controller.php | 4 +- ...wc-rest-system-status-tools-controller.php | 4 +- .../class-wc-rest-tax-classes-controller.php | 4 +- .../V3}/class-wc-rest-taxes-controller.php | 4 +- .../V3}/class-wc-rest-terms-controller.php | 2 +- .../V3}/class-wc-rest-webhooks-controller.php | 4 +- ...cks-product-attribute-terms-controller.php | 4 +- ...t-blocks-product-attributes-controller.php | 4 +- ...t-blocks-product-categories-controller.php | 4 +- ...ass-wc-rest-blocks-products-controller.php | 4 +- .../SingletonTrait.php} | 6 +- src/class-autoload.php | 75 ------------------- woocommerce-rest-api.php | 45 ++++++----- 104 files changed, 262 insertions(+), 322 deletions(-) create mode 100644 composer.json rename src/{class-server.php => RestApi.php} (86%) rename src/{v1 => RestApi/V1}/class-wc-rest-coupons-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-customer-downloads-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-customers-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-order-notes-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-order-refunds-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-orders-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-product-attribute-terms-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-product-attributes-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-product-categories-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-product-reviews-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-product-shipping-classes-v1-controller.php (98%) rename src/{v1 => RestApi/V1}/class-wc-rest-product-tags-v1-controller.php (98%) rename src/{v1 => RestApi/V1}/class-wc-rest-products-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-report-sales-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-report-top-sellers-v1-controller.php (98%) rename src/{v1 => RestApi/V1}/class-wc-rest-reports-v1-controller.php (98%) rename src/{v1 => RestApi/V1}/class-wc-rest-tax-classes-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-taxes-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-webhook-deliveries-v1-controller.php (99%) rename src/{v1 => RestApi/V1}/class-wc-rest-webhooks-v1-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-coupons-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-customer-downloads-v2-controller.php (98%) rename src/{v2 => RestApi/V2}/class-wc-rest-customers-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-network-orders-v2-controller.php (98%) rename src/{v2 => RestApi/V2}/class-wc-rest-order-notes-v2-controller.php (98%) rename src/{v2 => RestApi/V2}/class-wc-rest-order-refunds-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-orders-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-payment-gateways-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-product-attribute-terms-v2-controller.php (88%) rename src/{v2 => RestApi/V2}/class-wc-rest-product-attributes-v2-controller.php (88%) rename src/{v2 => RestApi/V2}/class-wc-rest-product-categories-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-product-reviews-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-product-shipping-classes-v2-controller.php (88%) rename src/{v2 => RestApi/V2}/class-wc-rest-product-tags-v2-controller.php (87%) rename src/{v2 => RestApi/V2}/class-wc-rest-product-variations-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-products-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-report-sales-v2-controller.php (87%) rename src/{v2 => RestApi/V2}/class-wc-rest-report-top-sellers-v2-controller.php (87%) rename src/{v2 => RestApi/V2}/class-wc-rest-reports-v2-controller.php (86%) rename src/{v2 => RestApi/V2}/class-wc-rest-setting-options-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-settings-v2-controller.php (98%) rename src/{v2 => RestApi/V2}/class-wc-rest-shipping-methods-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-shipping-zone-locations-v2-controller.php (98%) rename src/{v2 => RestApi/V2}/class-wc-rest-shipping-zone-methods-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-shipping-zones-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-system-status-tools-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-system-status-v2-controller.php (99%) rename src/{v2 => RestApi/V2}/class-wc-rest-tax-classes-v2-controller.php (87%) rename src/{v2 => RestApi/V2}/class-wc-rest-taxes-v2-controller.php (85%) rename src/{v2 => RestApi/V2}/class-wc-rest-webhook-deliveries-v2-controller.php (98%) rename src/{v2 => RestApi/V2}/class-wc-rest-webhooks-v2-controller.php (98%) rename src/{ => RestApi/V3}/class-wc-rest-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-coupons-controller.php (86%) rename src/{ => RestApi/V3}/class-wc-rest-crud-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-customer-downloads-controller.php (88%) rename src/{v3 => RestApi/V3}/class-wc-rest-customers-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-data-continents-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-data-controller.php (98%) rename src/{v3 => RestApi/V3}/class-wc-rest-data-countries-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-data-currencies-controller.php (98%) rename src/{v3 => RestApi/V3}/class-wc-rest-network-orders-controller.php (87%) rename src/{v3 => RestApi/V3}/class-wc-rest-order-notes-controller.php (98%) rename src/{v3 => RestApi/V3}/class-wc-rest-order-refunds-controller.php (97%) rename src/{v3 => RestApi/V3}/class-wc-rest-orders-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-payment-gateways-controller.php (99%) rename src/{ => RestApi/V3}/class-wc-rest-posts-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-product-attribute-terms-controller.php (88%) rename src/{v3 => RestApi/V3}/class-wc-rest-product-attributes-controller.php (87%) rename src/{v3 => RestApi/V3}/class-wc-rest-product-categories-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-product-reviews-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-product-shipping-classes-controller.php (88%) rename src/{v3 => RestApi/V3}/class-wc-rest-product-tags-controller.php (87%) rename src/{v3 => RestApi/V3}/class-wc-rest-product-variations-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-products-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-report-coupons-totals-controller.php (98%) rename src/{v3 => RestApi/V3}/class-wc-rest-report-customers-totals-controller.php (98%) rename src/{v3 => RestApi/V3}/class-wc-rest-report-orders-totals-controller.php (97%) rename src/{v3 => RestApi/V3}/class-wc-rest-report-products-totals-controller.php (98%) rename src/{v3 => RestApi/V3}/class-wc-rest-report-reviews-totals-controller.php (98%) rename src/{v3 => RestApi/V3}/class-wc-rest-report-sales-controller.php (86%) rename src/{v3 => RestApi/V3}/class-wc-rest-report-top-sellers-controller.php (87%) rename src/{v3 => RestApi/V3}/class-wc-rest-reports-controller.php (96%) rename src/{v3 => RestApi/V3}/class-wc-rest-setting-options-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-settings-controller.php (97%) rename src/{v3 => RestApi/V3}/class-wc-rest-shipping-methods-controller.php (87%) rename src/{v3 => RestApi/V3}/class-wc-rest-shipping-zone-locations-controller.php (88%) rename src/{v3 => RestApi/V3}/class-wc-rest-shipping-zone-methods-controller.php (88%) rename src/{ => RestApi/V3}/class-wc-rest-shipping-zones-controller-base.php (98%) rename src/{v3 => RestApi/V3}/class-wc-rest-shipping-zones-controller.php (87%) rename src/{v3 => RestApi/V3}/class-wc-rest-system-status-controller.php (87%) rename src/{v3 => RestApi/V3}/class-wc-rest-system-status-tools-controller.php (87%) rename src/{v3 => RestApi/V3}/class-wc-rest-tax-classes-controller.php (86%) rename src/{v3 => RestApi/V3}/class-wc-rest-taxes-controller.php (85%) rename src/{ => RestApi/V3}/class-wc-rest-terms-controller.php (99%) rename src/{v3 => RestApi/V3}/class-wc-rest-webhooks-controller.php (89%) rename src/{ => RestApi}/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php (98%) rename src/{ => RestApi}/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php (98%) rename src/{ => RestApi}/wc-blocks/class-wc-rest-blocks-product-categories-controller.php (98%) rename src/{ => RestApi}/wc-blocks/class-wc-rest-blocks-products-controller.php (99%) rename src/{class-singleton.php => Utilities/SingletonTrait.php} (87%) delete mode 100644 src/class-autoload.php diff --git a/composer.json b/composer.json new file mode 100644 index 00000000000..422c98a48a4 --- /dev/null +++ b/composer.json @@ -0,0 +1,15 @@ +{ + "name": "woocommerce/rest-api", + "description": "The WooCommerce core REST API.", + "homepage": "https://github.com/woocommerce/woocommerce-rest-api", + "type": "wordpress-plugin", + "license": "GPL-3.0-or-later", + "prefer-stable": true, + "minimum-stability": "dev", + "autoload": { + "psr-4": { + "WooCommerce\\": "src/" + }, + "classmap": ["src/RestApi/V1", "src/RestApi/V2", "src/RestApi/V3", "src/RestApi/wc-blocks"] + } +} diff --git a/src/class-server.php b/src/RestApi.php similarity index 86% rename from src/class-server.php rename to src/RestApi.php index da232e7475c..1720f68c210 100644 --- a/src/class-server.php +++ b/src/RestApi.php @@ -1,38 +1,33 @@ init(); add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); } @@ -40,10 +35,10 @@ class Server { * Register REST API routes. */ public function register_rest_routes() { - foreach ( $this->get_namespaces() as $namespace ) { - $this->endpoints[ $namespace ] = array(); + foreach ( $this->get_rest_namespaces() as $namespace ) { + $this->endpoints[ $namespace ] = []; - foreach ( $this->get_controllers( $namespace ) as $name => $class ) { + foreach ( $this->get_rest_controllers( $namespace ) as $name => $class ) { $this->endpoints[ $namespace ][ $class ] = new $class(); $this->endpoints[ $namespace ][ $class ]->register_routes(); } @@ -55,13 +50,13 @@ class Server { * * @return array */ - protected function get_namespaces() { - return array( + protected function get_rest_namespaces() { + return [ 'wc/v1', 'wc/v2', 'wc/v3', 'wc-blocks/v1', - ); + ]; } /** @@ -70,10 +65,10 @@ class Server { * @param string $namespace Namespace to get controllers for. * @return array */ - protected function get_controllers( $namespace ) { + protected function get_rest_controllers( $namespace ) { switch ( $namespace ) { case 'wc/v1': - return array( + return [ 'WC_REST_Coupons_V1_Controller', 'WC_REST_Customer_Downloads_V1_Controller', 'WC_REST_Customers_V1_Controller', @@ -94,9 +89,9 @@ class Server { 'WC_REST_Taxes_V1_Controller', 'WC_REST_Webhook_Deliveries_V1_Controller', 'WC_REST_Webhooks_V1_Controller', - ); + ]; case 'wc/v2': - return array( + return [ 'WC_REST_Coupons_V2_Controller', 'WC_REST_Customer_Downloads_V2_Controller', 'WC_REST_Customers_V2_Controller', @@ -128,9 +123,9 @@ class Server { 'WC_REST_System_Status_Tools_V2_Controller', 'WC_REST_Shipping_Methods_V2_Controller', 'WC_REST_Payment_Gateways_V2_Controller', - ); + ]; case 'wc/v3': - return array( + return [ 'WC_REST_Coupons_Controller', 'WC_REST_Customer_Downloads_Controller', 'WC_REST_Customers_Controller', @@ -170,14 +165,14 @@ class Server { 'WC_REST_Data_Continents_Controller', 'WC_REST_Data_Countries_Controller', 'WC_REST_Data_Currencies_Controller', - ); + ]; case 'wc-blocks/v1': - return array( + return [ 'WC_REST_Blocks_Product_Attributes_Controller', 'WC_REST_Blocks_Product_Attribute_Terms_Controller', 'WC_REST_Blocks_Product_Categories_Controller', 'WC_REST_Blocks_Products_Controller', - ); + ]; } return array(); } diff --git a/src/v1/class-wc-rest-coupons-v1-controller.php b/src/RestApi/V1/class-wc-rest-coupons-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-coupons-v1-controller.php rename to src/RestApi/V1/class-wc-rest-coupons-v1-controller.php index fcedf22ae1f..f3bcf562a23 100644 --- a/src/v1/class-wc-rest-coupons-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-coupons-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Coupons controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Posts_Controller */ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { diff --git a/src/v1/class-wc-rest-customer-downloads-v1-controller.php b/src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-customer-downloads-v1-controller.php rename to src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php index 7557161adef..904f32fa68d 100644 --- a/src/v1/class-wc-rest-customer-downloads-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Customers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-customers-v1-controller.php b/src/RestApi/V1/class-wc-rest-customers-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-customers-v1-controller.php rename to src/RestApi/V1/class-wc-rest-customers-v1-controller.php index 4659e60946b..04b12cd4e47 100644 --- a/src/v1/class-wc-rest-customers-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-customers-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Customers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-order-notes-v1-controller.php b/src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-order-notes-v1-controller.php rename to src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php index 976a295bf7a..4eac1bd38e0 100644 --- a/src/v1/class-wc-rest-order-notes-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Order Notes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-order-refunds-v1-controller.php b/src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-order-refunds-v1-controller.php rename to src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php index 4b4bfa037ef..03b55bfe7da 100644 --- a/src/v1/class-wc-rest-order-refunds-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Order Refunds controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Orders_V1_Controller */ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { diff --git a/src/v1/class-wc-rest-orders-v1-controller.php b/src/RestApi/V1/class-wc-rest-orders-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-orders-v1-controller.php rename to src/RestApi/V1/class-wc-rest-orders-v1-controller.php index d03863c3bbd..8ee59793536 100644 --- a/src/v1/class-wc-rest-orders-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-orders-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Orders controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Posts_Controller */ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { diff --git a/src/v1/class-wc-rest-product-attribute-terms-v1-controller.php b/src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-product-attribute-terms-v1-controller.php rename to src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php index d40b90877d8..76d43c5cd90 100644 --- a/src/v1/class-wc-rest-product-attribute-terms-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Product Attribute Terms controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Terms_Controller */ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Controller { diff --git a/src/v1/class-wc-rest-product-attributes-v1-controller.php b/src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-product-attributes-v1-controller.php rename to src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php index e4290657e1d..211380c3144 100644 --- a/src/v1/class-wc-rest-product-attributes-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Product Attributes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-product-categories-v1-controller.php b/src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-product-categories-v1-controller.php rename to src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php index 9f12ee2a932..3cca0ab7420 100644 --- a/src/v1/class-wc-rest-product-categories-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Product Categories controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Terms_Controller */ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller { diff --git a/src/v1/class-wc-rest-product-reviews-v1-controller.php b/src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-product-reviews-v1-controller.php rename to src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php index 37237ae7992..ebfbdba7778 100644 --- a/src/v1/class-wc-rest-product-reviews-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Product Reviews Controller Class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-product-shipping-classes-v1-controller.php b/src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php similarity index 98% rename from src/v1/class-wc-rest-product-shipping-classes-v1-controller.php rename to src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php index 445c109df27..89b59f1b9b6 100644 --- a/src/v1/class-wc-rest-product-shipping-classes-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Product Shipping Classes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Terms_Controller */ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Controller { diff --git a/src/v1/class-wc-rest-product-tags-v1-controller.php b/src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php similarity index 98% rename from src/v1/class-wc-rest-product-tags-v1-controller.php rename to src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php index accdfae4c63..76161e94e13 100644 --- a/src/v1/class-wc-rest-product-tags-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Product Tags controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Terms_Controller */ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { diff --git a/src/v1/class-wc-rest-products-v1-controller.php b/src/RestApi/V1/class-wc-rest-products-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-products-v1-controller.php rename to src/RestApi/V1/class-wc-rest-products-v1-controller.php index f8162881862..6ca69c397c0 100644 --- a/src/v1/class-wc-rest-products-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-products-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Products controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Posts_Controller */ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { diff --git a/src/v1/class-wc-rest-report-sales-v1-controller.php b/src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-report-sales-v1-controller.php rename to src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php index 56aa1854c30..ebd52c67565 100644 --- a/src/v1/class-wc-rest-report-sales-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Report Sales controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-report-top-sellers-v1-controller.php b/src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php similarity index 98% rename from src/v1/class-wc-rest-report-top-sellers-v1-controller.php rename to src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php index de8ec7e80c9..8d581540858 100644 --- a/src/v1/class-wc-rest-report-top-sellers-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Report Top Sellers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Report_Sales_V1_Controller */ class WC_REST_Report_Top_Sellers_V1_Controller extends WC_REST_Report_Sales_V1_Controller { diff --git a/src/v1/class-wc-rest-reports-v1-controller.php b/src/RestApi/V1/class-wc-rest-reports-v1-controller.php similarity index 98% rename from src/v1/class-wc-rest-reports-v1-controller.php rename to src/RestApi/V1/class-wc-rest-reports-v1-controller.php index 2d284aa48bc..4b40f00875f 100644 --- a/src/v1/class-wc-rest-reports-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-reports-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Reports controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Reports_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-tax-classes-v1-controller.php b/src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-tax-classes-v1-controller.php rename to src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php index f857256ac95..6e5b25d8cd6 100644 --- a/src/v1/class-wc-rest-tax-classes-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Tax Classes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-taxes-v1-controller.php b/src/RestApi/V1/class-wc-rest-taxes-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-taxes-v1-controller.php rename to src/RestApi/V1/class-wc-rest-taxes-v1-controller.php index 1b8c9bdd0aa..278e87bd999 100644 --- a/src/v1/class-wc-rest-taxes-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-taxes-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Taxes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-webhook-deliveries-v1-controller.php b/src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-webhook-deliveries-v1-controller.php rename to src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php index 7b51ac7f4d3..a3b2cd81981 100644 --- a/src/v1/class-wc-rest-webhook-deliveries-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -18,7 +18,7 @@ if ( ! defined( 'ABSPATH' ) ) { * REST API Webhook Deliveries controller class. * * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { diff --git a/src/v1/class-wc-rest-webhooks-v1-controller.php b/src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php similarity index 99% rename from src/v1/class-wc-rest-webhooks-v1-controller.php rename to src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php index 15a9d07244c..97b1640ac56 100644 --- a/src/v1/class-wc-rest-webhooks-v1-controller.php +++ b/src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /webhooks endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Webhooks controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { diff --git a/src/v2/class-wc-rest-coupons-v2-controller.php b/src/RestApi/V2/class-wc-rest-coupons-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-coupons-v2-controller.php rename to src/RestApi/V2/class-wc-rest-coupons-v2-controller.php index a417c4a5737..cb727a2a568 100644 --- a/src/v2/class-wc-rest-coupons-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-coupons-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /coupons endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Coupons controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_CRUD_Controller */ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { diff --git a/src/v2/class-wc-rest-customer-downloads-v2-controller.php b/src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php similarity index 98% rename from src/v2/class-wc-rest-customer-downloads-v2-controller.php rename to src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php index 887761e074b..127ae9314b7 100644 --- a/src/v2/class-wc-rest-customer-downloads-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /customers//downloads endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Customers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Customer_Downloads_V1_Controller */ class WC_REST_Customer_Downloads_V2_Controller extends WC_REST_Customer_Downloads_V1_Controller { diff --git a/src/v2/class-wc-rest-customers-v2-controller.php b/src/RestApi/V2/class-wc-rest-customers-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-customers-v2-controller.php rename to src/RestApi/V2/class-wc-rest-customers-v2-controller.php index cbb3d22afff..e780f8f6122 100644 --- a/src/v2/class-wc-rest-customers-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-customers-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /customers endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Customers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Customers_V1_Controller */ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { diff --git a/src/v2/class-wc-rest-network-orders-v2-controller.php b/src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php similarity index 98% rename from src/v2/class-wc-rest-network-orders-v2-controller.php rename to src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php index 0ccd5150b62..26213306ceb 100644 --- a/src/v2/class-wc-rest-network-orders-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders/network endpoint * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.4.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Network Orders controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Orders_V2_Controller */ class WC_REST_Network_Orders_V2_Controller extends WC_REST_Orders_V2_Controller { diff --git a/src/v2/class-wc-rest-order-notes-v2-controller.php b/src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php similarity index 98% rename from src/v2/class-wc-rest-order-notes-v2-controller.php rename to src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php index b7f31d1ea79..f08ddaef67d 100644 --- a/src/v2/class-wc-rest-order-notes-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders//notes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Order Notes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Order_Notes_V1_Controller */ class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controller { diff --git a/src/v2/class-wc-rest-order-refunds-v2-controller.php b/src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-order-refunds-v2-controller.php rename to src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php index 3ce6e7fbf82..46407715f5e 100644 --- a/src/v2/class-wc-rest-order-refunds-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders//refunds endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Order Refunds controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Orders_V2_Controller */ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { diff --git a/src/v2/class-wc-rest-orders-v2-controller.php b/src/RestApi/V2/class-wc-rest-orders-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-orders-v2-controller.php rename to src/RestApi/V2/class-wc-rest-orders-v2-controller.php index 50689174f9c..eb149c52d19 100644 --- a/src/v2/class-wc-rest-orders-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-orders-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Orders controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_CRUD_Controller */ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { diff --git a/src/v2/class-wc-rest-payment-gateways-v2-controller.php b/src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-payment-gateways-v2-controller.php rename to src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php index 02e71571126..96eece65ae4 100644 --- a/src/v2/class-wc-rest-payment-gateways-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /payment_gateways endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * Paymenga gateways controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { diff --git a/src/v2/class-wc-rest-product-attribute-terms-v2-controller.php b/src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php similarity index 88% rename from src/v2/class-wc-rest-product-attribute-terms-v2-controller.php rename to src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php index 23ad5e14d9c..7a7ded8a5b0 100644 --- a/src/v2/class-wc-rest-product-attribute-terms-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/attributes//terms endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Attribute Terms controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Attribute_Terms_V1_Controller */ class WC_REST_Product_Attribute_Terms_V2_Controller extends WC_REST_Product_Attribute_Terms_V1_Controller { diff --git a/src/v2/class-wc-rest-product-attributes-v2-controller.php b/src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php similarity index 88% rename from src/v2/class-wc-rest-product-attributes-v2-controller.php rename to src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php index 59d5416b52e..f31088d2fc5 100644 --- a/src/v2/class-wc-rest-product-attributes-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/attributes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Attributes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Attributes_V1_Controller */ class WC_REST_Product_Attributes_V2_Controller extends WC_REST_Product_Attributes_V1_Controller { diff --git a/src/v2/class-wc-rest-product-categories-v2-controller.php b/src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-product-categories-v2-controller.php rename to src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php index 8f32517f6eb..a217e3f3c9f 100644 --- a/src/v2/class-wc-rest-product-categories-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/categories endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Categories controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Categories_V1_Controller */ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categories_V1_Controller { diff --git a/src/v2/class-wc-rest-product-reviews-v2-controller.php b/src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-product-reviews-v2-controller.php rename to src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php index 5eb6ca0ab07..cde63971b85 100644 --- a/src/v2/class-wc-rest-product-reviews-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to /products//reviews. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Reviews Controller Class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Reviews_V1_Controller */ class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_Controller { diff --git a/src/v2/class-wc-rest-product-shipping-classes-v2-controller.php b/src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php similarity index 88% rename from src/v2/class-wc-rest-product-shipping-classes-v2-controller.php rename to src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php index 1eeec0041df..8e2f2204595 100644 --- a/src/v2/class-wc-rest-product-shipping-classes-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/shipping_classes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Shipping Classes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Shipping_Classes_V1_Controller */ class WC_REST_Product_Shipping_Classes_V2_Controller extends WC_REST_Product_Shipping_Classes_V1_Controller { diff --git a/src/v2/class-wc-rest-product-tags-v2-controller.php b/src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php similarity index 87% rename from src/v2/class-wc-rest-product-tags-v2-controller.php rename to src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php index 1f184c8971e..0d62cbdda84 100644 --- a/src/v2/class-wc-rest-product-tags-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/tags endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Tags controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Tags_V1_Controller */ class WC_REST_Product_Tags_V2_Controller extends WC_REST_Product_Tags_V1_Controller { diff --git a/src/v2/class-wc-rest-product-variations-v2-controller.php b/src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-product-variations-v2-controller.php rename to src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php index 26883d35a66..d1fdb90e72f 100644 --- a/src/v2/class-wc-rest-product-variations-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /products//variations endpoints. * - * @package WooCommerce\API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API variations controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Products_V2_Controller */ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Controller { diff --git a/src/v2/class-wc-rest-products-v2-controller.php b/src/RestApi/V2/class-wc-rest-products-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-products-v2-controller.php rename to src/RestApi/V2/class-wc-rest-products-v2-controller.php index d3558ded964..c96016a182c 100644 --- a/src/v2/class-wc-rest-products-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-products-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /products endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Products controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_CRUD_Controller */ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { diff --git a/src/v2/class-wc-rest-report-sales-v2-controller.php b/src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php similarity index 87% rename from src/v2/class-wc-rest-report-sales-v2-controller.php rename to src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php index 14b2e52077b..f2232447c0a 100644 --- a/src/v2/class-wc-rest-report-sales-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports/sales endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Report Sales controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Report_Sales_V1_Controller */ class WC_REST_Report_Sales_V2_Controller extends WC_REST_Report_Sales_V1_Controller { diff --git a/src/v2/class-wc-rest-report-top-sellers-v2-controller.php b/src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php similarity index 87% rename from src/v2/class-wc-rest-report-top-sellers-v2-controller.php rename to src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php index ab208b74272..407ade5c256 100644 --- a/src/v2/class-wc-rest-report-top-sellers-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports/top_sellers endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Report Top Sellers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Report_Top_Sellers_V1_Controller */ class WC_REST_Report_Top_Sellers_V2_Controller extends WC_REST_Report_Top_Sellers_V1_Controller { diff --git a/src/v2/class-wc-rest-reports-v2-controller.php b/src/RestApi/V2/class-wc-rest-reports-v2-controller.php similarity index 86% rename from src/v2/class-wc-rest-reports-v2-controller.php rename to src/RestApi/V2/class-wc-rest-reports-v2-controller.php index 642ac866aa4..2eea5b97f67 100644 --- a/src/v2/class-wc-rest-reports-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-reports-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Reports_V1_Controller */ class WC_REST_Reports_V2_Controller extends WC_REST_Reports_V1_Controller { diff --git a/src/v2/class-wc-rest-setting-options-v2-controller.php b/src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-setting-options-v2-controller.php rename to src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php index 136ef1f7cd9..7136459b925 100644 --- a/src/v2/class-wc-rest-setting-options-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /settings/$group/$setting endpoints. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Setting Options controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { diff --git a/src/v2/class-wc-rest-settings-v2-controller.php b/src/RestApi/V2/class-wc-rest-settings-v2-controller.php similarity index 98% rename from src/v2/class-wc-rest-settings-v2-controller.php rename to src/RestApi/V2/class-wc-rest-settings-v2-controller.php index f8f33f2e4bc..3b1dd0be705 100644 --- a/src/v2/class-wc-rest-settings-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-settings-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /settings endpoints. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Settings controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { diff --git a/src/v2/class-wc-rest-shipping-methods-v2-controller.php b/src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-shipping-methods-v2-controller.php rename to src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php index 78df57ece6e..9b8442a12fc 100644 --- a/src/v2/class-wc-rest-shipping-methods-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping_methods endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * Shipping methods controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { diff --git a/src/v2/class-wc-rest-shipping-zone-locations-v2-controller.php b/src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php similarity index 98% rename from src/v2/class-wc-rest-shipping-zone-locations-v2-controller.php rename to src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php index 77d85143209..4fd40bc9060 100644 --- a/src/v2/class-wc-rest-shipping-zone-locations-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones//locations endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Locations class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { diff --git a/src/v2/class-wc-rest-shipping-zone-methods-v2-controller.php b/src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-shipping-zone-methods-v2-controller.php rename to src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php index 69fdc4b87db..3cd52028ea6 100644 --- a/src/v2/class-wc-rest-shipping-zone-methods-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones//methods endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Methods class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { diff --git a/src/v2/class-wc-rest-shipping-zones-v2-controller.php b/src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-shipping-zones-v2-controller.php rename to src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php index 6071f6edb26..17038d2d9e5 100644 --- a/src/v2/class-wc-rest-shipping-zones-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zones class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { diff --git a/src/v2/class-wc-rest-system-status-tools-v2-controller.php b/src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-system-status-tools-v2-controller.php rename to src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php index f73d9702063..a0e91c97346 100644 --- a/src/v2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /system_status/tools/* endpoints. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * System status tools controller. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { diff --git a/src/v2/class-wc-rest-system-status-v2-controller.php b/src/RestApi/V2/class-wc-rest-system-status-v2-controller.php similarity index 99% rename from src/v2/class-wc-rest-system-status-v2-controller.php rename to src/RestApi/V2/class-wc-rest-system-status-v2-controller.php index f12588dd089..d141e656009 100644 --- a/src/v2/class-wc-rest-system-status-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-system-status-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /system_status endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * System status controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { diff --git a/src/v2/class-wc-rest-tax-classes-v2-controller.php b/src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php similarity index 87% rename from src/v2/class-wc-rest-tax-classes-v2-controller.php rename to src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php index cab4ad800ba..d024195657a 100644 --- a/src/v2/class-wc-rest-tax-classes-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /taxes/classes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Tax Classes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Tax_Classes_V1_Controller */ class WC_REST_Tax_Classes_V2_Controller extends WC_REST_Tax_Classes_V1_Controller { diff --git a/src/v2/class-wc-rest-taxes-v2-controller.php b/src/RestApi/V2/class-wc-rest-taxes-v2-controller.php similarity index 85% rename from src/v2/class-wc-rest-taxes-v2-controller.php rename to src/RestApi/V2/class-wc-rest-taxes-v2-controller.php index 06689ab6324..ea3884e9a9b 100644 --- a/src/v2/class-wc-rest-taxes-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-taxes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /taxes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Taxes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Taxes_V1_Controller */ class WC_REST_Taxes_V2_Controller extends WC_REST_Taxes_V1_Controller { diff --git a/src/v2/class-wc-rest-webhook-deliveries-v2-controller.php b/src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php similarity index 98% rename from src/v2/class-wc-rest-webhook-deliveries-v2-controller.php rename to src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php index f26c2a8fdb9..012a10ba78b 100644 --- a/src/v2/class-wc-rest-webhook-deliveries-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /webhooks//deliveries endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -14,7 +14,7 @@ defined( 'ABSPATH' ) || exit; * REST API Webhook Deliveries controller class. * * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Webhook_Deliveries_V1_Controller */ class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliveries_V1_Controller { diff --git a/src/v2/class-wc-rest-webhooks-v2-controller.php b/src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php similarity index 98% rename from src/v2/class-wc-rest-webhooks-v2-controller.php rename to src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php index 746d17e938e..7c02e332765 100644 --- a/src/v2/class-wc-rest-webhooks-v2-controller.php +++ b/src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /webhooks endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Webhooks controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Webhooks_V1_Controller */ class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller { diff --git a/src/class-wc-rest-controller.php b/src/RestApi/V3/class-wc-rest-controller.php similarity index 99% rename from src/class-wc-rest-controller.php rename to src/RestApi/V3/class-wc-rest-controller.php index 987a4d78741..e0ff5c4732c 100644 --- a/src/class-wc-rest-controller.php +++ b/src/RestApi/V3/class-wc-rest-controller.php @@ -12,7 +12,7 @@ * If necessary extend this class and create new abstract classes like `WC_REST_CRUD_Controller` or `WC_REST_Terms_Controller`. * * @class WC_REST_Controller - * @package WooCommerce/Abstracts + * @package WooCommerce/RestApi * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ */ @@ -23,7 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * Abstract Rest Controller Class * - * @package WooCommerce/Abstracts + * @package WooCommerce/RestApi * @extends WP_REST_Controller * @version 2.6.0 */ diff --git a/src/v3/class-wc-rest-coupons-controller.php b/src/RestApi/V3/class-wc-rest-coupons-controller.php similarity index 86% rename from src/v3/class-wc-rest-coupons-controller.php rename to src/RestApi/V3/class-wc-rest-coupons-controller.php index 6fc216b11e9..fe6bcd0e449 100644 --- a/src/v3/class-wc-rest-coupons-controller.php +++ b/src/RestApi/V3/class-wc-rest-coupons-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /coupons endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Coupons controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Coupons_V2_Controller */ class WC_REST_Coupons_Controller extends WC_REST_Coupons_V2_Controller { diff --git a/src/class-wc-rest-crud-controller.php b/src/RestApi/V3/class-wc-rest-crud-controller.php similarity index 99% rename from src/class-wc-rest-crud-controller.php rename to src/RestApi/V3/class-wc-rest-crud-controller.php index c42f1233141..6953ee2cb52 100644 --- a/src/class-wc-rest-crud-controller.php +++ b/src/RestApi/V3/class-wc-rest-crud-controller.php @@ -3,7 +3,7 @@ * Abstract Rest CRUD Controller Class * * @class WC_REST_CRUD_Controller - * @package WooCommerce/Abstracts + * @package WooCommerce/RestApi * @version 3.0.0 */ diff --git a/src/v3/class-wc-rest-customer-downloads-controller.php b/src/RestApi/V3/class-wc-rest-customer-downloads-controller.php similarity index 88% rename from src/v3/class-wc-rest-customer-downloads-controller.php rename to src/RestApi/V3/class-wc-rest-customer-downloads-controller.php index 3fd89d4a4fb..1d67ca98c57 100644 --- a/src/v3/class-wc-rest-customer-downloads-controller.php +++ b/src/RestApi/V3/class-wc-rest-customer-downloads-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /customers//downloads endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Customers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Customer_Downloads_V2_Controller */ class WC_REST_Customer_Downloads_Controller extends WC_REST_Customer_Downloads_V2_Controller { diff --git a/src/v3/class-wc-rest-customers-controller.php b/src/RestApi/V3/class-wc-rest-customers-controller.php similarity index 99% rename from src/v3/class-wc-rest-customers-controller.php rename to src/RestApi/V3/class-wc-rest-customers-controller.php index 05c45a9196c..e87360a60a0 100644 --- a/src/v3/class-wc-rest-customers-controller.php +++ b/src/RestApi/V3/class-wc-rest-customers-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /customers endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Customers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Customers_V2_Controller */ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { diff --git a/src/v3/class-wc-rest-data-continents-controller.php b/src/RestApi/V3/class-wc-rest-data-continents-controller.php similarity index 99% rename from src/v3/class-wc-rest-data-continents-controller.php rename to src/RestApi/V3/class-wc-rest-data-continents-controller.php index 56c82fcb2f3..ccf64086b3f 100644 --- a/src/v3/class-wc-rest-data-continents-controller.php +++ b/src/RestApi/V3/class-wc-rest-data-continents-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /data/continents endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Data continents controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { diff --git a/src/v3/class-wc-rest-data-controller.php b/src/RestApi/V3/class-wc-rest-data-controller.php similarity index 98% rename from src/v3/class-wc-rest-data-controller.php rename to src/RestApi/V3/class-wc-rest-data-controller.php index 216586510e6..71c6dd9029a 100644 --- a/src/v3/class-wc-rest-data-controller.php +++ b/src/RestApi/V3/class-wc-rest-data-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /data endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Data controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Data_Controller extends WC_REST_Controller { diff --git a/src/v3/class-wc-rest-data-countries-controller.php b/src/RestApi/V3/class-wc-rest-data-countries-controller.php similarity index 99% rename from src/v3/class-wc-rest-data-countries-controller.php rename to src/RestApi/V3/class-wc-rest-data-countries-controller.php index 3bc7cb65762..ff659b67e09 100644 --- a/src/v3/class-wc-rest-data-countries-controller.php +++ b/src/RestApi/V3/class-wc-rest-data-countries-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /data/countries endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Data countries controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { diff --git a/src/v3/class-wc-rest-data-currencies-controller.php b/src/RestApi/V3/class-wc-rest-data-currencies-controller.php similarity index 98% rename from src/v3/class-wc-rest-data-currencies-controller.php rename to src/RestApi/V3/class-wc-rest-data-currencies-controller.php index 1b589c297fa..b5439695d0d 100644 --- a/src/v3/class-wc-rest-data-currencies-controller.php +++ b/src/RestApi/V3/class-wc-rest-data-currencies-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /data/currencies endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Data Currencies controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi */ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { diff --git a/src/v3/class-wc-rest-network-orders-controller.php b/src/RestApi/V3/class-wc-rest-network-orders-controller.php similarity index 87% rename from src/v3/class-wc-rest-network-orders-controller.php rename to src/RestApi/V3/class-wc-rest-network-orders-controller.php index 070f95b0555..963a7cbec36 100644 --- a/src/v3/class-wc-rest-network-orders-controller.php +++ b/src/RestApi/V3/class-wc-rest-network-orders-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders/network endpoint * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.4.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Network Orders controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Network_Orders_V2_Controller */ class WC_REST_Network_Orders_Controller extends WC_REST_Network_Orders_V2_Controller { diff --git a/src/v3/class-wc-rest-order-notes-controller.php b/src/RestApi/V3/class-wc-rest-order-notes-controller.php similarity index 98% rename from src/v3/class-wc-rest-order-notes-controller.php rename to src/RestApi/V3/class-wc-rest-order-notes-controller.php index 3a50006586e..e45d1ef3e27 100644 --- a/src/v3/class-wc-rest-order-notes-controller.php +++ b/src/RestApi/V3/class-wc-rest-order-notes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders//notes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Order Notes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Order_Notes_V2_Controller */ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { diff --git a/src/v3/class-wc-rest-order-refunds-controller.php b/src/RestApi/V3/class-wc-rest-order-refunds-controller.php similarity index 97% rename from src/v3/class-wc-rest-order-refunds-controller.php rename to src/RestApi/V3/class-wc-rest-order-refunds-controller.php index 0834a2b9f04..38e6a69bb6d 100644 --- a/src/v3/class-wc-rest-order-refunds-controller.php +++ b/src/RestApi/V3/class-wc-rest-order-refunds-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders//refunds endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Order Refunds controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Order_Refunds_V2_Controller */ class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controller { diff --git a/src/v3/class-wc-rest-orders-controller.php b/src/RestApi/V3/class-wc-rest-orders-controller.php similarity index 99% rename from src/v3/class-wc-rest-orders-controller.php rename to src/RestApi/V3/class-wc-rest-orders-controller.php index d2bb6f06663..f7dadc8b42c 100644 --- a/src/v3/class-wc-rest-orders-controller.php +++ b/src/RestApi/V3/class-wc-rest-orders-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Orders controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Orders_V2_Controller */ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller { diff --git a/src/v3/class-wc-rest-payment-gateways-controller.php b/src/RestApi/V3/class-wc-rest-payment-gateways-controller.php similarity index 99% rename from src/v3/class-wc-rest-payment-gateways-controller.php rename to src/RestApi/V3/class-wc-rest-payment-gateways-controller.php index 88f09312425..dc71790b6f7 100644 --- a/src/v3/class-wc-rest-payment-gateways-controller.php +++ b/src/RestApi/V3/class-wc-rest-payment-gateways-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /payment_gateways endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * Paymenga gateways controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Payment_Gateways_V2_Controller */ class WC_REST_Payment_Gateways_Controller extends WC_REST_Payment_Gateways_V2_Controller { diff --git a/src/class-wc-rest-posts-controller.php b/src/RestApi/V3/class-wc-rest-posts-controller.php similarity index 99% rename from src/class-wc-rest-posts-controller.php rename to src/RestApi/V3/class-wc-rest-posts-controller.php index bffc4a6843e..d5966551502 100644 --- a/src/class-wc-rest-posts-controller.php +++ b/src/RestApi/V3/class-wc-rest-posts-controller.php @@ -3,7 +3,7 @@ * Abstract Rest Posts Controller Class * * @class WC_REST_Posts_Controller - * @package WooCommerce/Abstracts + * @package WooCommerce/RestApi */ if ( ! defined( 'ABSPATH' ) ) { @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * WC_REST_Posts_Controller * - * @package WooCommerce/Abstracts + * @package WooCommerce/RestApi * @version 2.6.0 */ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { diff --git a/src/v3/class-wc-rest-product-attribute-terms-controller.php b/src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php similarity index 88% rename from src/v3/class-wc-rest-product-attribute-terms-controller.php rename to src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php index 3e652894d69..ee6d7b48868 100644 --- a/src/v3/class-wc-rest-product-attribute-terms-controller.php +++ b/src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/attributes//terms endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Attribute Terms controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Attribute_Terms_V2_Controller */ class WC_REST_Product_Attribute_Terms_Controller extends WC_REST_Product_Attribute_Terms_V2_Controller { diff --git a/src/v3/class-wc-rest-product-attributes-controller.php b/src/RestApi/V3/class-wc-rest-product-attributes-controller.php similarity index 87% rename from src/v3/class-wc-rest-product-attributes-controller.php rename to src/RestApi/V3/class-wc-rest-product-attributes-controller.php index 047e6e4e257..6dfd84e7972 100644 --- a/src/v3/class-wc-rest-product-attributes-controller.php +++ b/src/RestApi/V3/class-wc-rest-product-attributes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/attributes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Attributes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Attributes_V2_Controller */ class WC_REST_Product_Attributes_Controller extends WC_REST_Product_Attributes_V2_Controller { diff --git a/src/v3/class-wc-rest-product-categories-controller.php b/src/RestApi/V3/class-wc-rest-product-categories-controller.php similarity index 99% rename from src/v3/class-wc-rest-product-categories-controller.php rename to src/RestApi/V3/class-wc-rest-product-categories-controller.php index 368befeb555..094c6e8bb52 100644 --- a/src/v3/class-wc-rest-product-categories-controller.php +++ b/src/RestApi/V3/class-wc-rest-product-categories-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/categories endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Categories controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Categories_V2_Controller */ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V2_Controller { diff --git a/src/v3/class-wc-rest-product-reviews-controller.php b/src/RestApi/V3/class-wc-rest-product-reviews-controller.php similarity index 99% rename from src/v3/class-wc-rest-product-reviews-controller.php rename to src/RestApi/V3/class-wc-rest-product-reviews-controller.php index 602b1b5f8dd..ae0270afa12 100644 --- a/src/v3/class-wc-rest-product-reviews-controller.php +++ b/src/RestApi/V3/class-wc-rest-product-reviews-controller.php @@ -4,7 +4,7 @@ * * Handles requests to /products/reviews. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Reviews Controller Class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { diff --git a/src/v3/class-wc-rest-product-shipping-classes-controller.php b/src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php similarity index 88% rename from src/v3/class-wc-rest-product-shipping-classes-controller.php rename to src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php index 3a3aa7c0444..af07ea955c4 100644 --- a/src/v3/class-wc-rest-product-shipping-classes-controller.php +++ b/src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/shipping_classes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Shipping Classes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Shipping_Classes_V2_Controller */ class WC_REST_Product_Shipping_Classes_Controller extends WC_REST_Product_Shipping_Classes_V2_Controller { diff --git a/src/v3/class-wc-rest-product-tags-controller.php b/src/RestApi/V3/class-wc-rest-product-tags-controller.php similarity index 87% rename from src/v3/class-wc-rest-product-tags-controller.php rename to src/RestApi/V3/class-wc-rest-product-tags-controller.php index 121808721be..bb6db01e85b 100644 --- a/src/v3/class-wc-rest-product-tags-controller.php +++ b/src/RestApi/V3/class-wc-rest-product-tags-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/tags endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Tags controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Tags_V2_Controller */ class WC_REST_Product_Tags_Controller extends WC_REST_Product_Tags_V2_Controller { diff --git a/src/v3/class-wc-rest-product-variations-controller.php b/src/RestApi/V3/class-wc-rest-product-variations-controller.php similarity index 99% rename from src/v3/class-wc-rest-product-variations-controller.php rename to src/RestApi/V3/class-wc-rest-product-variations-controller.php index deb6cc61218..5b69656b0ab 100644 --- a/src/v3/class-wc-rest-product-variations-controller.php +++ b/src/RestApi/V3/class-wc-rest-product-variations-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /products//variations endpoints. * - * @package WooCommerce\API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API variations controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Product_Variations_V2_Controller */ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V2_Controller { diff --git a/src/v3/class-wc-rest-products-controller.php b/src/RestApi/V3/class-wc-rest-products-controller.php similarity index 99% rename from src/v3/class-wc-rest-products-controller.php rename to src/RestApi/V3/class-wc-rest-products-controller.php index 8b79b823604..95c32c4b238 100644 --- a/src/v3/class-wc-rest-products-controller.php +++ b/src/RestApi/V3/class-wc-rest-products-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /products endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Products controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Products_V2_Controller */ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { diff --git a/src/v3/class-wc-rest-report-coupons-totals-controller.php b/src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php similarity index 98% rename from src/v3/class-wc-rest-report-coupons-totals-controller.php rename to src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php index fa73796e3fe..d999b349703 100644 --- a/src/v3/class-wc-rest-report-coupons-totals-controller.php +++ b/src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/coupons/count endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Coupons Totals controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Coupons_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/v3/class-wc-rest-report-customers-totals-controller.php b/src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php similarity index 98% rename from src/v3/class-wc-rest-report-customers-totals-controller.php rename to src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php index e5459728414..c32b170e2db 100644 --- a/src/v3/class-wc-rest-report-customers-totals-controller.php +++ b/src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/customers/count endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Customers Totals controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Customers_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/v3/class-wc-rest-report-orders-totals-controller.php b/src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php similarity index 97% rename from src/v3/class-wc-rest-report-orders-totals-controller.php rename to src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php index 4bfb773ba76..3fdc4619351 100644 --- a/src/v3/class-wc-rest-report-orders-totals-controller.php +++ b/src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/orders/count endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Orders Totals controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Orders_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/v3/class-wc-rest-report-products-totals-controller.php b/src/RestApi/V3/class-wc-rest-report-products-totals-controller.php similarity index 98% rename from src/v3/class-wc-rest-report-products-totals-controller.php rename to src/RestApi/V3/class-wc-rest-report-products-totals-controller.php index 63812219260..adb42b0d276 100644 --- a/src/v3/class-wc-rest-report-products-totals-controller.php +++ b/src/RestApi/V3/class-wc-rest-report-products-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/products/count endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Products Totals controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Products_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/v3/class-wc-rest-report-reviews-totals-controller.php b/src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php similarity index 98% rename from src/v3/class-wc-rest-report-reviews-totals-controller.php rename to src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php index 4bff520ee3d..ef7ce098baa 100644 --- a/src/v3/class-wc-rest-report-reviews-totals-controller.php +++ b/src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/reviews/count endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Reviews Totals controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Reviews_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/v3/class-wc-rest-report-sales-controller.php b/src/RestApi/V3/class-wc-rest-report-sales-controller.php similarity index 86% rename from src/v3/class-wc-rest-report-sales-controller.php rename to src/RestApi/V3/class-wc-rest-report-sales-controller.php index 165add54796..4712c333394 100644 --- a/src/v3/class-wc-rest-report-sales-controller.php +++ b/src/RestApi/V3/class-wc-rest-report-sales-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports/sales endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Report Sales controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Report_Sales_V2_Controller */ class WC_REST_Report_Sales_Controller extends WC_REST_Report_Sales_V2_Controller { diff --git a/src/v3/class-wc-rest-report-top-sellers-controller.php b/src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php similarity index 87% rename from src/v3/class-wc-rest-report-top-sellers-controller.php rename to src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php index f9d705bd8ff..1b7a3044cec 100644 --- a/src/v3/class-wc-rest-report-top-sellers-controller.php +++ b/src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports/top_sellers endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Report Top Sellers controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Report_Top_Sellers_V2_Controller */ class WC_REST_Report_Top_Sellers_Controller extends WC_REST_Report_Top_Sellers_V2_Controller { diff --git a/src/v3/class-wc-rest-reports-controller.php b/src/RestApi/V3/class-wc-rest-reports-controller.php similarity index 96% rename from src/v3/class-wc-rest-reports-controller.php rename to src/RestApi/V3/class-wc-rest-reports-controller.php index 413b4995e93..b99d2c3c059 100644 --- a/src/v3/class-wc-rest-reports-controller.php +++ b/src/RestApi/V3/class-wc-rest-reports-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Reports_V2_Controller */ class WC_REST_Reports_Controller extends WC_REST_Reports_V2_Controller { diff --git a/src/v3/class-wc-rest-setting-options-controller.php b/src/RestApi/V3/class-wc-rest-setting-options-controller.php similarity index 99% rename from src/v3/class-wc-rest-setting-options-controller.php rename to src/RestApi/V3/class-wc-rest-setting-options-controller.php index 9613ce818eb..41ae7ae86f7 100644 --- a/src/v3/class-wc-rest-setting-options-controller.php +++ b/src/RestApi/V3/class-wc-rest-setting-options-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /settings/$group/$setting endpoints. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Setting Options controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Setting_Options_V2_Controller */ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Controller { diff --git a/src/v3/class-wc-rest-settings-controller.php b/src/RestApi/V3/class-wc-rest-settings-controller.php similarity index 97% rename from src/v3/class-wc-rest-settings-controller.php rename to src/RestApi/V3/class-wc-rest-settings-controller.php index f3ad622e467..869f725144f 100644 --- a/src/v3/class-wc-rest-settings-controller.php +++ b/src/RestApi/V3/class-wc-rest-settings-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /settings endpoints. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Settings controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Settings_V2_Controller */ class WC_REST_Settings_Controller extends WC_REST_Settings_V2_Controller { diff --git a/src/v3/class-wc-rest-shipping-methods-controller.php b/src/RestApi/V3/class-wc-rest-shipping-methods-controller.php similarity index 87% rename from src/v3/class-wc-rest-shipping-methods-controller.php rename to src/RestApi/V3/class-wc-rest-shipping-methods-controller.php index 075e4f777cd..ca3c36d607c 100644 --- a/src/v3/class-wc-rest-shipping-methods-controller.php +++ b/src/RestApi/V3/class-wc-rest-shipping-methods-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping_methods endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * Shipping methods controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Shipping_Methods_V2_Controller */ class WC_REST_Shipping_Methods_Controller extends WC_REST_Shipping_Methods_V2_Controller { diff --git a/src/v3/class-wc-rest-shipping-zone-locations-controller.php b/src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php similarity index 88% rename from src/v3/class-wc-rest-shipping-zone-locations-controller.php rename to src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php index cba326a80ca..6211eccd561 100644 --- a/src/v3/class-wc-rest-shipping-zone-locations-controller.php +++ b/src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones//locations endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Locations class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Shipping_Zone_Locations_V2_Controller */ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zone_Locations_V2_Controller { diff --git a/src/v3/class-wc-rest-shipping-zone-methods-controller.php b/src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php similarity index 88% rename from src/v3/class-wc-rest-shipping-zone-methods-controller.php rename to src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php index 6058e95baaf..3ed5cf4e08b 100644 --- a/src/v3/class-wc-rest-shipping-zone-methods-controller.php +++ b/src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones//methods endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Methods class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Shipping_Zone_Methods_V2_Controller */ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zone_Methods_V2_Controller { diff --git a/src/class-wc-rest-shipping-zones-controller-base.php b/src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php similarity index 98% rename from src/class-wc-rest-shipping-zones-controller-base.php rename to src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php index b89a5a442c8..7b8cc282f3b 100644 --- a/src/class-wc-rest-shipping-zones-controller-base.php +++ b/src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php @@ -4,7 +4,7 @@ * * Houses common functionality between Shipping Zones and Locations. * - * @package WooCommerce/Abstracts + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Shipping Zones base class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Controller */ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller { diff --git a/src/v3/class-wc-rest-shipping-zones-controller.php b/src/RestApi/V3/class-wc-rest-shipping-zones-controller.php similarity index 87% rename from src/v3/class-wc-rest-shipping-zones-controller.php rename to src/RestApi/V3/class-wc-rest-shipping-zones-controller.php index dd766a3291c..778861bff5c 100644 --- a/src/v3/class-wc-rest-shipping-zones-controller.php +++ b/src/RestApi/V3/class-wc-rest-shipping-zones-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zones class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Shipping_Zones_V2_Controller */ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_V2_Controller { diff --git a/src/v3/class-wc-rest-system-status-controller.php b/src/RestApi/V3/class-wc-rest-system-status-controller.php similarity index 87% rename from src/v3/class-wc-rest-system-status-controller.php rename to src/RestApi/V3/class-wc-rest-system-status-controller.php index 78b37fbe162..71a1ce085e4 100644 --- a/src/v3/class-wc-rest-system-status-controller.php +++ b/src/RestApi/V3/class-wc-rest-system-status-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /system_status endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * System status controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_System_Status_V2_Controller */ class WC_REST_System_Status_Controller extends WC_REST_System_Status_V2_Controller { diff --git a/src/v3/class-wc-rest-system-status-tools-controller.php b/src/RestApi/V3/class-wc-rest-system-status-tools-controller.php similarity index 87% rename from src/v3/class-wc-rest-system-status-tools-controller.php rename to src/RestApi/V3/class-wc-rest-system-status-tools-controller.php index f1b0bef61d7..7e8e452f875 100644 --- a/src/v3/class-wc-rest-system-status-tools-controller.php +++ b/src/RestApi/V3/class-wc-rest-system-status-tools-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /system_status/tools/* endpoints. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * System status tools controller. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_System_Status_Tools_V2_Controller */ class WC_REST_System_Status_Tools_Controller extends WC_REST_System_Status_Tools_V2_Controller { diff --git a/src/v3/class-wc-rest-tax-classes-controller.php b/src/RestApi/V3/class-wc-rest-tax-classes-controller.php similarity index 86% rename from src/v3/class-wc-rest-tax-classes-controller.php rename to src/RestApi/V3/class-wc-rest-tax-classes-controller.php index 39879e20ef4..2fff460b540 100644 --- a/src/v3/class-wc-rest-tax-classes-controller.php +++ b/src/RestApi/V3/class-wc-rest-tax-classes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /taxes/classes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Tax Classes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Tax_Classes_V2_Controller */ class WC_REST_Tax_Classes_Controller extends WC_REST_Tax_Classes_V2_Controller { diff --git a/src/v3/class-wc-rest-taxes-controller.php b/src/RestApi/V3/class-wc-rest-taxes-controller.php similarity index 85% rename from src/v3/class-wc-rest-taxes-controller.php rename to src/RestApi/V3/class-wc-rest-taxes-controller.php index 35c20e57908..5b90905cfec 100644 --- a/src/v3/class-wc-rest-taxes-controller.php +++ b/src/RestApi/V3/class-wc-rest-taxes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /taxes endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Taxes controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Taxes_V2_Controller */ class WC_REST_Taxes_Controller extends WC_REST_Taxes_V2_Controller { diff --git a/src/class-wc-rest-terms-controller.php b/src/RestApi/V3/class-wc-rest-terms-controller.php similarity index 99% rename from src/class-wc-rest-terms-controller.php rename to src/RestApi/V3/class-wc-rest-terms-controller.php index 4d20b07ea34..d9588099149 100644 --- a/src/class-wc-rest-terms-controller.php +++ b/src/RestApi/V3/class-wc-rest-terms-controller.php @@ -2,7 +2,7 @@ /** * Abstract Rest Terms Controller * - * @package WooCommerce/Abstracts + * @package WooCommerce/RestApi * @version 3.3.0 */ diff --git a/src/v3/class-wc-rest-webhooks-controller.php b/src/RestApi/V3/class-wc-rest-webhooks-controller.php similarity index 89% rename from src/v3/class-wc-rest-webhooks-controller.php rename to src/RestApi/V3/class-wc-rest-webhooks-controller.php index 99e1c70a729..77aebc5059f 100644 --- a/src/v3/class-wc-rest-webhooks-controller.php +++ b/src/RestApi/V3/class-wc-rest-webhooks-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /webhooks endpoint. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Webhooks controller class. * - * @package WooCommerce/API + * @package WooCommerce/RestApi * @extends WC_REST_Webhooks_V2_Controller */ class WC_REST_Webhooks_Controller extends WC_REST_Webhooks_V2_Controller { diff --git a/src/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php b/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php similarity index 98% rename from src/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php rename to src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php index 08c9320b0c2..bd42104463f 100644 --- a/src/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php +++ b/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php @@ -5,7 +5,7 @@ * Handles requests to the /products/attributes/get_file_name_from_class( $class ); - $dir = trailingslashit( dirname( __FILE__ ) ); - - // Non-namespaced files. - if ( stristr( $class, 'WC_REST_' ) ) { - if ( stristr( $class, 'WC_REST_Blocks' ) ) { - $subdir = 'wc-blocks/'; - } elseif ( stristr( $class, '_V1_' ) ) { - $subdir = 'v1/'; - } elseif ( stristr( $class, '_V2_' ) ) { - $subdir = 'v2/'; - } else { - $subdir = 'v3/'; - } - - if ( file_exists( $dir . $subdir . $file ) ) { - include $dir . $subdir . $file; - return; - } - } - - if ( file_exists( $dir . $class . '.php' ) ) { - include $dir . $class . '.php'; - return; - } - - if ( file_exists( $dir . $file ) ) { - include $dir . $file; - return; - } - } -} diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 52b681d0757..884b25e634b 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -9,7 +9,7 @@ * Requires PHP: 5.6 * License: GPLv3 * - * @package WooCommerce/RestAPI + * @package WooCommerce/RestApi */ defined( 'ABSPATH' ) || exit; @@ -18,24 +18,29 @@ if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) { return; } -if ( ! function_exists( 'wc_rest_api_1_dot_0_dot_0_dev' ) ) { - /** - * This is a version specific loader used as a callback so only the latest version of the API plugin is used. - * - * @internal Never call manually - this function will change between versions. - */ - function wc_rest_api_1_dot_0_dot_0_dev() { - require_once dirname( __FILE__ ) . '/src/class-server.php'; - \WooCommerce\Rest_Api\Server::instance()->init(); - } -} +/** + * API feature plugin version. + * + * @internal This version needs incrementing when releasing new versions of the API. + */ +$version = '1.1.0'; -add_action( - 'woocommerce_loaded', - function() { - if ( is_callable( array( wc()->api, 'register' ) ) ) { - // @internal When bumping the version remember to update the function names below. - wc()->api->register( '1.1.0', 'wc_rest_api_1_dot_0_dot_0_dev' ); - } +/** + * This callback loads this version of the API. + */ +$init_callback = function() { + require __DIR__ . '/vendor/autoload.php'; + \WooCommerce\RestApi::instance()->init(); +}; + +/** + * This callback registers this version of the API with WooCommerce. + */ +$register_callback = function() use ( $version, $init_callback ) { + if ( ! is_callable( array( wc()->api, 'register' ) ) ) { + return; } -); + wc()->api->register( $version, $init_callback ); +}; + +add_action( 'woocommerce_loaded', $register_callback ); From 12f667645de545ff173e20f6a8935b2fa95357f0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 May 2019 13:46:06 +0100 Subject: [PATCH 006/440] version helpers --- src/RestApi.php | 25 +++++++++++++++++++++++++ woocommerce-rest-api.php | 6 ++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/RestApi.php b/src/RestApi.php index 1720f68c210..ecc20286b55 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -24,6 +24,13 @@ class RestApi { */ protected $endpoints = []; + /** + * REST API package version. + * + * @var string + */ + protected $version; + /** * Hook into WordPress ready to init the REST API as needed. */ @@ -31,6 +38,24 @@ class RestApi { add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); } + /** + * Return REST API package version. + * + * @return string + */ + public function get_version() { + return $this->version; + } + + /** + * Set REST API package version. + * + * @param string $version Version to set. + */ + public function set_version( $version ) { + $this->version = $version; + } + /** * Register REST API routes. */ diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 884b25e634b..ef0ae00a5d3 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -28,9 +28,11 @@ $version = '1.1.0'; /** * This callback loads this version of the API. */ -$init_callback = function() { +$init_callback = function() use ( $version ) { require __DIR__ . '/vendor/autoload.php'; - \WooCommerce\RestApi::instance()->init(); + $rest_api = \WooCommerce\RestApi::instance(); + $rest_api->set_version( $version ); + $rest_api->init(); }; /** From 52f6887e48a306e77c42304251ae1f34f6746588 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 May 2019 13:49:59 +0100 Subject: [PATCH 007/440] update package name --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 422c98a48a4..7406eaedce2 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "woocommerce/rest-api", + "name": "woocommerce/woocommerce-rest-api", "description": "The WooCommerce core REST API.", "homepage": "https://github.com/woocommerce/woocommerce-rest-api", "type": "wordpress-plugin", From 756ced93b156edaab60714157595b11d4bc96283 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 May 2019 13:54:46 +0100 Subject: [PATCH 008/440] installers support --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index 7406eaedce2..5e63a416137 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,9 @@ "license": "GPL-3.0-or-later", "prefer-stable": true, "minimum-stability": "dev", + "require" : { + "composer/installers" : "~1.0" + }, "autoload": { "psr-4": { "WooCommerce\\": "src/" From e6405ba7bc4e9d6ad20a83d0cb0a8e94a911de2b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 May 2019 16:35:10 +0100 Subject: [PATCH 009/440] Init improvements/push vendor dir --- .gitignore | 12 - composer.json | 5 +- init.php | 11 + src/Autoloader.php | 70 ++++ src/RestApi.php | 29 +- vendor/autoload.php | 7 + vendor/composer/ClassLoader.php | 445 ++++++++++++++++++++++++ vendor/composer/LICENSE | 21 ++ vendor/composer/autoload_classmap.php | 110 ++++++ vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 9 + vendor/composer/autoload_real.php | 52 +++ vendor/composer/autoload_static.php | 120 +++++++ vendor/composer/installed.json | 1 + version.php | 8 + woocommerce-rest-api.php | 17 +- 16 files changed, 871 insertions(+), 55 deletions(-) create mode 100644 init.php create mode 100644 src/Autoloader.php create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.json create mode 100644 version.php diff --git a/.gitignore b/.gitignore index 6d673efc6ba..e6f2d231aad 100644 --- a/.gitignore +++ b/.gitignore @@ -24,9 +24,6 @@ none # Windows junk Thumbs.db -# ApiGen -/wc-apidocs/ - # Behat/CLI Tests tests/cli/installer tests/cli/composer.phar @@ -37,15 +34,6 @@ tests/cli/vendor # Unit tests /tmp /tests/bin/tmp -/tests/e2e-tests/config/local-*.json -/tests/e2e-tests/config/local.json # Logs /logs - -# Composer -/vendor/ -contributors.md - -# Screenshots for e2e tests failures -/screenshots/ diff --git a/composer.json b/composer.json index 5e63a416137..82ad2e52fc8 100644 --- a/composer.json +++ b/composer.json @@ -10,9 +10,6 @@ "composer/installers" : "~1.0" }, "autoload": { - "psr-4": { - "WooCommerce\\": "src/" - }, - "classmap": ["src/RestApi/V1", "src/RestApi/V2", "src/RestApi/V3", "src/RestApi/wc-blocks"] + "classmap": ["src"] } } diff --git a/init.php b/init.php new file mode 100644 index 00000000000..d761c9af059 --- /dev/null +++ b/init.php @@ -0,0 +1,11 @@ +init(); +}; diff --git a/src/Autoloader.php b/src/Autoloader.php new file mode 100644 index 00000000000..34b0884f911 --- /dev/null +++ b/src/Autoloader.php @@ -0,0 +1,70 @@ +get_file_name_from_class( $class ); + $dir = trailingslashit( dirname( __FILE__ ) ); + + // Non-namespaced files. + if ( stristr( $class, 'WC_REST_' ) ) { + if ( stristr( $class, 'WC_REST_Blocks' ) ) { + $subdir = 'wc-blocks/'; + } elseif ( stristr( $class, '_V1_' ) ) { + $subdir = 'v1/'; + } elseif ( stristr( $class, '_V2_' ) ) { + $subdir = 'v2/'; + } else { + $subdir = 'v3/'; + } + + if ( file_exists( $dir . $subdir . $file ) ) { + include $dir . $subdir . $file; + return; + } + } + + if ( file_exists( $dir . $class . '.php' ) ) { + include $dir . $class . '.php'; + return; + } + + if ( file_exists( $dir . $file ) ) { + include $dir . $file; + return; + } + } +} diff --git a/src/RestApi.php b/src/RestApi.php index ecc20286b55..345bad0f0d0 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -24,38 +24,17 @@ class RestApi { */ protected $endpoints = []; - /** - * REST API package version. - * - * @var string - */ - protected $version; - /** * Hook into WordPress ready to init the REST API as needed. */ public function init() { + // Get the autoloader for this version of the API. + if ( file_exists( __DIR__ . '/../vendor/autoload.php' ) ) { + require __DIR__ . '/../vendor/autoload.php'; + } add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); } - /** - * Return REST API package version. - * - * @return string - */ - public function get_version() { - return $this->version; - } - - /** - * Set REST API package version. - * - * @param string $version Version to set. - */ - public function set_version( $version ) { - $this->version = $version; - } - /** * Register REST API routes. */ diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 00000000000..f8128b854ed --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 00000000000..f27399a042d --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000000..1d76a2cd496 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,110 @@ + $baseDir . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php', + 'WC_REST_Blocks_Product_Attributes_Controller' => $baseDir . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php', + 'WC_REST_Blocks_Product_Categories_Controller' => $baseDir . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-categories-controller.php', + 'WC_REST_Blocks_Products_Controller' => $baseDir . '/src/RestApi/wc-blocks/class-wc-rest-blocks-products-controller.php', + 'WC_REST_CRUD_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php', + 'WooCommerce\\RestApi' => $baseDir . '/src/RestApi.php', + 'WooCommerce\\Utilities\\SingletonTrait' => $baseDir . '/src/Utilities/SingletonTrait.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000000..b7fc0125dbc --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInitf71e7bc9895f702f48d84a180f514421::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 00000000000..75978765673 --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,120 @@ + __DIR__ . '/../..' . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php', + 'WC_REST_Blocks_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php', + 'WC_REST_Blocks_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-categories-controller.php', + 'WC_REST_Blocks_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/wc-blocks/class-wc-rest-blocks-products-controller.php', + 'WC_REST_CRUD_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php', + 'WooCommerce\\RestApi' => __DIR__ . '/../..' . '/src/RestApi.php', + 'WooCommerce\\Utilities\\SingletonTrait' => __DIR__ . '/../..' . '/src/Utilities/SingletonTrait.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->classMap = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1 @@ +[] diff --git a/version.php b/version.php new file mode 100644 index 00000000000..bd963c406c1 --- /dev/null +++ b/version.php @@ -0,0 +1,8 @@ +set_version( $version ); - $rest_api->init(); -}; +$version = include __DIR__ . '/version.php'; +$init_callback = include __DIR__ . '/init.php'; /** * This callback registers this version of the API with WooCommerce. From d8fb17a0edf789740f6b0a2c747fcfcfa705f236 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 May 2019 16:39:55 +0100 Subject: [PATCH 010/440] Remove old autoloader --- src/Autoloader.php | 70 ---------------------------------------------- src/RestApi.php | 8 +++--- 2 files changed, 4 insertions(+), 74 deletions(-) delete mode 100644 src/Autoloader.php diff --git a/src/Autoloader.php b/src/Autoloader.php deleted file mode 100644 index 34b0884f911..00000000000 --- a/src/Autoloader.php +++ /dev/null @@ -1,70 +0,0 @@ -get_file_name_from_class( $class ); - $dir = trailingslashit( dirname( __FILE__ ) ); - - // Non-namespaced files. - if ( stristr( $class, 'WC_REST_' ) ) { - if ( stristr( $class, 'WC_REST_Blocks' ) ) { - $subdir = 'wc-blocks/'; - } elseif ( stristr( $class, '_V1_' ) ) { - $subdir = 'v1/'; - } elseif ( stristr( $class, '_V2_' ) ) { - $subdir = 'v2/'; - } else { - $subdir = 'v3/'; - } - - if ( file_exists( $dir . $subdir . $file ) ) { - include $dir . $subdir . $file; - return; - } - } - - if ( file_exists( $dir . $class . '.php' ) ) { - include $dir . $class . '.php'; - return; - } - - if ( file_exists( $dir . $file ) ) { - include $dir . $file; - return; - } - } -} diff --git a/src/RestApi.php b/src/RestApi.php index 345bad0f0d0..9090d54e35d 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -9,6 +9,10 @@ namespace WooCommerce; defined( 'ABSPATH' ) || exit; +if ( file_exists( __DIR__ . '/../vendor/autoload.php' ) ) { + require __DIR__ . '/../vendor/autoload.php'; +} + use WooCommerce\Utilities\SingletonTrait; /** @@ -28,10 +32,6 @@ class RestApi { * Hook into WordPress ready to init the REST API as needed. */ public function init() { - // Get the autoloader for this version of the API. - if ( file_exists( __DIR__ . '/../vendor/autoload.php' ) ) { - require __DIR__ . '/../vendor/autoload.php'; - } add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); } From ec721630ffcb0d9b57c72e3e74a6bb5f70413266 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 May 2019 16:56:55 +0100 Subject: [PATCH 011/440] Rename subdirs --- src/RestApi.php | 2 +- ...cks-product-attribute-terms-controller.php | 0 ...t-blocks-product-attributes-controller.php | 0 ...t-blocks-product-categories-controller.php | 0 ...ass-wc-rest-blocks-products-controller.php | 0 .../class-wc-rest-coupons-v1-controller.php | 0 ...-rest-customer-downloads-v1-controller.php | 0 .../class-wc-rest-customers-v1-controller.php | 0 ...lass-wc-rest-order-notes-v1-controller.php | 0 ...ss-wc-rest-order-refunds-v1-controller.php | 0 .../class-wc-rest-orders-v1-controller.php | 0 ...-product-attribute-terms-v1-controller.php | 0 ...-rest-product-attributes-v1-controller.php | 0 ...-rest-product-categories-v1-controller.php | 0 ...-wc-rest-product-reviews-v1-controller.php | 0 ...product-shipping-classes-v1-controller.php | 0 ...ass-wc-rest-product-tags-v1-controller.php | 0 .../class-wc-rest-products-v1-controller.php | 0 ...ass-wc-rest-report-sales-v1-controller.php | 0 ...-rest-report-top-sellers-v1-controller.php | 0 .../class-wc-rest-reports-v1-controller.php | 0 ...lass-wc-rest-tax-classes-v1-controller.php | 0 .../class-wc-rest-taxes-v1-controller.php | 0 ...-rest-webhook-deliveries-v1-controller.php | 0 .../class-wc-rest-webhooks-v1-controller.php | 0 .../class-wc-rest-coupons-v2-controller.php | 0 ...-rest-customer-downloads-v2-controller.php | 0 .../class-wc-rest-customers-v2-controller.php | 0 ...s-wc-rest-network-orders-v2-controller.php | 0 ...lass-wc-rest-order-notes-v2-controller.php | 0 ...ss-wc-rest-order-refunds-v2-controller.php | 0 .../class-wc-rest-orders-v2-controller.php | 0 ...wc-rest-payment-gateways-v2-controller.php | 0 ...-product-attribute-terms-v2-controller.php | 0 ...-rest-product-attributes-v2-controller.php | 0 ...-rest-product-categories-v2-controller.php | 0 ...-wc-rest-product-reviews-v2-controller.php | 0 ...product-shipping-classes-v2-controller.php | 0 ...ass-wc-rest-product-tags-v2-controller.php | 0 ...-rest-product-variations-v2-controller.php | 0 .../class-wc-rest-products-v2-controller.php | 0 ...ass-wc-rest-report-sales-v2-controller.php | 0 ...-rest-report-top-sellers-v2-controller.php | 0 .../class-wc-rest-reports-v2-controller.php | 0 ...-wc-rest-setting-options-v2-controller.php | 0 .../class-wc-rest-settings-v2-controller.php | 0 ...wc-rest-shipping-methods-v2-controller.php | 0 ...-shipping-zone-locations-v2-controller.php | 0 ...st-shipping-zone-methods-v2-controller.php | 0 ...s-wc-rest-shipping-zones-v2-controller.php | 0 ...rest-system-status-tools-v2-controller.php | 0 ...ss-wc-rest-system-status-v2-controller.php | 0 ...lass-wc-rest-tax-classes-v2-controller.php | 0 .../class-wc-rest-taxes-v2-controller.php | 0 ...-rest-webhook-deliveries-v2-controller.php | 0 .../class-wc-rest-webhooks-v2-controller.php | 0 .../class-wc-rest-controller.php | 0 .../class-wc-rest-coupons-controller.php | 0 .../class-wc-rest-crud-controller.php | 0 ...-wc-rest-customer-downloads-controller.php | 0 .../class-wc-rest-customers-controller.php | 0 ...ass-wc-rest-data-continents-controller.php | 0 .../class-wc-rest-data-controller.php | 0 ...lass-wc-rest-data-countries-controller.php | 0 ...ass-wc-rest-data-currencies-controller.php | 0 ...lass-wc-rest-network-orders-controller.php | 0 .../class-wc-rest-order-notes-controller.php | 0 ...class-wc-rest-order-refunds-controller.php | 0 .../class-wc-rest-orders-controller.php | 0 ...ss-wc-rest-payment-gateways-controller.php | 0 .../class-wc-rest-posts-controller.php | 0 ...est-product-attribute-terms-controller.php | 0 ...-wc-rest-product-attributes-controller.php | 0 ...-wc-rest-product-categories-controller.php | 0 ...ass-wc-rest-product-reviews-controller.php | 0 ...st-product-shipping-classes-controller.php | 0 .../class-wc-rest-product-tags-controller.php | 0 ...-wc-rest-product-variations-controller.php | 0 .../class-wc-rest-products-controller.php | 0 ...-rest-report-coupons-totals-controller.php | 0 ...est-report-customers-totals-controller.php | 0 ...c-rest-report-orders-totals-controller.php | 0 ...rest-report-products-totals-controller.php | 0 ...-rest-report-reviews-totals-controller.php | 0 .../class-wc-rest-report-sales-controller.php | 0 ...-wc-rest-report-top-sellers-controller.php | 0 .../class-wc-rest-reports-controller.php | 0 ...ass-wc-rest-setting-options-controller.php | 0 .../class-wc-rest-settings-controller.php | 0 ...ss-wc-rest-shipping-methods-controller.php | 0 ...est-shipping-zone-locations-controller.php | 0 ...-rest-shipping-zone-methods-controller.php | 0 ...wc-rest-shipping-zones-controller-base.php | 0 ...lass-wc-rest-shipping-zones-controller.php | 0 ...class-wc-rest-system-status-controller.php | 0 ...wc-rest-system-status-tools-controller.php | 0 .../class-wc-rest-tax-classes-controller.php | 0 .../class-wc-rest-taxes-controller.php | 0 .../class-wc-rest-terms-controller.php | 0 .../class-wc-rest-webhooks-controller.php | 0 src/Utilities/SingletonTrait.php | 2 + vendor/composer/autoload_classmap.php | 198 +++++++++--------- vendor/composer/autoload_static.php | 198 +++++++++--------- 103 files changed, 201 insertions(+), 199 deletions(-) rename src/RestApi/{wc-blocks => Blocks/Version1}/class-wc-rest-blocks-product-attribute-terms-controller.php (100%) rename src/RestApi/{wc-blocks => Blocks/Version1}/class-wc-rest-blocks-product-attributes-controller.php (100%) rename src/RestApi/{wc-blocks => Blocks/Version1}/class-wc-rest-blocks-product-categories-controller.php (100%) rename src/RestApi/{wc-blocks => Blocks/Version1}/class-wc-rest-blocks-products-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-coupons-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-customer-downloads-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-customers-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-order-notes-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-order-refunds-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-orders-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-product-attribute-terms-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-product-attributes-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-product-categories-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-product-reviews-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-product-shipping-classes-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-product-tags-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-products-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-report-sales-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-report-top-sellers-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-reports-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-tax-classes-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-taxes-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-webhook-deliveries-v1-controller.php (100%) rename src/RestApi/{V1 => Version1}/class-wc-rest-webhooks-v1-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-coupons-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-customer-downloads-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-customers-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-network-orders-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-order-notes-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-order-refunds-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-orders-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-payment-gateways-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-product-attribute-terms-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-product-attributes-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-product-categories-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-product-reviews-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-product-shipping-classes-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-product-tags-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-product-variations-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-products-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-report-sales-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-report-top-sellers-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-reports-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-setting-options-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-settings-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-shipping-methods-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-shipping-zone-locations-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-shipping-zone-methods-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-shipping-zones-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-system-status-tools-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-system-status-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-tax-classes-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-taxes-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-webhook-deliveries-v2-controller.php (100%) rename src/RestApi/{V2 => Version2}/class-wc-rest-webhooks-v2-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-coupons-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-crud-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-customer-downloads-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-customers-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-data-continents-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-data-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-data-countries-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-data-currencies-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-network-orders-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-order-notes-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-order-refunds-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-orders-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-payment-gateways-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-posts-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-product-attribute-terms-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-product-attributes-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-product-categories-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-product-reviews-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-product-shipping-classes-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-product-tags-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-product-variations-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-products-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-report-coupons-totals-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-report-customers-totals-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-report-orders-totals-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-report-products-totals-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-report-reviews-totals-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-report-sales-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-report-top-sellers-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-reports-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-setting-options-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-settings-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-shipping-methods-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-shipping-zone-locations-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-shipping-zone-methods-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-shipping-zones-controller-base.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-shipping-zones-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-system-status-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-system-status-tools-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-tax-classes-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-taxes-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-terms-controller.php (100%) rename src/RestApi/{V3 => Version3}/class-wc-rest-webhooks-controller.php (100%) diff --git a/src/RestApi.php b/src/RestApi.php index 9090d54e35d..ec73a0d2bdf 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -178,6 +178,6 @@ class RestApi { 'WC_REST_Blocks_Products_Controller', ]; } - return array(); + return []; } } diff --git a/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php similarity index 100% rename from src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php rename to src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php diff --git a/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php similarity index 100% rename from src/RestApi/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php rename to src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php diff --git a/src/RestApi/wc-blocks/class-wc-rest-blocks-product-categories-controller.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php similarity index 100% rename from src/RestApi/wc-blocks/class-wc-rest-blocks-product-categories-controller.php rename to src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php diff --git a/src/RestApi/wc-blocks/class-wc-rest-blocks-products-controller.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php similarity index 100% rename from src/RestApi/wc-blocks/class-wc-rest-blocks-products-controller.php rename to src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php diff --git a/src/RestApi/V1/class-wc-rest-coupons-v1-controller.php b/src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-coupons-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php b/src/RestApi/Version1/class-wc-rest-customer-downloads-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-customer-downloads-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-customers-v1-controller.php b/src/RestApi/Version1/class-wc-rest-customers-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-customers-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-customers-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php b/src/RestApi/Version1/class-wc-rest-order-notes-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-order-notes-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php b/src/RestApi/Version1/class-wc-rest-order-refunds-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-order-refunds-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-orders-v1-controller.php b/src/RestApi/Version1/class-wc-rest-orders-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-orders-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-orders-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php b/src/RestApi/Version1/class-wc-rest-product-attribute-terms-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-product-attribute-terms-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php b/src/RestApi/Version1/class-wc-rest-product-attributes-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-product-attributes-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php b/src/RestApi/Version1/class-wc-rest-product-categories-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-product-categories-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php b/src/RestApi/Version1/class-wc-rest-product-reviews-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-product-reviews-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php b/src/RestApi/Version1/class-wc-rest-product-shipping-classes-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-product-shipping-classes-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php b/src/RestApi/Version1/class-wc-rest-product-tags-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-product-tags-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-products-v1-controller.php b/src/RestApi/Version1/class-wc-rest-products-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-products-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-products-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php b/src/RestApi/Version1/class-wc-rest-report-sales-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-report-sales-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php b/src/RestApi/Version1/class-wc-rest-report-top-sellers-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-report-top-sellers-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-reports-v1-controller.php b/src/RestApi/Version1/class-wc-rest-reports-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-reports-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-reports-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php b/src/RestApi/Version1/class-wc-rest-tax-classes-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-tax-classes-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-taxes-v1-controller.php b/src/RestApi/Version1/class-wc-rest-taxes-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-taxes-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-taxes-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php b/src/RestApi/Version1/class-wc-rest-webhook-deliveries-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-webhook-deliveries-v1-controller.php diff --git a/src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php b/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php similarity index 100% rename from src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php rename to src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php diff --git a/src/RestApi/V2/class-wc-rest-coupons-v2-controller.php b/src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-coupons-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php b/src/RestApi/Version2/class-wc-rest-customer-downloads-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-customer-downloads-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-customers-v2-controller.php b/src/RestApi/Version2/class-wc-rest-customers-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-customers-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-customers-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php b/src/RestApi/Version2/class-wc-rest-network-orders-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-network-orders-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php b/src/RestApi/Version2/class-wc-rest-order-notes-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-order-notes-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php b/src/RestApi/Version2/class-wc-rest-order-refunds-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-order-refunds-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-orders-v2-controller.php b/src/RestApi/Version2/class-wc-rest-orders-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-orders-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-orders-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php b/src/RestApi/Version2/class-wc-rest-payment-gateways-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-payment-gateways-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php b/src/RestApi/Version2/class-wc-rest-product-attribute-terms-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-product-attribute-terms-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php b/src/RestApi/Version2/class-wc-rest-product-attributes-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-product-attributes-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php b/src/RestApi/Version2/class-wc-rest-product-categories-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-product-categories-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php b/src/RestApi/Version2/class-wc-rest-product-reviews-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-product-reviews-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php b/src/RestApi/Version2/class-wc-rest-product-shipping-classes-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-product-shipping-classes-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php b/src/RestApi/Version2/class-wc-rest-product-tags-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-product-tags-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php b/src/RestApi/Version2/class-wc-rest-product-variations-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-product-variations-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-products-v2-controller.php b/src/RestApi/Version2/class-wc-rest-products-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-products-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-products-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php b/src/RestApi/Version2/class-wc-rest-report-sales-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-report-sales-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php b/src/RestApi/Version2/class-wc-rest-report-top-sellers-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-report-top-sellers-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-reports-v2-controller.php b/src/RestApi/Version2/class-wc-rest-reports-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-reports-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-reports-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php b/src/RestApi/Version2/class-wc-rest-setting-options-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-setting-options-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-settings-v2-controller.php b/src/RestApi/Version2/class-wc-rest-settings-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-settings-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-settings-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php b/src/RestApi/Version2/class-wc-rest-shipping-methods-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-shipping-methods-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php b/src/RestApi/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php b/src/RestApi/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php b/src/RestApi/Version2/class-wc-rest-shipping-zones-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-shipping-zones-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php b/src/RestApi/Version2/class-wc-rest-system-status-tools-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-system-status-tools-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-system-status-v2-controller.php b/src/RestApi/Version2/class-wc-rest-system-status-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-system-status-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-system-status-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php b/src/RestApi/Version2/class-wc-rest-tax-classes-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-tax-classes-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-taxes-v2-controller.php b/src/RestApi/Version2/class-wc-rest-taxes-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-taxes-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-taxes-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php b/src/RestApi/Version2/class-wc-rest-webhook-deliveries-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-webhook-deliveries-v2-controller.php diff --git a/src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php b/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php similarity index 100% rename from src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php rename to src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php diff --git a/src/RestApi/V3/class-wc-rest-controller.php b/src/RestApi/Version3/class-wc-rest-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-controller.php rename to src/RestApi/Version3/class-wc-rest-controller.php diff --git a/src/RestApi/V3/class-wc-rest-coupons-controller.php b/src/RestApi/Version3/class-wc-rest-coupons-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-coupons-controller.php rename to src/RestApi/Version3/class-wc-rest-coupons-controller.php diff --git a/src/RestApi/V3/class-wc-rest-crud-controller.php b/src/RestApi/Version3/class-wc-rest-crud-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-crud-controller.php rename to src/RestApi/Version3/class-wc-rest-crud-controller.php diff --git a/src/RestApi/V3/class-wc-rest-customer-downloads-controller.php b/src/RestApi/Version3/class-wc-rest-customer-downloads-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-customer-downloads-controller.php rename to src/RestApi/Version3/class-wc-rest-customer-downloads-controller.php diff --git a/src/RestApi/V3/class-wc-rest-customers-controller.php b/src/RestApi/Version3/class-wc-rest-customers-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-customers-controller.php rename to src/RestApi/Version3/class-wc-rest-customers-controller.php diff --git a/src/RestApi/V3/class-wc-rest-data-continents-controller.php b/src/RestApi/Version3/class-wc-rest-data-continents-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-data-continents-controller.php rename to src/RestApi/Version3/class-wc-rest-data-continents-controller.php diff --git a/src/RestApi/V3/class-wc-rest-data-controller.php b/src/RestApi/Version3/class-wc-rest-data-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-data-controller.php rename to src/RestApi/Version3/class-wc-rest-data-controller.php diff --git a/src/RestApi/V3/class-wc-rest-data-countries-controller.php b/src/RestApi/Version3/class-wc-rest-data-countries-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-data-countries-controller.php rename to src/RestApi/Version3/class-wc-rest-data-countries-controller.php diff --git a/src/RestApi/V3/class-wc-rest-data-currencies-controller.php b/src/RestApi/Version3/class-wc-rest-data-currencies-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-data-currencies-controller.php rename to src/RestApi/Version3/class-wc-rest-data-currencies-controller.php diff --git a/src/RestApi/V3/class-wc-rest-network-orders-controller.php b/src/RestApi/Version3/class-wc-rest-network-orders-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-network-orders-controller.php rename to src/RestApi/Version3/class-wc-rest-network-orders-controller.php diff --git a/src/RestApi/V3/class-wc-rest-order-notes-controller.php b/src/RestApi/Version3/class-wc-rest-order-notes-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-order-notes-controller.php rename to src/RestApi/Version3/class-wc-rest-order-notes-controller.php diff --git a/src/RestApi/V3/class-wc-rest-order-refunds-controller.php b/src/RestApi/Version3/class-wc-rest-order-refunds-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-order-refunds-controller.php rename to src/RestApi/Version3/class-wc-rest-order-refunds-controller.php diff --git a/src/RestApi/V3/class-wc-rest-orders-controller.php b/src/RestApi/Version3/class-wc-rest-orders-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-orders-controller.php rename to src/RestApi/Version3/class-wc-rest-orders-controller.php diff --git a/src/RestApi/V3/class-wc-rest-payment-gateways-controller.php b/src/RestApi/Version3/class-wc-rest-payment-gateways-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-payment-gateways-controller.php rename to src/RestApi/Version3/class-wc-rest-payment-gateways-controller.php diff --git a/src/RestApi/V3/class-wc-rest-posts-controller.php b/src/RestApi/Version3/class-wc-rest-posts-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-posts-controller.php rename to src/RestApi/Version3/class-wc-rest-posts-controller.php diff --git a/src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php b/src/RestApi/Version3/class-wc-rest-product-attribute-terms-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php rename to src/RestApi/Version3/class-wc-rest-product-attribute-terms-controller.php diff --git a/src/RestApi/V3/class-wc-rest-product-attributes-controller.php b/src/RestApi/Version3/class-wc-rest-product-attributes-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-product-attributes-controller.php rename to src/RestApi/Version3/class-wc-rest-product-attributes-controller.php diff --git a/src/RestApi/V3/class-wc-rest-product-categories-controller.php b/src/RestApi/Version3/class-wc-rest-product-categories-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-product-categories-controller.php rename to src/RestApi/Version3/class-wc-rest-product-categories-controller.php diff --git a/src/RestApi/V3/class-wc-rest-product-reviews-controller.php b/src/RestApi/Version3/class-wc-rest-product-reviews-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-product-reviews-controller.php rename to src/RestApi/Version3/class-wc-rest-product-reviews-controller.php diff --git a/src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php b/src/RestApi/Version3/class-wc-rest-product-shipping-classes-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php rename to src/RestApi/Version3/class-wc-rest-product-shipping-classes-controller.php diff --git a/src/RestApi/V3/class-wc-rest-product-tags-controller.php b/src/RestApi/Version3/class-wc-rest-product-tags-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-product-tags-controller.php rename to src/RestApi/Version3/class-wc-rest-product-tags-controller.php diff --git a/src/RestApi/V3/class-wc-rest-product-variations-controller.php b/src/RestApi/Version3/class-wc-rest-product-variations-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-product-variations-controller.php rename to src/RestApi/Version3/class-wc-rest-product-variations-controller.php diff --git a/src/RestApi/V3/class-wc-rest-products-controller.php b/src/RestApi/Version3/class-wc-rest-products-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-products-controller.php rename to src/RestApi/Version3/class-wc-rest-products-controller.php diff --git a/src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php b/src/RestApi/Version3/class-wc-rest-report-coupons-totals-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php rename to src/RestApi/Version3/class-wc-rest-report-coupons-totals-controller.php diff --git a/src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php b/src/RestApi/Version3/class-wc-rest-report-customers-totals-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php rename to src/RestApi/Version3/class-wc-rest-report-customers-totals-controller.php diff --git a/src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php b/src/RestApi/Version3/class-wc-rest-report-orders-totals-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php rename to src/RestApi/Version3/class-wc-rest-report-orders-totals-controller.php diff --git a/src/RestApi/V3/class-wc-rest-report-products-totals-controller.php b/src/RestApi/Version3/class-wc-rest-report-products-totals-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-report-products-totals-controller.php rename to src/RestApi/Version3/class-wc-rest-report-products-totals-controller.php diff --git a/src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php b/src/RestApi/Version3/class-wc-rest-report-reviews-totals-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php rename to src/RestApi/Version3/class-wc-rest-report-reviews-totals-controller.php diff --git a/src/RestApi/V3/class-wc-rest-report-sales-controller.php b/src/RestApi/Version3/class-wc-rest-report-sales-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-report-sales-controller.php rename to src/RestApi/Version3/class-wc-rest-report-sales-controller.php diff --git a/src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php b/src/RestApi/Version3/class-wc-rest-report-top-sellers-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php rename to src/RestApi/Version3/class-wc-rest-report-top-sellers-controller.php diff --git a/src/RestApi/V3/class-wc-rest-reports-controller.php b/src/RestApi/Version3/class-wc-rest-reports-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-reports-controller.php rename to src/RestApi/Version3/class-wc-rest-reports-controller.php diff --git a/src/RestApi/V3/class-wc-rest-setting-options-controller.php b/src/RestApi/Version3/class-wc-rest-setting-options-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-setting-options-controller.php rename to src/RestApi/Version3/class-wc-rest-setting-options-controller.php diff --git a/src/RestApi/V3/class-wc-rest-settings-controller.php b/src/RestApi/Version3/class-wc-rest-settings-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-settings-controller.php rename to src/RestApi/Version3/class-wc-rest-settings-controller.php diff --git a/src/RestApi/V3/class-wc-rest-shipping-methods-controller.php b/src/RestApi/Version3/class-wc-rest-shipping-methods-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-shipping-methods-controller.php rename to src/RestApi/Version3/class-wc-rest-shipping-methods-controller.php diff --git a/src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php b/src/RestApi/Version3/class-wc-rest-shipping-zone-locations-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php rename to src/RestApi/Version3/class-wc-rest-shipping-zone-locations-controller.php diff --git a/src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php b/src/RestApi/Version3/class-wc-rest-shipping-zone-methods-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php rename to src/RestApi/Version3/class-wc-rest-shipping-zone-methods-controller.php diff --git a/src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php b/src/RestApi/Version3/class-wc-rest-shipping-zones-controller-base.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php rename to src/RestApi/Version3/class-wc-rest-shipping-zones-controller-base.php diff --git a/src/RestApi/V3/class-wc-rest-shipping-zones-controller.php b/src/RestApi/Version3/class-wc-rest-shipping-zones-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-shipping-zones-controller.php rename to src/RestApi/Version3/class-wc-rest-shipping-zones-controller.php diff --git a/src/RestApi/V3/class-wc-rest-system-status-controller.php b/src/RestApi/Version3/class-wc-rest-system-status-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-system-status-controller.php rename to src/RestApi/Version3/class-wc-rest-system-status-controller.php diff --git a/src/RestApi/V3/class-wc-rest-system-status-tools-controller.php b/src/RestApi/Version3/class-wc-rest-system-status-tools-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-system-status-tools-controller.php rename to src/RestApi/Version3/class-wc-rest-system-status-tools-controller.php diff --git a/src/RestApi/V3/class-wc-rest-tax-classes-controller.php b/src/RestApi/Version3/class-wc-rest-tax-classes-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-tax-classes-controller.php rename to src/RestApi/Version3/class-wc-rest-tax-classes-controller.php diff --git a/src/RestApi/V3/class-wc-rest-taxes-controller.php b/src/RestApi/Version3/class-wc-rest-taxes-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-taxes-controller.php rename to src/RestApi/Version3/class-wc-rest-taxes-controller.php diff --git a/src/RestApi/V3/class-wc-rest-terms-controller.php b/src/RestApi/Version3/class-wc-rest-terms-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-terms-controller.php rename to src/RestApi/Version3/class-wc-rest-terms-controller.php diff --git a/src/RestApi/V3/class-wc-rest-webhooks-controller.php b/src/RestApi/Version3/class-wc-rest-webhooks-controller.php similarity index 100% rename from src/RestApi/V3/class-wc-rest-webhooks-controller.php rename to src/RestApi/Version3/class-wc-rest-webhooks-controller.php diff --git a/src/Utilities/SingletonTrait.php b/src/Utilities/SingletonTrait.php index b780f86f23c..5190f079023 100644 --- a/src/Utilities/SingletonTrait.php +++ b/src/Utilities/SingletonTrait.php @@ -2,6 +2,8 @@ /** * Abstract singleton class. * + * TODO: move to core? + * * @package WooCommerce/Utilities */ diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 1d76a2cd496..cc30854ff9e 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,105 +6,105 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( - 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php', - 'WC_REST_Blocks_Product_Attributes_Controller' => $baseDir . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php', - 'WC_REST_Blocks_Product_Categories_Controller' => $baseDir . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-categories-controller.php', - 'WC_REST_Blocks_Products_Controller' => $baseDir . '/src/RestApi/wc-blocks/class-wc-rest-blocks-products-controller.php', - 'WC_REST_CRUD_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-controller.php', - 'WC_REST_Coupons_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => $baseDir . '/src/RestApi/V3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php', + 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php', + 'WC_REST_Blocks_Product_Attributes_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php', + 'WC_REST_Blocks_Product_Categories_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php', + 'WC_REST_Blocks_Products_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php', + 'WC_REST_CRUD_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php', 'WooCommerce\\RestApi' => $baseDir . '/src/RestApi.php', 'WooCommerce\\Utilities\\SingletonTrait' => $baseDir . '/src/Utilities/SingletonTrait.php', ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 75978765673..d9c3939a6fa 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -7,105 +7,105 @@ namespace Composer\Autoload; class ComposerStaticInitf71e7bc9895f702f48d84a180f514421 { public static $classMap = array ( - 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attribute-terms-controller.php', - 'WC_REST_Blocks_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-attributes-controller.php', - 'WC_REST_Blocks_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/wc-blocks/class-wc-rest-blocks-product-categories-controller.php', - 'WC_REST_Blocks_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/wc-blocks/class-wc-rest-blocks-products-controller.php', - 'WC_REST_CRUD_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-controller.php', - 'WC_REST_Coupons_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => __DIR__ . '/../..' . '/src/RestApi/V3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/V1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/V2/class-wc-rest-webhooks-v2-controller.php', + 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php', + 'WC_REST_Blocks_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php', + 'WC_REST_Blocks_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php', + 'WC_REST_Blocks_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php', + 'WC_REST_CRUD_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php', 'WooCommerce\\RestApi' => __DIR__ . '/../..' . '/src/RestApi.php', 'WooCommerce\\Utilities\\SingletonTrait' => __DIR__ . '/../..' . '/src/Utilities/SingletonTrait.php', ); From 15107d237867f36fe596717060e0a1fce326b620 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 May 2019 17:23:41 +0100 Subject: [PATCH 012/440] gitattributes --- .gitattributes | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..f125c3166c7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +/.* export-ignore +composer.* export-ignore +Gruntfile.js export-ignore +package.json export-ignore +package-lock.json export-ignore +phpcs.xml export-ignore +phpunit.* export-ignore +tests export-ignore From c8526719947520bb0798e17b0ea1ff742ead5135 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 11:20:56 +0100 Subject: [PATCH 013/440] Copy over v4 and creating working dir --- .../class-wc-rest-coupons-v1-controller.php | 801 +++++ ...-rest-customer-downloads-v1-controller.php | 252 ++ .../class-wc-rest-customers-v1-controller.php | 924 ++++++ ...lass-wc-rest-order-notes-v1-controller.php | 439 +++ ...ss-wc-rest-order-refunds-v1-controller.php | 530 ++++ .../class-wc-rest-orders-v1-controller.php | 1629 ++++++++++ ...-product-attribute-terms-v1-controller.php | 240 ++ ...-rest-product-attributes-v1-controller.php | 586 ++++ ...-rest-product-categories-v1-controller.php | 271 ++ ...-wc-rest-product-reviews-v1-controller.php | 578 ++++ ...product-shipping-classes-v1-controller.php | 134 + ...ass-wc-rest-product-tags-v1-controller.php | 134 + .../class-wc-rest-products-v1-controller.php | 2641 +++++++++++++++++ ...ass-wc-rest-report-sales-v1-controller.php | 397 +++ ...-rest-report-top-sellers-v1-controller.php | 174 ++ .../class-wc-rest-reports-v1-controller.php | 184 ++ ...lass-wc-rest-tax-classes-v1-controller.php | 364 +++ .../class-wc-rest-taxes-v1-controller.php | 709 +++++ ...-rest-webhook-deliveries-v1-controller.php | 314 ++ .../class-wc-rest-webhooks-v1-controller.php | 763 +++++ ...s-wc-admin-rest-admin-notes-controller.php | 484 +++ ...class-wc-admin-rest-coupons-controller.php | 93 + ...ass-wc-admin-rest-customers-controller.php | 50 + .../class-wc-admin-rest-data-controller.php | 47 + ...c-admin-rest-data-countries-controller.php | 27 + ...dmin-rest-data-download-ips-controller.php | 167 ++ ...-wc-admin-rest-leaderboards-controller.php | 546 ++++ ...dmin-rest-onboarding-levels-controller.php | 264 ++ ...min-rest-onboarding-plugins-controller.php | 289 ++ ...min-rest-onboarding-profile-controller.php | 348 +++ .../class-wc-admin-rest-orders-controller.php | 75 + ...min-rest-product-categories-controller.php | 26 + ...-admin-rest-product-reviews-controller.php | 55 + ...min-rest-product-variations-controller.php | 124 + ...lass-wc-admin-rest-products-controller.php | 189 ++ ...min-rest-reports-categories-controller.php | 320 ++ ...class-wc-admin-rest-reports-controller.php | 303 ++ ...-admin-rest-reports-coupons-controller.php | 290 ++ ...-rest-reports-coupons-stats-controller.php | 353 +++ ...dmin-rest-reports-customers-controller.php | 517 ++++ ...est-reports-customers-stats-controller.php | 364 +++ ...dmin-rest-reports-downloads-controller.php | 380 +++ ...est-reports-downloads-files-controller.php | 33 + ...est-reports-downloads-stats-controller.php | 372 +++ ...c-admin-rest-reports-import-controller.php | 315 ++ ...c-admin-rest-reports-orders-controller.php | 377 +++ ...n-rest-reports-orders-stats-controller.php | 493 +++ ...orts-performance-indicators-controller.php | 505 ++++ ...admin-rest-reports-products-controller.php | 344 +++ ...rest-reports-products-stats-controller.php | 416 +++ ...-rest-reports-revenue-stats-controller.php | 402 +++ ...wc-admin-rest-reports-stock-controller.php | 419 +++ ...in-rest-reports-stock-stats-controller.php | 138 + ...wc-admin-rest-reports-taxes-controller.php | 288 ++ ...in-rest-reports-taxes-stats-controller.php | 391 +++ ...min-rest-reports-variations-controller.php | 328 ++ ...-admin-rest-setting-options-controller.php | 27 + .../class-wc-admin-rest-taxes-controller.php | 159 + 58 files changed, 22382 insertions(+) create mode 100644 src/RestApi/AllYourBase/class-wc-rest-coupons-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-customer-downloads-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-customers-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-order-notes-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-order-refunds-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-orders-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-product-attribute-terms-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-product-attributes-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-product-categories-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-product-reviews-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-product-shipping-classes-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-product-tags-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-products-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-report-sales-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-report-top-sellers-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-reports-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-tax-classes-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-taxes-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-webhook-deliveries-v1-controller.php create mode 100644 src/RestApi/AllYourBase/class-wc-rest-webhooks-v1-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-admin-notes-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-coupons-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-customers-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-data-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-orders-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-product-categories-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-product-reviews-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-products-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-categories-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-coupons-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-coupons-stats-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-customers-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-customers-stats-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-downloads-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-downloads-files-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-downloads-stats-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-import-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-orders-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-orders-stats-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-performance-indicators-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-products-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-products-stats-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-revenue-stats-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-stock-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-stock-stats-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-taxes-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-taxes-stats-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-reports-variations-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php create mode 100644 src/RestApi/Version4/class-wc-admin-rest-taxes-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-coupons-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-coupons-v1-controller.php new file mode 100644 index 00000000000..832bbe1993c --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-coupons-v1-controller.php @@ -0,0 +1,801 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for coupons. + */ + public function register_routes() { + register_rest_route( + $this->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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'required' => true, + 'type' => 'string', + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return new WC_Coupon( $id ); + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + + $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); + $format_date = array( 'date_created', 'date_modified', 'date_expires' ); + $format_null = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], 2 ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format null values. + foreach ( $format_null as $key ) { + $data[ $key ] = $data[ $key ] ? $data[ $key ] : null; + } + + return array( + 'id' => $object->get_id(), + 'code' => $data['code'], + 'amount' => $data['amount'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_type' => $data['discount_type'], + 'description' => $data['description'], + 'date_expires' => $data['date_expires'], + 'date_expires_gmt' => $data['date_expires_gmt'], + 'usage_count' => $data['usage_count'], + 'individual_use' => $data['individual_use'], + 'product_ids' => $data['product_ids'], + 'excluded_product_ids' => $data['excluded_product_ids'], + 'usage_limit' => $data['usage_limit'], + 'usage_limit_per_user' => $data['usage_limit_per_user'], + 'limit_usage_to_x_items' => $data['limit_usage_to_x_items'], + 'free_shipping' => $data['free_shipping'], + 'product_categories' => $data['product_categories'], + 'excluded_product_categories' => $data['excluded_product_categories'], + 'exclude_sale_items' => $data['exclude_sale_items'], + 'minimum_amount' => $data['minimum_amount'], + 'maximum_amount' => $data['maximum_amount'], + 'email_restrictions' => $data['email_restrictions'], + 'used_by' => $data['used_by'], + 'meta_data' => $data['meta_data'], + ); + } + + /** + * Prepare a single coupon output for response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = $this->get_formatted_item_data( $object ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + if ( ! empty( $request['code'] ) ) { + $id = wc_get_coupon_id_by_code( $request['code'] ); + $args['post__in'] = array( $id ); + } + + // Get only ids. + $args['fields'] = 'ids'; + + return $args; + } + + /** + * Prepare a single coupon for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $coupon = new WC_Coupon( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Validate required POST fields. + if ( $creating && empty( $request['code'] ) ) { + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + } + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'code': + $coupon_code = wc_format_coupon_code( $value ); + $id = $coupon->get_id() ? $coupon->get_id() : 0; + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon->set_code( $coupon_code ); + break; + case 'meta_data': + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + case 'description': + $coupon->set_description( wp_filter_post_kses( $value ) ); + break; + default: + if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { + $coupon->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $coupon Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $coupon, $request, $creating ); + } + + /** + * Get the Coupon's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'amount' => array( + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_type' => array( + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'fixed_cart', + 'enum' => array_keys( wc_get_coupon_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Coupon description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_expires' => array( + 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_expires_gmt' => array( + 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'usage_count' => array( + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'individual_use' => array( + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_ids' => array( + 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'excluded_product_ids' => array( + 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit' => array( + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit_per_user' => array( + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'limit_usage_to_x_items' => array( + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'free_shipping' => array( + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_categories' => array( + 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'excluded_product_categories' => array( + 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'exclude_sale_items' => array( + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'minimum_amount' => array( + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'maximum_amount' => array( + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email_restrictions' => array( + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + 'used_by' => array( + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['code'] = array( + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Query args. + * + * @param array $args Query args. + * @param WP_REST_Request $request Request data. + * @return array + */ + public function query_args( $args, $request ) { + if ( ! empty( $request['code'] ) ) { + $id = wc_get_coupon_id_by_code( $request['code'] ); + $args['post__in'] = array( $id ); + } + + return $args; + } + + /** + * Prepare a single coupon output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $data + */ + public function prepare_item_for_response( $post, $request ) { + $coupon = new WC_Coupon( (int) $post->ID ); + $_data = $coupon->get_data(); + + $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); + $format_date = array( 'date_created', 'date_modified' ); + $format_date_utc = array( 'date_expires' ); + $format_null = array( 'usage_limit', 'usage_limit_per_user' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $_data[ $key ] = wc_format_decimal( $_data[ $key ], 2 ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ], false ) : null; + } + foreach ( $format_date_utc as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; + } + + // Format null values. + foreach ( $format_null as $key ) { + $_data[ $key ] = $_data[ $key ] ? $_data[ $key ] : null; + } + + $data = array( + 'id' => $_data['id'], + 'code' => $_data['code'], + 'date_created' => $_data['date_created'], + 'date_modified' => $_data['date_modified'], + 'discount_type' => $_data['discount_type'], + 'description' => $_data['description'], + 'amount' => $_data['amount'], + 'expiry_date' => $_data['date_expires'], + 'usage_count' => $_data['usage_count'], + 'individual_use' => $_data['individual_use'], + 'product_ids' => $_data['product_ids'], + 'exclude_product_ids' => $_data['excluded_product_ids'], + 'usage_limit' => $_data['usage_limit'], + 'usage_limit_per_user' => $_data['usage_limit_per_user'], + 'limit_usage_to_x_items' => $_data['limit_usage_to_x_items'], + 'free_shipping' => $_data['free_shipping'], + 'product_categories' => $_data['product_categories'], + 'excluded_product_categories' => $_data['excluded_product_categories'], + 'exclude_sale_items' => $_data['exclude_sale_items'], + 'minimum_amount' => $_data['minimum_amount'], + 'maximum_amount' => $_data['maximum_amount'], + 'email_restrictions' => $_data['email_restrictions'], + 'used_by' => $_data['used_by'], + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $post, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Only return writable props from schema. + * + * @param array $schema Schema array. + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Prepare a single coupon for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $coupon = new WC_Coupon( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Update to schema to make compatible with CRUD schema. + if ( $request['exclude_product_ids'] ) { + $request['excluded_product_ids'] = $request['exclude_product_ids']; + } + if ( $request['expiry_date'] ) { + $request['date_expires'] = $request['expiry_date']; + } + + // Validate required POST fields. + if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { + if ( empty( $request['code'] ) ) { + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + } + } + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'code': + $coupon_code = wc_format_coupon_code( $value ); + $id = $coupon->get_id() ? $coupon->get_id() : 0; + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon->set_code( $coupon_code ); + break; + case 'description': + $coupon->set_description( wp_filter_post_kses( $value ) ); + break; + case 'expiry_date': + $coupon->set_date_expires( $value ); + break; + default: + if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { + $coupon->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param WC_Coupon $coupon The coupon object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request ); + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $coupon_id = $this->save_coupon( $request ); + if ( is_wp_error( $coupon_id ) ) { + return $coupon_id; + } + + $post = get_post( $coupon_id ); + $this->update_additional_fields_for_object( $post, $request ); + + $this->add_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Update a single coupon. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon_id = $this->save_coupon( $request ); + if ( is_wp_error( $coupon_id ) ) { + return $coupon_id; + } + + $post = get_post( $coupon_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-customer-downloads-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-customer-downloads-v1-controller.php new file mode 100644 index 00000000000..904f32fa68d --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-customer-downloads-v1-controller.php @@ -0,0 +1,252 @@ +/downloads endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Customers controller class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Controller + */ +class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'customers/(?P[\d]+)/downloads'; + + /** + * Register the routes for customers. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'customer_id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + 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' ), + ) ); + } + + /** + * Check whether a given request has permission to read customers. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $customer = get_user_by( 'id', (int) $request['customer_id'] ); + + if ( ! $customer ) { + return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_user_permissions( 'read', $customer->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all customer downloads. + * + * @param WP_REST_Request $request + * @return array + */ + public function get_items( $request ) { + $downloads = wc_get_customer_available_downloads( (int) $request['customer_id'] ); + + $data = array(); + foreach ( $downloads as $download_data ) { + $download = $this->prepare_item_for_response( (object) $download_data, $request ); + $download = $this->prepare_response_for_collection( $download ); + $data[] = $download; + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a single download output for response. + * + * @param stdObject $download Download object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $download, $request ) { + $data = (array) $download; + $data['access_expires'] = $data['access_expires'] ? wc_rest_prepare_date_response( $data['access_expires'] ) : 'never'; + $data['downloads_remaining'] = '' === $data['downloads_remaining'] ? 'unlimited' : $data['downloads_remaining']; + + // Remove "product_name" since it's new in 3.0. + unset( $data['product_name'] ); + + $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( $download, $request ) ); + + /** + * Filter customer download data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdObject $download Download object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $download Download object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given customer download. + */ + protected function prepare_links( $download, $request ) { + $base = str_replace( '(?P[\d]+)', $request['customer_id'], $this->rest_base ); + $links = array( + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'product' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $download->product_id ) ), + ), + 'order' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $download->order_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Customer Download's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer_download', + 'type' => 'object', + 'properties' => array( + 'download_url' => array( + 'description' => __( 'Download file URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_id' => array( + 'description' => __( 'Download ID (MD5).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Downloadable product ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_name' => array( + 'description' => __( 'Downloadable file name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_id' => array( + 'description' => __( 'Order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'downloads_remaining' => array( + 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'access_expires' => array( + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File details.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-customers-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-customers-v1-controller.php new file mode 100644 index 00000000000..04b12cd4e47 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-customers-v1-controller.php @@ -0,0 +1,924 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'New user email address.', 'woocommerce' ), + ), + 'username' => array( + 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), + 'description' => __( 'New user username.', 'woocommerce' ), + 'type' => 'string', + ), + 'password' => array( + 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), + 'description' => __( 'New user password.', 'woocommerce' ), + 'type' => 'string', + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + 'reassign' => array( + 'default' => 0, + 'type' => 'integer', + 'description' => __( 'ID to reassign posts to.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read customers. + * + * @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_user_permissions( 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create customers. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_user_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'read', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a customer. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'edit', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a customer. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'delete', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_user_permissions( 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all customers. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $prepared_args = array(); + $prepared_args['exclude'] = $request['exclude']; + $prepared_args['include'] = $request['include']; + $prepared_args['order'] = $request['order']; + $prepared_args['number'] = $request['per_page']; + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + $orderby_possibles = array( + 'id' => 'ID', + 'include' => 'include', + 'name' => 'display_name', + 'registered_date' => 'registered', + ); + $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; + $prepared_args['search'] = $request['search']; + + if ( '' !== $prepared_args['search'] ) { + $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; + } + + // Filter by email. + if ( ! empty( $request['email'] ) ) { + $prepared_args['search'] = $request['email']; + $prepared_args['search_columns'] = array( 'user_email' ); + } + + // Filter by role. + if ( 'all' !== $request['role'] ) { + $prepared_args['role'] = $request['role']; + } + + /** + * Filter arguments, before passing to WP_User_Query, when querying users via the REST API. + * + * @see https://developer.wordpress.org/reference/classes/wp_user_query/ + * + * @param array $prepared_args Array of arguments for WP_User_Query. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_customer_query', $prepared_args, $request ); + + $query = new WP_User_Query( $prepared_args ); + + $users = array(); + foreach ( $query->results as $user ) { + $data = $this->prepare_item_for_response( $user, $request ); + $users[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $users ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + $prepared_args['fields'] = 'ID'; + + $total_users = $query->get_total(); + if ( $total_users < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $prepared_args['number'] ); + unset( $prepared_args['offset'] ); + $count_query = new WP_User_Query( $prepared_args ); + $total_users = $count_query->get_total(); + } + $response->header( 'X-WP-Total', (int) $total_users ); + $max_pages = ceil( $total_users / $per_page ); + $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; + } + + /** + * Create a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + try { + if ( ! empty( $request['id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); + } + + // Sets the username. + $request['username'] = ! empty( $request['username'] ) ? $request['username'] : ''; + + // Sets the password. + $request['password'] = ! empty( $request['password'] ) ? $request['password'] : ''; + + // Create customer. + $customer = new WC_Customer; + $customer->set_username( $request['username'] ); + $customer->set_password( $request['password'] ); + $customer->set_email( $request['email'] ); + $this->update_customer_meta_fields( $customer, $request ); + $customer->save(); + + if ( ! $customer->get_id() ) { + throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); + } + + $user_data = get_userdata( $customer->get_id() ); + $this->update_additional_fields_for_object( $user_data, $request ); + + /** + * Fires after a customer is created or updated via the REST API. + * + * @param WP_User $user_data Data used to create the customer. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating customer, false when updating customer. + */ + do_action( 'woocommerce_rest_insert_customer', $user_data, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ) ); + + return $response; + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $user_data = get_userdata( $id ); + + if ( empty( $id ) || empty( $user_data->ID ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $customer = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $customer ); + + return $response; + } + + /** + * Update a single user. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $id = (int) $request['id']; + $customer = new WC_Customer( $id ); + + if ( ! $customer->get_id() ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); + } + + if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->get_email() ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); + } + + if ( ! empty( $request['username'] ) && $request['username'] !== $customer->get_username() ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); + } + + // Customer email. + if ( isset( $request['email'] ) ) { + $customer->set_email( sanitize_email( $request['email'] ) ); + } + + // Customer password. + if ( isset( $request['password'] ) ) { + $customer->set_password( $request['password'] ); + } + + $this->update_customer_meta_fields( $customer, $request ); + $customer->save(); + + $user_data = get_userdata( $customer->get_id() ); + $this->update_additional_fields_for_object( $user_data, $request ); + + if ( ! is_user_member_of_blog( $user_data->ID ) ) { + $user_data->add_role( 'customer' ); + } + + /** + * Fires after a customer is created or updated via the REST API. + * + * @param WP_User $customer Data used to create the customer. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating customer, false when updating customer. + */ + do_action( 'woocommerce_rest_insert_customer', $user_data, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $response ); + return $response; + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $reassign = isset( $request['reassign'] ) ? absint( $request['reassign'] ) : null; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $user_data = get_userdata( $id ); + if ( ! $user_data ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + if ( ! empty( $reassign ) ) { + if ( $reassign === $id || ! get_userdata( $reassign ) ) { + return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + + /** Include admin customer functions to get access to wp_delete_user() */ + require_once ABSPATH . 'wp-admin/includes/user.php'; + + $customer = new WC_Customer( $id ); + + if ( ! is_null( $reassign ) ) { + $result = $customer->delete_and_reassign( $reassign ); + } else { + $result = $customer->delete(); + } + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a customer is deleted via the REST API. + * + * @param WP_User $user_data User data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_customer', $user_data, $response, $request ); + + return $response; + } + + /** + * Prepare a single customer output for response. + * + * @param WP_User $user_data User object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $user_data, $request ) { + $customer = new WC_Customer( $user_data->ID ); + $_data = $customer->get_data(); + $last_order = wc_get_customer_last_order( $customer->get_id() ); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; // v1 API used UTC. + } + + $data = array( + 'id' => $_data['id'], + 'date_created' => $_data['date_created'], + 'date_modified' => $_data['date_modified'], + 'email' => $_data['email'], + 'first_name' => $_data['first_name'], + 'last_name' => $_data['last_name'], + 'username' => $_data['username'], + 'last_order' => array( + 'id' => is_object( $last_order ) ? $last_order->get_id() : null, + 'date' => is_object( $last_order ) ? wc_rest_prepare_date_response( $last_order->get_date_created() ) : null, // v1 API used UTC. + ), + 'orders_count' => $customer->get_order_count(), + 'total_spent' => $customer->get_total_spent(), + 'avatar_url' => $customer->get_avatar_url(), + 'billing' => $_data['billing'], + 'shipping' => $_data['shipping'], + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $user_data ) ); + + /** + * Filter customer data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_User $user_data User object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); + } + + /** + * Update customer meta fields. + * + * @param WC_Customer $customer + * @param WP_REST_Request $request + */ + protected function update_customer_meta_fields( $customer, $request ) { + $schema = $this->get_item_schema(); + + // Customer first name. + if ( isset( $request['first_name'] ) ) { + $customer->set_first_name( wc_clean( $request['first_name'] ) ); + } + + // Customer last name. + if ( isset( $request['last_name'] ) ) { + $customer->set_last_name( wc_clean( $request['last_name'] ) ); + } + + // Customer billing address. + if ( isset( $request['billing'] ) ) { + foreach ( array_keys( $schema['properties']['billing']['properties'] ) as $field ) { + if ( isset( $request['billing'][ $field ] ) && is_callable( array( $customer, "set_billing_{$field}" ) ) ) { + $customer->{"set_billing_{$field}"}( $request['billing'][ $field ] ); + } + } + } + + // Customer shipping address. + if ( isset( $request['shipping'] ) ) { + foreach ( array_keys( $schema['properties']['shipping']['properties'] ) as $field ) { + if ( isset( $request['shipping'][ $field ] ) && is_callable( array( $customer, "set_shipping_{$field}" ) ) ) { + $customer->{"set_shipping_{$field}"}( $request['shipping'][ $field ] ); + } + } + } + } + + /** + * Prepare links for the request. + * + * @param WP_User $customer Customer object. + * @return array Links for the given customer. + */ + protected function prepare_links( $customer ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Customer's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'email' => array( + 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'first_name' => array( + 'description' => __( 'Customer first name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'last_name' => array( + 'description' => __( 'Customer last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'username' => array( + 'description' => __( 'Customer login name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_user', + ), + ), + 'password' => array( + 'description' => __( 'Customer password.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'last_order' => array( + 'description' => __( 'Last order data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => array( + 'id' => array( + 'description' => __( 'Last order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date' => array( + 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + 'orders_count' => array( + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_spent' => array( + 'description' => __( 'Total amount spent.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avatar_url' => array( + 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'billing' => array( + 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get role names. + * + * @return array + */ + protected function get_role_names() { + global $wp_roles; + + return array_keys( $wp_roles->role_names ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $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( + 'default' => 'asc', + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'enum' => array( 'asc', 'desc' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'default' => 'name', + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'enum' => array( + 'id', + 'include', + 'name', + 'registered_date', + ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['email'] = array( + 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['role'] = array( + 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'customer', + 'enum' => array_merge( array( 'all' ), $this->get_role_names() ), + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-order-notes-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-order-notes-v1-controller.php new file mode 100644 index 00000000000..4eac1bd38e0 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-order-notes-v1-controller.php @@ -0,0 +1,439 @@ +/notes endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Order Notes controller class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Controller + */ +class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'orders/(?P[\d]+)/notes'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'shop_order'; + + /** + * Register the routes for order notes. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'note' => array( + 'type' => 'string', + 'description' => __( 'Order note content.', 'woocommerce' ), + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read order 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_post_permissions( $this->post_type, 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create order notes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a order note. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get order notes from an order. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $args = array( + 'post_id' => $order->get_id(), + 'approve' => 'approve', + 'type' => 'order_note', + ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $data = array(); + foreach ( $notes as $note ) { + $order_note = $this->prepare_item_for_response( $note, $request ); + $order_note = $this->prepare_response_for_collection( $order_note ); + $data[] = $order_note; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Create the note. + $note_id = $order->add_order_note( $request['note'], $request['customer_note'] ); + + if ( ! $note_id ) { + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $note = get_comment( $note_id ); + $this->update_additional_fields_for_object( $note, $request ); + + /** + * Fires after a order note is created or updated via the REST API. + * + * @param WP_Comment $note New order note object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $note, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); + + return $response; + } + + /** + * Get a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $note = get_comment( $id ); + + if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $order_note = $this->prepare_item_for_response( $note, $request ); + $response = rest_ensure_response( $order_note ); + + return $response; + } + + /** + * Delete a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $note = get_comment( $id ); + + if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $note, $request ); + + $result = wc_delete_order_note( $note->comment_ID ); + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a order note is deleted or trashed via the REST API. + * + * @param WP_Comment $note The deleted or trashed order note. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_order_note', $note, $response, $request ); + + return $response; + } + + /** + * Prepare a single order note output for response. + * + * @param WP_Comment $note Order note object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $note, $request ) { + $data = array( + 'id' => (int) $note->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + $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( $note ) ); + + /** + * Filter order note object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $note Order note object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $note Delivery order_note object. + * @return array Links for the given order note. + */ + protected function prepare_links( $note ) { + $order_id = (int) $note->comment_post_ID; + $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $note->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Order Notes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'order_note', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'note' => array( + 'description' => __( 'Order note.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_note' => array( + 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-order-refunds-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-order-refunds-v1-controller.php new file mode 100644 index 00000000000..03b55bfe7da --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-order-refunds-v1-controller.php @@ -0,0 +1,530 @@ +/refunds endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/RestApi + * @since 2.6.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Order Refunds controller class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Orders_V1_Controller + */ +class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'orders/(?P[\d]+)/refunds'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'shop_order_refund'; + + /** + * Order refunds actions. + */ + public function __construct() { + add_filter( "woocommerce_rest_{$this->post_type}_trashable", '__return_false' ); + add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for order refunds. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Prepare a single order refund output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * + * @return WP_Error|WP_REST_Response + */ + public function prepare_item_for_response( $post, $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + $refund = wc_get_order( $post ); + + if ( ! $refund || $refund->get_parent_id() !== $order->get_id() ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + } + + $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); + + $data = array( + 'id' => $refund->get_id(), + 'date_created' => wc_rest_prepare_date_response( $refund->get_date_created() ), + 'amount' => wc_format_decimal( $refund->get_amount(), $dp ), + 'reason' => $refund->get_reason(), + 'line_items' => array(), + ); + + // Add line items. + foreach ( $refund->get_items() as $item_id => $item ) { + $product = $refund->get_product_from_item( $item ); + $product_id = 0; + $variation_id = 0; + $product_sku = null; + + // Check if the product exists. + if ( is_object( $product ) ) { + $product_id = $item->get_product_id(); + $variation_id = $item->get_variation_id(); + $product_sku = $product->get_sku(); + } + + $item_meta = array(); + + $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; + + foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { + $item_meta[] = array( + 'key' => $formatted_meta->key, + 'label' => $formatted_meta->display_key, + 'value' => wc_clean( $formatted_meta->display_value ), + ); + } + + $line_item = array( + 'id' => $item_id, + 'name' => $item['name'], + 'sku' => $product_sku, + 'product_id' => (int) $product_id, + 'variation_id' => (int) $variation_id, + 'quantity' => wc_stock_amount( $item['qty'] ), + 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', + 'price' => wc_format_decimal( $refund->get_item_total( $item, false, false ), $dp ), + 'subtotal' => wc_format_decimal( $refund->get_line_subtotal( $item, false, false ), $dp ), + 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), + 'total' => wc_format_decimal( $refund->get_line_total( $item, false, false ), $dp ), + 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), + 'taxes' => array(), + 'meta' => $item_meta, + ); + + $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); + if ( isset( $item_line_taxes['total'] ) ) { + $line_tax = array(); + + foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + + $line_item['taxes'] = array_values( $line_tax ); + } + + $data['line_items'][] = $line_item; + } + + $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( $refund, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Order_Refund $refund Comment object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given order refund. + */ + protected function prepare_links( $refund, $request ) { + $order_id = $refund->get_parent_id(); + $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $refund->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), + ), + ); + + return $links; + } + + /** + * Query args. + * + * @param array $args Request args. + * @param WP_REST_Request $request Request object. + * @return array + */ + public function query_args( $args, $request ) { + $args['post_status'] = array_keys( wc_get_order_statuses() ); + $args['post_parent__in'] = array( absint( $request['order_id'] ) ); + + return $args; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order_data = get_post( (int) $request['order_id'] ); + + if ( empty( $order_data ) ) { + return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); + } + + if ( 0 > $request['amount'] ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + } + + // Create the refund. + $refund = wc_create_refund( array( + 'order_id' => $order_data->ID, + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) ); + + if ( is_wp_error( $refund ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + } + + if ( ! $refund ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + $post = get_post( $refund->get_id() ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'amount' => array( + 'description' => __( 'Refund amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'reason' => array( + 'description' => __( 'Reason for refund.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta' => array( + 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Meta label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + '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 = parent::get_collection_params(); + + $params['dp'] = array( + 'default' => wc_get_price_decimals(), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-orders-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-orders-v1-controller.php new file mode 100644 index 00000000000..8ee59793536 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-orders-v1-controller.php @@ -0,0 +1,1629 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for orders. + */ + public function register_routes() { + register_rest_route( $this->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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Prepare a single order output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $data + */ + public function prepare_item_for_response( $post, $request ) { + $order = wc_get_order( $post ); + $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); + + $data = array( + 'id' => $order->get_id(), + 'parent_id' => $order->get_parent_id(), + 'status' => $order->get_status(), + 'order_key' => $order->get_order_key(), + 'number' => $order->get_order_number(), + 'currency' => $order->get_currency(), + 'version' => $order->get_version(), + 'prices_include_tax' => $order->get_prices_include_tax(), + 'date_created' => wc_rest_prepare_date_response( $order->get_date_created() ), // v1 API used UTC. + 'date_modified' => wc_rest_prepare_date_response( $order->get_date_modified() ), // v1 API used UTC. + 'customer_id' => $order->get_customer_id(), + 'discount_total' => wc_format_decimal( $order->get_total_discount(), $dp ), + 'discount_tax' => wc_format_decimal( $order->get_discount_tax(), $dp ), + 'shipping_total' => wc_format_decimal( $order->get_shipping_total(), $dp ), + 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), $dp ), + 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), $dp ), + 'total' => wc_format_decimal( $order->get_total(), $dp ), + 'total_tax' => wc_format_decimal( $order->get_total_tax(), $dp ), + 'billing' => array(), + 'shipping' => array(), + 'payment_method' => $order->get_payment_method(), + 'payment_method_title' => $order->get_payment_method_title(), + 'transaction_id' => $order->get_transaction_id(), + 'customer_ip_address' => $order->get_customer_ip_address(), + 'customer_user_agent' => $order->get_customer_user_agent(), + 'created_via' => $order->get_created_via(), + 'customer_note' => $order->get_customer_note(), + 'date_completed' => wc_rest_prepare_date_response( $order->get_date_completed(), false ), // v1 API used local time. + 'date_paid' => wc_rest_prepare_date_response( $order->get_date_paid(), false ), // v1 API used local time. + 'cart_hash' => $order->get_cart_hash(), + 'line_items' => array(), + 'tax_lines' => array(), + 'shipping_lines' => array(), + 'fee_lines' => array(), + 'coupon_lines' => array(), + 'refunds' => array(), + ); + + // Add addresses. + $data['billing'] = $order->get_address( 'billing' ); + $data['shipping'] = $order->get_address( 'shipping' ); + + // Add line items. + foreach ( $order->get_items() as $item_id => $item ) { + $product = $order->get_product_from_item( $item ); + $product_id = 0; + $variation_id = 0; + $product_sku = null; + + // Check if the product exists. + if ( is_object( $product ) ) { + $product_id = $item->get_product_id(); + $variation_id = $item->get_variation_id(); + $product_sku = $product->get_sku(); + } + + $item_meta = array(); + + $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; + + foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { + $item_meta[] = array( + 'key' => $formatted_meta->key, + 'label' => $formatted_meta->display_key, + 'value' => wc_clean( $formatted_meta->display_value ), + ); + } + + $line_item = array( + 'id' => $item_id, + 'name' => $item['name'], + 'sku' => $product_sku, + 'product_id' => (int) $product_id, + 'variation_id' => (int) $variation_id, + 'quantity' => wc_stock_amount( $item['qty'] ), + 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', + 'price' => wc_format_decimal( $order->get_item_total( $item, false, false ), $dp ), + 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item, false, false ), $dp ), + 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), + 'total' => wc_format_decimal( $order->get_line_total( $item, false, false ), $dp ), + 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), + 'taxes' => array(), + 'meta' => $item_meta, + ); + + $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); + if ( isset( $item_line_taxes['total'] ) ) { + $line_tax = array(); + + foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + + $line_item['taxes'] = array_values( $line_tax ); + } + + $data['line_items'][] = $line_item; + } + + // Add taxes. + foreach ( $order->get_items( 'tax' ) as $key => $tax ) { + $tax_line = array( + 'id' => $key, + 'rate_code' => $tax['name'], + 'rate_id' => $tax['rate_id'], + 'label' => isset( $tax['label'] ) ? $tax['label'] : $tax['name'], + 'compound' => (bool) $tax['compound'], + 'tax_total' => wc_format_decimal( $tax['tax_amount'], $dp ), + 'shipping_tax_total' => wc_format_decimal( $tax['shipping_tax_amount'], $dp ), + ); + + $data['tax_lines'][] = $tax_line; + } + + // Add shipping. + foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { + $shipping_line = array( + 'id' => $shipping_item_id, + 'method_title' => $shipping_item['name'], + 'method_id' => $shipping_item['method_id'], + 'total' => wc_format_decimal( $shipping_item['cost'], $dp ), + 'total_tax' => wc_format_decimal( '', $dp ), + 'taxes' => array(), + ); + + $shipping_taxes = $shipping_item->get_taxes(); + + if ( ! empty( $shipping_taxes['total'] ) ) { + $shipping_line['total_tax'] = wc_format_decimal( array_sum( $shipping_taxes['total'] ), $dp ); + + foreach ( $shipping_taxes['total'] as $tax_rate_id => $tax ) { + $shipping_line['taxes'][] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + ); + } + } + + $data['shipping_lines'][] = $shipping_line; + } + + // Add fees. + foreach ( $order->get_fees() as $fee_item_id => $fee_item ) { + $fee_line = array( + 'id' => $fee_item_id, + 'name' => $fee_item['name'], + 'tax_class' => ! empty( $fee_item['tax_class'] ) ? $fee_item['tax_class'] : '', + 'tax_status' => 'taxable', + 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), $dp ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), $dp ), + 'taxes' => array(), + ); + + $fee_line_taxes = maybe_unserialize( $fee_item['line_tax_data'] ); + if ( isset( $fee_line_taxes['total'] ) ) { + $fee_tax = array(); + + foreach ( $fee_line_taxes['total'] as $tax_rate_id => $tax ) { + $fee_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + if ( isset( $fee_line_taxes['subtotal'] ) ) { + foreach ( $fee_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $fee_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + } + + $fee_line['taxes'] = array_values( $fee_tax ); + } + + $data['fee_lines'][] = $fee_line; + } + + // Add coupons. + foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) { + $coupon_line = array( + 'id' => $coupon_item_id, + 'code' => $coupon_item['name'], + 'discount' => wc_format_decimal( $coupon_item['discount_amount'], $dp ), + 'discount_tax' => wc_format_decimal( $coupon_item['discount_amount_tax'], $dp ), + ); + + $data['coupon_lines'][] = $coupon_line; + } + + // Add refunds. + foreach ( $order->get_refunds() as $refund ) { + $data['refunds'][] = array( + 'id' => $refund->get_id(), + 'refund' => $refund->get_reason() ? $refund->get_reason() : '', + 'total' => '-' . wc_format_decimal( $refund->get_amount(), $dp ), + ); + } + + $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( $order, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Order $order Order object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given order. + */ + protected function prepare_links( $order, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $order->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + if ( 0 !== (int) $order->get_user_id() ) { + $links['customer'] = array( + 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $order->get_user_id() ) ), + ); + } + if ( 0 !== (int) $order->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order->get_parent_id() ) ), + ); + } + return $links; + } + + /** + * Query args. + * + * @param array $args + * @param WP_REST_Request $request + * @return array + */ + public function query_args( $args, $request ) { + global $wpdb; + + // Set post_status. + if ( 'any' !== $request['status'] ) { + $args['post_status'] = 'wc-' . $request['status']; + } else { + $args['post_status'] = 'any'; + } + + if ( isset( $request['customer'] ) ) { + if ( ! empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); + } + + $args['meta_query'][] = array( + 'key' => '_customer_user', + 'value' => $request['customer'], + 'type' => 'NUMERIC', + ); + } + + // Search by product. + if ( ! empty( $request['product'] ) ) { + $order_ids = $wpdb->get_col( $wpdb->prepare( " + SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item' + ", $request['product'] ) ); + + // Force WP_Query return empty if don't found any order. + $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); + + $args['post__in'] = $order_ids; + } + + // Search. + if ( ! empty( $args['s'] ) ) { + $order_ids = wc_order_search( $args['s'] ); + + if ( ! empty( $order_ids ) ) { + unset( $args['s'] ); + $args['post__in'] = array_merge( $order_ids, array( 0 ) ); + } + } + + return $args; + } + + /** + * Prepare a single order for create. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|WC_Order $data Object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $order = new WC_Order( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Handle all writable props + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'billing' : + case 'shipping' : + $this->update_address( $order, $value, $key ); + break; + case 'line_items' : + case 'shipping_lines' : + case 'fee_lines' : + case 'coupon_lines' : + if ( is_array( $value ) ) { + foreach ( $value as $item ) { + if ( is_array( $item ) ) { + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $order->remove_item( $item['id'] ); + } else { + $this->set_item( $order, $key, $item ); + } + } + } + } + break; + default : + if ( is_callable( array( $order, "set_{$key}" ) ) ) { + $order->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filter the data for the insert. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WC_Order $order The order object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $order, $request ); + } + + /** + * Create base WC Order object. + * @deprecated 3.0.0 + * @param array $data + * @return WC_Order + */ + protected function create_base_order( $data ) { + return wc_create_order( $data ); + } + + /** + * Only return writable props from schema. + * @param array $schema + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Create order. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function create_order( $request ) { + try { + // Make sure customer exists. + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] && false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } + + $order = $this->prepare_item_for_database( $request ); + $order->set_created_via( 'rest-api' ); + $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $order->calculate_totals(); + $order->save(); + + // Handle set paid. + if ( true === $request['set_paid'] ) { + $order->payment_complete( $request['transaction_id'] ); + } + + return $order->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update order. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function update_order( $request ) { + try { + $order = $this->prepare_item_for_database( $request ); + $order->save(); + + // Handle set paid. + if ( $order->needs_payment() && true === $request['set_paid'] ) { + $order->payment_complete( $request['transaction_id'] ); + } + + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $order->calculate_totals( true ); + } + + return $order->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update address. + * + * @param WC_Order $order + * @param array $posted + * @param string $type + */ + protected function update_address( $order, $posted, $type = 'billing' ) { + foreach ( $posted as $key => $value ) { + if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { + $order->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Gets the product ID from the SKU or posted ID. + * + * @param array $posted Request data + * + * @return int + * @throws WC_REST_Exception + */ + protected function get_product_id( $posted ) { + if ( ! empty( $posted['sku'] ) ) { + $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); + } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['product_id']; + } elseif ( ! empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['variation_id']; + } else { + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + } + return $product_id; + } + + /** + * Maybe set an item prop if the value was posted. + * @param WC_Order_Item $item + * @param string $prop + * @param array $posted Request data. + */ + protected function maybe_set_item_prop( $item, $prop, $posted ) { + if ( isset( $posted[ $prop ] ) ) { + $item->{"set_$prop"}( $posted[ $prop ] ); + } + } + + /** + * Maybe set item props if the values were posted. + * @param WC_Order_Item $item + * @param string[] $props + * @param array $posted Request data. + */ + protected function maybe_set_item_props( $item, $props, $posted ) { + foreach ( $props as $prop ) { + $this->maybe_set_item_prop( $item, $prop, $posted ); + } + } + + /** + * Create or update a line item. + * + * @param array $posted Line item data. + * @param string $action 'create' to add line item or 'update' to update it. + * + * @return WC_Order_Item_Product + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_line_items( $posted, $action = 'create' ) { + $item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + $product = wc_get_product( $this->get_product_id( $posted ) ); + + if ( $product !== $item->get_product() ) { + $item->set_product( $product ); + + if ( 'create' === $action ) { + $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; + $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); + $item->set_total( $total ); + $item->set_subtotal( $total ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); + + return $item; + } + + /** + * Create or update an order shipping method. + * + * @param $posted $shipping Item data. + * @param string $action 'create' to add shipping or 'update' to update it. + * + * @return WC_Order_Item_Shipping + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_shipping_lines( $posted, $action ) { + $item = new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['method_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); + + return $item; + } + + /** + * Create or update an order fee. + * + * @param array $posted Item data. + * @param string $action 'create' to add fee or 'update' to update it. + * + * @return WC_Order_Item_Fee + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_fee_lines( $posted, $action ) { + $item = new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['name'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); + + return $item; + } + + /** + * Create or update an order coupon. + * + * @param array $posted Item data. + * @param string $action 'create' to add coupon or 'update' to update it. + * + * @return WC_Order_Item_Coupon + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_coupon_lines( $posted, $action ) { + $item = new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['code'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); + + return $item; + } + + /** + * Wrapper method to create/update order items. + * When updating, the item ID provided is checked to ensure it is associated + * with the order. + * + * @param WC_Order $order order + * @param string $item_type + * @param array $posted item provided in the request body + * @throws WC_REST_Exception If item ID is not associated with order + */ + protected function set_item( $order, $item_type, $posted ) { + global $wpdb; + + if ( ! empty( $posted['id'] ) ) { + $action = 'update'; + } else { + $action = 'create'; + } + + $method = 'prepare_' . $item_type; + + // Verify provided line item ID is associated with order. + if ( 'update' === $action ) { + $result = $wpdb->get_row( + $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d", + absint( $posted['id'] ), + absint( $order->get_id() ) + ) ); + if ( is_null( $result ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + } + } + + // Prepare item data + $item = $this->$method( $posted, $action ); + + /** + * Action hook to adjust item before save. + * @since 3.0.0 + */ + do_action( 'woocommerce_rest_set_order_item', $item, $posted ); + + // Save or add to order + if ( 'create' === $action ) { + $order->add_item( $item ); + } else { + $item->save(); + } + } + + /** + * Helper method to check if the resource ID associated with the provided item is null. + * Items can be deleted by setting the resource ID to null. + * + * @param array $item Item provided in the request body. + * @return bool True if the item resource ID is null, false otherwise. + */ + protected function item_is_null( $item ) { + $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); + + foreach ( $keys as $key ) { + if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { + return true; + } + } + + return false; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order_id = $this->create_order( $request ); + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $post = get_post( $order_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Update a single order. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $order_id = $this->update_order( $request ); + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $post = get_post( $order_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get order statuses without prefixes. + * @return array + */ + protected function get_order_statuses() { + $order_statuses = array(); + + foreach ( array_keys( wc_get_order_statuses() ) as $status ) { + $order_statuses[] = str_replace( 'wc-', '', $status ); + } + + return $order_statuses; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + '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' => __( 'Parent order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Order status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'pending', + 'enum' => $this->get_order_statuses(), + 'context' => array( 'view', 'edit' ), + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'number' => array( + 'description' => __( 'Order number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'currency' => array( + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), + 'type' => 'string', + 'default' => get_woocommerce_currency(), + 'enum' => array_keys( get_woocommerce_currencies() ), + 'context' => array( 'view', 'edit' ), + ), + 'version' => array( + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'prices_include_tax' => array( + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order was created, as GMT.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_id' => array( + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 0, + 'context' => array( 'view', 'edit' ), + ), + 'discount_total' => array( + 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_tax' => array( + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_total' => array( + 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax' => array( + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_tax' => array( + 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Grand total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Sum of all taxes.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'billing' => array( + 'description' => __( 'Billing address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'Shipping address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'payment_method' => array( + 'description' => __( 'Payment method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'payment_method_title' => array( + 'description' => __( 'Payment method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'set_paid' => array( + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), + 'transaction_id' => array( + 'description' => __( 'Unique transaction ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_ip_address' => array( + 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_user_agent' => array( + 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'created_via' => array( + 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_note' => array( + 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_completed' => array( + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_paid' => array( + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_hash' => array( + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta' => array( + 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Meta label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'tax_lines' => array( + 'description' => __( 'Tax lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_code' => array( + 'description' => __( 'Tax rate code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Tax rate label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'compound' => array( + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_total' => array( + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax_total' => array( + 'description' => __( 'Shipping tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'shipping_lines' => array( + 'description' => __( 'Shipping lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_title' => array( + 'description' => __( 'Shipping method name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'fee_lines' => array( + 'description' => __( 'Fee lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Fee name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'taxable', 'none' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'coupon_lines' => array( + 'description' => __( 'Coupons line data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'discount' => array( + 'description' => __( 'Discount total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'discount_tax' => array( + 'description' => __( 'Discount total tax.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'refunds' => array( + 'description' => __( 'List of refunds.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Refund ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reason' => array( + 'description' => __( 'Refund reason.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Refund total.', 'woocommerce' ), + 'type' => 'string', + '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 = parent::get_collection_params(); + + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any' ), $this->get_order_statuses() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['customer'] = array( + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['product'] = array( + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['dp'] = array( + 'default' => wc_get_price_decimals(), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-attribute-terms-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-product-attribute-terms-v1-controller.php new file mode 100644 index 00000000000..76d43c5cd90 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-product-attribute-terms-v1-controller.php @@ -0,0 +1,240 @@ +/terms endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Product Attribute Terms controller class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Terms_Controller + */ +class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/attributes/(?P[\d]+)/terms'; + + /** + * Register the routes for terms. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'type' => 'string', + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + )); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Prepare a single product attribute term output for response. + * + * @param WP_Term $item Term object. + * @param WP_REST_Request $request + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + // Get term order. + $menu_order = get_term_meta( $item->term_id, 'order_' . $this->taxonomy, true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Update term meta fields. + * + * @param WP_Term $term + * @param WP_REST_Request $request + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + $id = (int) $term->term_id; + + update_term_meta( $id, 'order_' . $this->taxonomy, $request['menu_order'] ); + + return true; + } + + /** + * Get the Attribute Term's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_attribute_term', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-attributes-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-product-attributes-v1-controller.php new file mode 100644 index 00000000000..211380c3144 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-product-attributes-v1-controller.php @@ -0,0 +1,586 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'type' => 'string', + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + )); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check if a given request has access to read the attributes. + * + * @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( 'attributes', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'attributes', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'attributes', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all attributes. + * + * @param WP_REST_Request $request + * @return array + */ + public function get_items( $request ) { + $attributes = wc_get_attribute_taxonomies(); + $data = array(); + foreach ( $attributes as $attribute_obj ) { + $attribute = $this->prepare_item_for_response( $attribute_obj, $request ); + $attribute = $this->prepare_response_for_collection( $attribute ); + $data[] = $attribute; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + global $wpdb; + + $id = wc_create_attribute( array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => ! empty( $request['type'] ) ? $request['type'] : 'select', + 'order_by' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', + 'has_archives' => true === $request['has_archives'], + ) ); + + // Checks for errors. + if ( is_wp_error( $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', $id->get_error_message(), array( 'status' => 400 ) ); + } + + $attribute = $this->get_attribute( $id ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $this->update_additional_fields_for_object( $attribute, $request ); + + /** + * Fires after a single product attribute is created or updated via the REST API. + * + * @param stdObject $attribute Inserted attribute object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating attribute, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( '/' . $this->namespace . '/' . $this->rest_base . '/' . $attribute->attribute_id ) ); + + return $response; + } + + /** + * Get a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function get_item( $request ) { + $attribute = $this->get_attribute( (int) $request['id'] ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $response = $this->prepare_item_for_response( $attribute, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Update a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + global $wpdb; + + $id = (int) $request['id']; + $edited = wc_update_attribute( $id, array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => $request['type'], + 'order_by' => $request['order_by'], + 'has_archives' => $request['has_archives'], + ) ); + + // Checks for errors. + if ( is_wp_error( $edited ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', $edited->get_error_message(), array( 'status' => 400 ) ); + } + + $attribute = $this->get_attribute( $id ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $this->update_additional_fields_for_object( $attribute, $request ); + + /** + * Fires after a single product attribute is created or updated via the REST API. + * + * @param stdObject $attribute Inserted attribute object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating attribute, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $attribute = $this->get_attribute( (int) $request['id'] ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + + $deleted = wc_delete_attribute( $attribute->attribute_id ); + + if ( false === $deleted ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single attribute is deleted via the REST API. + * + * @param stdObject $attribute The deleted attribute. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_product_attribute', $attribute, $response, $request ); + + return $response; + } + + /** + * Prepare a single product attribute output for response. + * + * @param obj $item Term object. + * @param WP_REST_Request $request + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $data = array( + 'id' => (int) $item->attribute_id, + 'name' => $item->attribute_label, + 'slug' => wc_attribute_taxonomy_name( $item->attribute_name ), + 'type' => $item->attribute_type, + 'order_by' => $item->attribute_orderby, + 'has_archives' => (bool) $item->attribute_public, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter a attribute item returned from the API. + * + * Allows modification of the product attribute data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original attribute object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_product_attribute', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $attribute Attribute object. + * @return array Links for the given attribute. + */ + protected function prepare_links( $attribute ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $attribute->attribute_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Attribute's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_attribute', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'type' => array( + 'description' => __( 'Type of attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'select', + 'enum' => array_keys( wc_get_attribute_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'order_by' => array( + 'description' => __( 'Default sort order.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'menu_order', + 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ), + 'context' => array( 'view', 'edit' ), + ), + 'has_archives' => array( + 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + 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; + } + + /** + * Get attribute name. + * + * @param WP_REST_Request $request Full details about the request. + * @return string + */ + protected function get_taxonomy( $request ) { + if ( '' !== $this->attribute ) { + return $this->attribute; + } + + if ( $request['id'] ) { + $name = wc_attribute_taxonomy_name_by_id( (int) $request['id'] ); + + $this->attribute = $name; + } + + return $this->attribute; + } + + /** + * Get attribute data. + * + * @param int $id Attribute ID. + * @return stdClass|WP_Error + */ + protected function get_attribute( $id ) { + global $wpdb; + + $attribute = $wpdb->get_row( $wpdb->prepare( " + SELECT * + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); + + if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { + return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return $attribute; + } + + /** + * Validate attribute slug. + * + * @deprecated 3.2.0 + * @param string $slug + * @param bool $new_data + * @return bool|WP_Error + */ + protected function validate_attribute_slug( $slug, $new_data = true ) { + if ( strlen( $slug ) >= 28 ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } + + return true; + } + + /** + * Schedule to flush rewrite rules. + * + * @deprecated 3.2.0 + * @since 3.0.0 + */ + protected function flush_rewrite_rules() { + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-categories-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-product-categories-v1-controller.php new file mode 100644 index 00000000000..3cca0ab7420 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-product-categories-v1-controller.php @@ -0,0 +1,271 @@ +term_id, 'display_type', true ); + + // Get category order. + $menu_order = get_term_meta( $item->term_id, 'order', true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'parent' => (int) $item->parent, + 'description' => $item->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => null, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + // Get category image. + $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); + if ( $image_id ) { + $attachment = get_post( $image_id ); + + $data['image'] = array( + 'id' => (int) $image_id, + 'date_created' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), + 'src' => wp_get_attachment_url( $image_id ), + 'title' => get_the_title( $attachment ), + 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Update term meta fields. + * + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Request instance. + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + $id = (int) $term->term_id; + + if ( isset( $request['display'] ) ) { + update_term_meta( $id, 'display_type', 'default' === $request['display'] ? '' : $request['display'] ); + } + + if ( isset( $request['menu_order'] ) ) { + update_term_meta( $id, 'order', $request['menu_order'] ); + } + + if ( isset( $request['image'] ) ) { + if ( empty( $request['image']['id'] ) && ! empty( $request['image']['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $request['image']['src'] ) ); + + if ( is_wp_error( $upload ) ) { + return $upload; + } + + $image_id = wc_rest_set_uploaded_image_as_attachment( $upload ); + } else { + $image_id = isset( $request['image']['id'] ) ? absint( $request['image']['id'] ) : 0; + } + + // Check if image_id is a valid image attachment before updating the term meta. + if ( $image_id && wp_attachment_is_image( $image_id ) ) { + update_term_meta( $id, 'thumbnail_id', $image_id ); + + // Set the image alt. + if ( ! empty( $request['image']['alt'] ) ) { + update_post_meta( $image_id, '_wp_attachment_image_alt', wc_clean( $request['image']['alt'] ) ); + } + + // Set the image title. + if ( ! empty( $request['image']['title'] ) ) { + wp_update_post( array( + 'ID' => $image_id, + 'post_title' => wc_clean( $request['image']['title'] ), + ) ); + } + } else { + delete_term_meta( $id, 'thumbnail_id' ); + } + } + + return true; + } + + /** + * Get the Category schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'parent' => array( + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'display' => array( + 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'default', + 'enum' => array( 'default', 'products', 'subcategories', 'both' ), + 'context' => array( 'view', 'edit' ), + ), + 'image' => array( + 'description' => __( 'Image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'title' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-reviews-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-product-reviews-v1-controller.php new file mode 100644 index 00000000000..ebfbdba7778 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-product-reviews-v1-controller.php @@ -0,0 +1,578 @@ +/reviews. + * + * @author WooThemes + * @category API + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Product Reviews Controller Class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Controller + */ +class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/(?P[\d]+)/reviews'; + + /** + * Register the routes for product reviews. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'review' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Review content.', 'woocommerce' ), + ), + 'name' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + ), + 'email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read webhook deliveries. + * + * @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_post_permissions( 'product', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + + if ( $post && ! wc_rest_check_post_permissions( 'product', 'read', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a new product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'create', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to update a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'edit', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to delete a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'delete', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get all reviews from a product. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $reviews = get_approved_comments( $product_id ); + $data = array(); + foreach ( $reviews as $review_data ) { + $review = $this->prepare_item_for_response( $review_data, $request ); + $review = $this->prepare_response_for_collection( $review ); + $data[] = $review; + } + + return rest_ensure_response( $data ); + } + + /** + * Get a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $review = get_comment( $id ); + + if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $delivery = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $delivery ); + + return $response; + } + + + /** + * Create a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + + /** + * Filter a product review (comment) before it is inserted via the REST API. + * + * Allows modification of the comment right before it is inserted via `wp_insert_comment`. + * + * @param array $prepared_review The prepared comment data for `wp_insert_comment`. + * @param WP_REST_Request $request Request used to insert the comment. + */ + $prepared_review = apply_filters( 'rest_pre_insert_product_review', $prepared_review, $request ); + + $product_review_id = wp_insert_comment( $prepared_review ); + if ( ! $product_review_id ) { + return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); + + $product_review = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $product_review, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Comment $product_review Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $product_review_id ) ) ); + + return $response; + } + + /** + * Update a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $product_review_id = (int) $request['id']; + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $review = get_comment( $product_review_id ); + + if ( empty( $product_review_id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + + $updated = wp_update_comment( $prepared_review ); + if ( 0 === $updated ) { + return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( ! empty( $request['rating'] ) ) { + update_comment_meta( $product_review_id, 'rating', $request['rating'] ); + } + + $product_review = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $product_review, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Comment $comment Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a product review. + * + * @param WP_REST_Request $request Full details about the request + * + * @return bool|WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $product_review_id = absint( is_array( $request['id'] ) ? $request['id']['id'] : $request['id'] ); + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + $product_review = get_comment( $product_review_id ); + if ( empty( $product_review_id ) || empty( $product_review->comment_ID ) || empty( $product_review->comment_post_ID ) ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + /** + * Filter whether a product review is trashable. + * + * Return false to disable trash support for the product review. + * + * @param boolean $supports_trash Whether the object supports trashing. + * @param WP_Post $product_review The object being considered for trashing support. + */ + $supports_trash = apply_filters( 'rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $product_review ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + + if ( $force ) { + $result = wp_delete_comment( $product_review_id, true ); + } else { + if ( ! $supports_trash ) { + return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + if ( 'trash' === $product_review->comment_approved ) { + return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + } + + $result = wp_trash_comment( $product_review->comment_ID ); + } + + if ( ! $result ) { + return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a product review is deleted via the REST API. + * + * @param object $product_review The deleted item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'rest_delete_product_review', $product_review, $response, $request ); + + return $response; + } + + /** + * Prepare a single product review output for response. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $review, $request ) { + $data = array( + 'id' => (int) $review->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $review->comment_date_gmt ), + 'review' => $review->comment_content, + 'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ), + 'name' => $review->comment_author, + 'email' => $review->comment_author_email, + 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), + ); + + $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( $review, $request ) ); + + /** + * Filter product reviews object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $review Product review object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + } + + /** + * Prepare a single product review to be inserted into the database. + * + * @param WP_REST_Request $request Request object. + * @return array|WP_Error $prepared_review + */ + protected function prepare_item_for_database( $request ) { + $prepared_review = array( 'comment_approved' => 1, 'comment_type' => 'review' ); + + if ( isset( $request['id'] ) ) { + $prepared_review['comment_ID'] = (int) $request['id']; + } + + if ( isset( $request['review'] ) ) { + $prepared_review['comment_content'] = $request['review']; + } + + if ( isset( $request['product_id'] ) ) { + $prepared_review['comment_post_ID'] = (int) $request['product_id']; + } + + if ( isset( $request['name'] ) ) { + $prepared_review['comment_author'] = $request['name']; + } + + if ( isset( $request['email'] ) ) { + $prepared_review['comment_author_email'] = $request['email']; + } + + if ( isset( $request['date_created'] ) ) { + $prepared_review['comment_date'] = $request['date_created']; + } + + if ( isset( $request['date_created_gmt'] ) ) { + $prepared_review['comment_date_gmt'] = $request['date_created_gmt']; + } + + return apply_filters( 'rest_preprocess_product_review', $prepared_review, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given product review. + */ + protected function prepare_links( $review, $request ) { + $product_id = (int) $request['product_id']; + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $review->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Product Review's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_review', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'rating' => array( + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'verified' => array( + 'description' => __( 'Shows if the reviewer bought the product or not.', '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() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-shipping-classes-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-product-shipping-classes-v1-controller.php new file mode 100644 index 00000000000..89b59f1b9b6 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-product-shipping-classes-v1-controller.php @@ -0,0 +1,134 @@ + (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Shipping Class schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Shipping class name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-tags-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-product-tags-v1-controller.php new file mode 100644 index 00000000000..76161e94e13 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-product-tags-v1-controller.php @@ -0,0 +1,134 @@ + (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Tag's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-products-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-products-v1-controller.php new file mode 100644 index 00000000000..6ca69c397c0 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-products-v1-controller.php @@ -0,0 +1,2641 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + add_action( "woocommerce_rest_insert_{$this->post_type}", array( $this, 'clear_transients' ) ); + } + + /** + * Register the routes for products. + */ + public function register_routes() { + register_rest_route( $this->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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'type' => 'boolean', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Get post types. + * + * @return array + */ + protected function get_post_types() { + return array( 'product', 'product_variation' ); + } + + /** + * Query args. + * + * @param array $args Request args. + * @param WP_REST_Request $request Request data. + * @return array + */ + public function query_args( $args, $request ) { + // Set post_status. + $args['post_status'] = $request['status']; + + // Taxonomy query to filter products by type, category, + // tag, shipping class, and attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies = array( + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) && is_array( $request[ $key ] ) ) { + $request[ $key ] = array_filter( $request[ $key ] ); + } + + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + if ( ! empty( $tax_query ) ) { + $args['tax_query'] = $tax_query; + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) ); + } + + // Apply all WP_Query filters again. + if ( is_array( $request['filter'] ) ) { + $args = array_merge( $args, $request['filter'] ); + unset( $args['filter'] ); + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + return $args; + } + + /** + * Get the downloads for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_downloads( $product ) { + $downloads = array(); + + if ( $product->is_downloadable() ) { + foreach ( $product->get_downloads() as $file_id => $file ) { + $downloads[] = array( + 'id' => $file_id, // MD5 hash. + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param string $taxonomy Taxonomy slug. + * @return array + */ + protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { + $terms = array(); + + foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { + $terms[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + ); + } + + return $terms; + } + + /** + * Get the images for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_images( $product ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( $product->get_image_id() ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $position => $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified_gmt ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + 'position' => (int) $position, + ); + } + + // Set a placeholder image if the product has no images set. + if ( empty( $images ) ) { + $images[] = array( + 'id' => 0, + 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), // Default to now. + 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), + 'src' => wc_placeholder_img_src(), + 'name' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), + 'position' => 0, + ); + } + + return $images; + } + + /** + * Get attribute taxonomy label. + * + * @param string $name Taxonomy name. + * @return string + */ + protected function get_attribute_taxonomy_label( $name ) { + $tax = get_taxonomy( $name ); + $labels = get_taxonomy_labels( $tax ); + + return $labels->singular_name; + } + + /** + * Get default attributes. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_default_attributes( $product ) { + $default = array(); + + if ( $product->is_type( 'variable' ) ) { + foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { + if ( 0 === strpos( $key, 'pa_' ) ) { + $default[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $key ), + 'name' => $this->get_attribute_taxonomy_label( $key ), + 'option' => $value, + ); + } else { + $default[] = array( + 'id' => 0, + 'name' => wc_attribute_taxonomy_slug( $key ), + 'option' => $value, + ); + } + } + } + + return $default; + } + + /** + * Get attribute options. + * + * @param int $product_id Product ID. + * @param array $attribute Attribute data. + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( $product_id, $attribute['name'], array( 'fields' => 'names' ) ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_attributes( $product ) { + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + // Variation attributes. + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + $name = str_replace( 'attribute_', '', $attribute_name ); + + if ( ! $attribute ) { + continue; + } + + // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. + if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $name ); + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $name ), + 'name' => $this->get_attribute_taxonomy_label( $name ), + 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $name, + 'option' => $attribute, + ); + } + } + } else { + foreach ( $product->get_attributes() as $attribute ) { + if ( $attribute['is_taxonomy'] ) { + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $attribute['name'] ), + 'name' => $this->get_attribute_taxonomy_label( $attribute['name'] ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $attribute['name'], + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + } + + return $attributes; + } + + /** + * Get product menu order. + * + * @deprecated 3.0.0 + * @param WC_Product $product Product instance. + * @return int + */ + protected function get_product_menu_order( $product ) { + return $product->get_menu_order(); + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_product_data( $product ) { + $data = array( + 'id' => $product->get_id(), + 'name' => $product->get_name(), + 'slug' => $product->get_slug(), + 'permalink' => $product->get_permalink(), + 'date_created' => wc_rest_prepare_date_response( $product->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified() ), + 'type' => $product->get_type(), + 'status' => $product->get_status(), + 'featured' => $product->is_featured(), + 'catalog_visibility' => $product->get_catalog_visibility(), + 'description' => wpautop( do_shortcode( $product->get_description() ) ), + 'short_description' => apply_filters( 'woocommerce_short_description', $product->get_short_description() ), + 'sku' => $product->get_sku(), + 'price' => $product->get_price(), + 'regular_price' => $product->get_regular_price(), + 'sale_price' => $product->get_sale_price() ? $product->get_sale_price() : '', + 'date_on_sale_from' => $product->get_date_on_sale_from() ? date( 'Y-m-d', $product->get_date_on_sale_from()->getTimestamp() ) : '', + 'date_on_sale_to' => $product->get_date_on_sale_to() ? date( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ) : '', + 'price_html' => $product->get_price_html(), + 'on_sale' => $product->is_on_sale(), + 'purchasable' => $product->is_purchasable(), + 'total_sales' => $product->get_total_sales(), + 'virtual' => $product->is_virtual(), + 'downloadable' => $product->is_downloadable(), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit(), + 'download_expiry' => $product->get_download_expiry(), + 'download_type' => 'standard', + 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url() : '', + 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text() : '', + 'tax_status' => $product->get_tax_status(), + 'tax_class' => $product->get_tax_class(), + 'manage_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity(), + 'in_stock' => $product->is_in_stock(), + 'backorders' => $product->get_backorders(), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'weight' => $product->get_weight(), + 'dimensions' => array( + 'length' => $product->get_length(), + 'width' => $product->get_width(), + 'height' => $product->get_height(), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => $product->get_shipping_class_id(), + 'reviews_allowed' => $product->get_reviews_allowed(), + 'average_rating' => wc_format_decimal( $product->get_average_rating(), 2 ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids() ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids() ), + 'parent_id' => $product->get_parent_id(), + 'purchase_note' => wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ), + 'categories' => $this->get_taxonomy_terms( $product ), + 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), + 'images' => $this->get_images( $product ), + 'attributes' => $this->get_attributes( $product ), + 'default_attributes' => $this->get_default_attributes( $product ), + 'variations' => array(), + 'grouped_products' => array(), + 'menu_order' => $product->get_menu_order(), + ); + + return $data; + } + + /** + * Get an individual variation's data. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_variation_data( $product ) { + $variations = array(); + + foreach ( $product->get_children() as $child_id ) { + $variation = wc_get_product( $child_id ); + if ( ! $variation || ! $variation->exists() ) { + continue; + } + + $variations[] = array( + 'id' => $variation->get_id(), + 'date_created' => wc_rest_prepare_date_response( $variation->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $variation->get_date_modified() ), + 'permalink' => $variation->get_permalink(), + 'sku' => $variation->get_sku(), + 'price' => $variation->get_price(), + 'regular_price' => $variation->get_regular_price(), + 'sale_price' => $variation->get_sale_price(), + 'date_on_sale_from' => $variation->get_date_on_sale_from() ? date( 'Y-m-d', $variation->get_date_on_sale_from()->getTimestamp() ) : '', + 'date_on_sale_to' => $variation->get_date_on_sale_to() ? date( 'Y-m-d', $variation->get_date_on_sale_to()->getTimestamp() ) : '', + 'on_sale' => $variation->is_on_sale(), + 'purchasable' => $variation->is_purchasable(), + 'visible' => $variation->is_visible(), + 'virtual' => $variation->is_virtual(), + 'downloadable' => $variation->is_downloadable(), + 'downloads' => $this->get_downloads( $variation ), + 'download_limit' => '' !== $variation->get_download_limit() ? (int) $variation->get_download_limit() : -1, + 'download_expiry' => '' !== $variation->get_download_expiry() ? (int) $variation->get_download_expiry() : -1, + 'tax_status' => $variation->get_tax_status(), + 'tax_class' => $variation->get_tax_class(), + 'manage_stock' => $variation->managing_stock(), + 'stock_quantity' => $variation->get_stock_quantity(), + 'in_stock' => $variation->is_in_stock(), + 'backorders' => $variation->get_backorders(), + 'backorders_allowed' => $variation->backorders_allowed(), + 'backordered' => $variation->is_on_backorder(), + 'weight' => $variation->get_weight(), + 'dimensions' => array( + 'length' => $variation->get_length(), + 'width' => $variation->get_width(), + 'height' => $variation->get_height(), + ), + 'shipping_class' => $variation->get_shipping_class(), + 'shipping_class_id' => $variation->get_shipping_class_id(), + 'image' => $this->get_images( $variation ), + 'attributes' => $this->get_attributes( $variation ), + ); + } + + return $variations; + } + + /** + * Prepare a single product output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $post, $request ) { + $product = wc_get_product( $post ); + $data = $this->get_product_data( $product ); + + // Add variations to variable products. + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + $data['variations'] = $this->get_variation_data( $product ); + } + + // Add grouped products data. + if ( $product->is_type( 'grouped' ) && $product->has_child() ) { + $data['grouped_products'] = $product->get_children(); + } + + $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, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Product $product Product object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given product. + */ + protected function prepare_links( $product, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $product->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + if ( $product->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_parent_id() ) ), + ); + } + + return $links; + } + + /** + * Prepare a single product for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + + // Type is the most important part here because we need to be using the correct class and methods. + if ( isset( $request['type'] ) ) { + $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + + $product = new $classname( $id ); + } elseif ( isset( $request['id'] ) ) { + $product = wc_get_product( $id ); + } else { + $product = new WC_Product_Simple(); + } + + // Post title. + if ( isset( $request['name'] ) ) { + $product->set_name( wp_filter_post_kses( $request['name'] ) ); + } + + // Post content. + if ( isset( $request['description'] ) ) { + $product->set_description( wp_filter_post_kses( $request['description'] ) ); + } + + // Post excerpt. + if ( isset( $request['short_description'] ) ) { + $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); + } + + // Post status. + if ( isset( $request['status'] ) ) { + $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // Post slug. + if ( isset( $request['slug'] ) ) { + $product->set_slug( $request['slug'] ); + } + + // Menu order. + if ( isset( $request['menu_order'] ) ) { + $product->set_menu_order( $request['menu_order'] ); + } + + // Comment status. + if ( isset( $request['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $request['reviews_allowed'] ); + } + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param WC_Product $product An object representing a single item prepared + * for inserting or updating the database. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $product, $request ); + } + + /** + * Create a single product. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $product_id = 0; + + try { + $product_id = $this->save_product( $request ); + $post = get_post( $product_id ); + $this->update_additional_fields_for_object( $post, $request ); + $this->update_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_product', $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } catch ( WC_Data_Exception $e ) { + $this->delete_post( $product_id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + $this->delete_post( $product_id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update a single product. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + try { + $product_id = $this->save_product( $request ); + $post = get_post( $product_id ); + $this->update_additional_fields_for_object( $post, $request ); + $this->update_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_product', $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + return rest_ensure_response( $response ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Saves a product to the database. + * + * @param WP_REST_Request $request Full details about the request. + * @return int + */ + public function save_product( $request ) { + $product = $this->prepare_item_for_database( $request ); + return $product->save(); + } + + /** + * Save product images. + * + * @deprecated 3.0.0 + * @param int $product_id + * @param array $images + * @throws WC_REST_Exception + */ + protected function save_product_images( $product_id, $images ) { + $product = wc_get_product( $product_id ); + + return set_product_images( $product, $images ); + } + + /** + * Set product images. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param array $images Images data. + * @return WC_Product + */ + protected function set_product_images( $product, $images ) { + if ( is_array( $images ) ) { + $gallery = array(); + + foreach ( $images as $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { + throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + if ( isset( $image['position'] ) && 0 === absint( $image['position'] ) ) { + $product->set_image_id( $attachment_id ); + } else { + $gallery[] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( array( 'ID' => $attachment_id, 'post_title' => $image['name'] ) ); + } + } + + if ( ! empty( $gallery ) ) { + $product->set_gallery_image_ids( $gallery ); + } + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Save product shipping data. + * + * @param WC_Product $product Product instance. + * @param array $data Shipping data. + * @return WC_Product + */ + protected function save_product_shipping_data( $product, $data ) { + // Virtual. + if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { + $product->set_weight( '' ); + $product->set_height( '' ); + $product->set_length( '' ); + $product->set_width( '' ); + } else { + if ( isset( $data['weight'] ) ) { + $product->set_weight( $data['weight'] ); + } + + // Height. + if ( isset( $data['dimensions']['height'] ) ) { + $product->set_height( $data['dimensions']['height'] ); + } + + // Width. + if ( isset( $data['dimensions']['width'] ) ) { + $product->set_width( $data['dimensions']['width'] ); + } + + // Length. + if ( isset( $data['dimensions']['length'] ) ) { + $product->set_length( $data['dimensions']['length'] ); + } + } + + // Shipping class. + if ( isset( $data['shipping_class'] ) ) { + $data_store = $product->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + + return $product; + } + + /** + * Save downloadable files. + * + * @param WC_Product $product Product instance. + * @param array $downloads Downloads data. + * @param int $deprecated Deprecated since 3.0. + * @return WC_Product + */ + protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { + if ( $deprecated ) { + wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); + } + + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); + $files[] = $download; + } + $product->set_downloads( $files ); + + return $product; + } + + /** + * Save taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param array $terms Terms data. + * @param string $taxonomy Taxonomy name. + * @return WC_Product + */ + protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { + $term_ids = wp_list_pluck( $terms, 'id' ); + + if ( 'cat' === $taxonomy ) { + $product->set_category_ids( $term_ids ); + } elseif ( 'tag' === $taxonomy ) { + $product->set_tag_ids( $term_ids ); + } + + return $product; + } + + /** + * Save default attributes. + * + * @since 3.0.0 + * + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return WC_Product + */ + protected function save_default_attributes( $product, $request ) { + if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { + $attributes = $product->get_attributes(); + $default_attributes = array(); + + foreach ( $request['default_attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( isset( $attributes[ $attribute_name ] ) ) { + $_attribute = $attributes[ $attribute_name ]; + + if ( $_attribute['is_variation'] ) { + $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( ! empty( $_attribute['is_taxonomy'] ) ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $value = $term->slug; + } else { + $value = sanitize_title( $value ); + } + } + + if ( $value ) { + $default_attributes[ $attribute_name ] = $value; + } + } + } + } + + $product->set_default_attributes( $default_attributes ); + } + + return $product; + } + + /** + * Save product meta. + * + * @deprecated 3.0.0 + * @param WC_Product $product + * @param WP_REST_Request $request + * @return bool + * @throws WC_REST_Exception + */ + protected function save_product_meta( $product, $request ) { + $product = $this->set_product_meta( $product, $request ); + $product->save(); + + return true; + } + + /** + * Set product meta. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return WC_Product + */ + protected function set_product_meta( $product, $request ) { + // Virtual. + if ( isset( $request['virtual'] ) ) { + $product->set_virtual( $request['virtual'] ); + } + + // Tax status. + if ( isset( $request['tax_status'] ) ) { + $product->set_tax_status( $request['tax_status'] ); + } + + // Tax Class. + if ( isset( $request['tax_class'] ) ) { + $product->set_tax_class( $request['tax_class'] ); + } + + // Catalog Visibility. + if ( isset( $request['catalog_visibility'] ) ) { + $product->set_catalog_visibility( $request['catalog_visibility'] ); + } + + // Purchase Note. + if ( isset( $request['purchase_note'] ) ) { + $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); + } + + // Featured Product. + if ( isset( $request['featured'] ) ) { + $product->set_featured( $request['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $request ); + + // SKU. + if ( isset( $request['sku'] ) ) { + $product->set_sku( wc_clean( $request['sku'] ) ); + } + + // Attributes. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + } else { + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $product->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $product->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + } + + // Product parent ID for groups. + if ( isset( $request['parent_id'] ) ) { + $product->set_parent_id( $request['parent_id'] ); + } + + // Sold individually. + if ( isset( $request['sold_individually'] ) ) { + $product->set_sold_individually( $request['sold_individually'] ); + } + + // Stock status. + if ( isset( $request['in_stock'] ) ) { + $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; + } else { + $stock_status = $product->get_stock_status(); + } + + // Stock data. + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $request['manage_stock'] ) ) { + $product->set_manage_stock( $request['manage_stock'] ); + } + + // Backorders. + if ( isset( $request['backorders'] ) ) { + $product->set_backorders( $request['backorders'] ); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( $product->get_manage_stock() ) { + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $request['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $request['upsell_ids'] ) ) { + $upsells = array(); + $ids = $request['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + } + + $product->set_upsell_ids( $upsells ); + } + + // Cross sells. + if ( isset( $request['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $request['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + } + + $product->set_cross_sell_ids( $crosssells ); + } + + // Product categories. + if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); + } + + // Downloadable. + if ( isset( $request['downloadable'] ) ) { + $product->set_downloadable( $request['downloadable'] ); + } + + // Downloadable options. + if ( $product->get_downloadable() ) { + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $product->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $product->set_download_expiry( $request['download_expiry'] ); + } + } + + // Product url and button text for external products. + if ( $product->is_type( 'external' ) ) { + if ( isset( $request['external_url'] ) ) { + $product->set_product_url( $request['external_url'] ); + } + + if ( isset( $request['button_text'] ) ) { + $product->set_button_text( $request['button_text'] ); + } + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $request ); + } + + return $product; + } + + /** + * Save variations. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return bool + */ + protected function save_variations_data( $product, $request ) { + foreach ( $request['variations'] as $menu_order => $data ) { + $variation = new WC_Product_Variation( isset( $data['id'] ) ? absint( $data['id'] ) : 0 ); + + // Create initial name and status. + if ( ! $variation->get_slug() ) { + /* translators: 1: variation id 2: product name */ + $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); + $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); + } + + // Parent ID. + $variation->set_parent_id( $product->get_id() ); + + // Menu order. + $variation->set_menu_order( $menu_order ); + + // Status. + if ( isset( $data['visible'] ) ) { + $variation->set_status( false === $data['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $data['sku'] ) ) { + $variation->set_sku( wc_clean( $data['sku'] ) ); + } + + // Thumbnail. + if ( isset( $data['image'] ) && is_array( $data['image'] ) ) { + $image = $data['image']; + $image = current( $image ); + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->set_product_images( $variation, array( $image ) ); + } + + // Virtual variation. + if ( isset( $data['virtual'] ) ) { + $variation->set_virtual( $data['virtual'] ); + } + + // Downloadable variation. + if ( isset( $data['downloadable'] ) ) { + $variation->set_downloadable( $data['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $data['downloads'] ); + } + + // Download limit. + if ( isset( $data['download_limit'] ) ) { + $variation->set_download_limit( $data['download_limit'] ); + } + + // Download expiry. + if ( isset( $data['download_expiry'] ) ) { + $variation->set_download_expiry( $data['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $data ); + + // Stock handling. + if ( isset( $data['manage_stock'] ) ) { + $variation->set_manage_stock( $data['manage_stock'] ); + } + + if ( isset( $data['in_stock'] ) ) { + $variation->set_stock_status( true === $data['in_stock'] ? 'instock' : 'outofstock' ); + } + + if ( isset( $data['backorders'] ) ) { + $variation->set_backorders( $data['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $data['stock_quantity'] ) ) { + $variation->set_stock_quantity( $data['stock_quantity'] ); + } elseif ( isset( $data['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $data['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $data['regular_price'] ) ) { + $variation->set_regular_price( $data['regular_price'] ); + } + + // Sale Price. + if ( isset( $data['sale_price'] ) ) { + $variation->set_sale_price( $data['sale_price'] ); + } + + if ( isset( $data['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $data['date_on_sale_from'] ); + } + + if ( isset( $data['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $data['date_on_sale_to'] ); + } + + // Tax class. + if ( isset( $data['tax_class'] ) ) { + $variation->set_tax_class( $data['tax_class'] ); + } + + // Description. + if ( isset( $data['description'] ) ) { + $variation->set_description( wp_kses_post( $data['description'] ) ); + } + + // Update taxonomies. + if ( isset( $data['attributes'] ) ) { + $attributes = array(); + $parent_attributes = $product->get_attributes(); + + foreach ( $data['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + $variation->save(); + + do_action( 'woocommerce_rest_save_product_variation', $variation->get_id(), $menu_order, $data ); + } + + return true; + } + + /** + * Add post meta fields. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request data. + * @return bool|WP_Error + */ + protected function add_post_meta_fields( $post, $request ) { + return $this->update_post_meta_fields( $post, $request ); + } + + /** + * Update post meta fields. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request data. + * @return bool|WP_Error + */ + protected function update_post_meta_fields( $post, $request ) { + $product = wc_get_product( $post ); + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + $product = $this->set_product_images( $product, $request['images'] ); + } + + // Save product meta fields. + $product = $this->set_product_meta( $product, $request ); + + // Save the product data. + $product->save(); + + // Save variations. + if ( $product->is_type( 'variable' ) ) { + if ( isset( $request['variations'] ) && is_array( $request['variations'] ) ) { + $this->save_variations_data( $product, $request ); + } + } + + // Clear caches here so in sync with any new variations/children. + wc_delete_product_transients( $product->get_id() ); + wp_cache_delete( 'product-' . $product->get_id(), 'products' ); + + return true; + } + + /** + * Clear cache/transients. + * + * @param WP_Post $post Post data. + */ + public function clear_transients( $post ) { + wc_delete_product_transients( $post->ID ); + } + + /** + * Delete post. + * + * @param int|WP_Post $id Post ID or WP_Post instance. + */ + protected function delete_post( $id ) { + if ( ! empty( $id->ID ) ) { + $id = $id->ID; + } elseif ( ! is_numeric( $id ) || 0 >= $id ) { + return; + } + + // Delete product attachments. + $attachments = get_posts( array( + 'post_parent' => $id, + 'post_status' => 'any', + 'post_type' => 'attachment', + ) ); + + foreach ( (array) $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + // Delete product. + $product = wc_get_product( $id ); + $product->delete( true ); + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = (bool) $request['force']; + $post = get_post( $id ); + $product = wc_get_product( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0; + + /** + * Filter whether an item is trashable. + * + * Return false to disable trash support for the item. + * + * @param boolean $supports_trash Whether the item type support trashing. + * @param WP_Post $post The Post object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + if ( $product->is_type( 'variable' ) ) { + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->delete( true ); + } + } + } else { + // For other product types, if the product has children, remove the relationship. + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->set_parent_id( 0 ); + $child->save(); + } + } + } + + $product->delete( true ); + $result = ! ( $product->get_id() > 0 ); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( 'trash' === $post->post_status ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + // (Note that internally this falls through to `wp_delete_post` if + // the trash is disabled.) + $product->delete(); + $result = 'trash' === $product->get_status(); + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + // Delete parent product transients. + if ( $parent_id = wp_get_post_parent_id( $id ) ) { + wc_delete_product_transients( $parent_id ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param object $post The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); + + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( 'Start date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( 'End date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_type' => array( + 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'standard', + 'enum' => array( 'standard' ), + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of upsell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Variation ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( 'Start date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( 'End date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'visible' => array( + 'description' => __( 'If the variation is visible.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['slug'] = array( + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['type'] = array( + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_types() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['category'] = array( + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['tag'] = array( + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['shipping_class'] = array( + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute'] = array( + 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute_term'] = array( + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['sku'] = array( + 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-report-sales-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-report-sales-v1-controller.php new file mode 100644 index 00000000000..ebd52c67565 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-report-sales-v1-controller.php @@ -0,0 +1,397 @@ +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' ), + ) ); + } + + /** + * Check whether a given request has permission to read report. + * + * @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( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get sales reports. + * + * @param WP_REST_Request $request + * @return array|WP_Error + */ + public function get_items( $request ) { + $data = array(); + $item = $this->prepare_item_for_response( null, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report sales object for serialization. + * + * @param null $_ + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $_, $request ) { + // Set date filtering. + $filter = array( + 'period' => $request['period'], + 'date_min' => $request['date_min'], + 'date_max' => $request['date_max'], + ); + $this->setup_report( $filter ); + + // New customers. + $users_query = new WP_User_Query( + array( + 'fields' => array( 'user_registered' ), + 'role' => 'customer', + ) + ); + + $customers = $users_query->get_results(); + + foreach ( $customers as $key => $customer ) { + if ( strtotime( $customer->user_registered ) < $this->report->start_date || strtotime( $customer->user_registered ) > $this->report->end_date ) { + unset( $customers[ $key ] ); + } + } + + $total_customers = count( $customers ); + $report_data = $this->report->get_report_data(); + $period_totals = array(); + + // Setup period totals by ensuring each period in the interval has data. + for ( $i = 0; $i <= $this->report->chart_interval; $i++ ) { + + switch ( $this->report->chart_groupby ) { + case 'day' : + $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $this->report->start_date ) ); + break; + default : + $time = date( 'Y-m', strtotime( "+{$i} MONTH", $this->report->start_date ) ); + break; + } + + // Set the customer signups for each period. + $customer_count = 0; + foreach ( $customers as $customer ) { + if ( date( ( 'day' == $this->report->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) { + $customer_count++; + } + } + + $period_totals[ $time ] = array( + 'sales' => wc_format_decimal( 0.00, 2 ), + 'orders' => 0, + 'items' => 0, + 'tax' => wc_format_decimal( 0.00, 2 ), + 'shipping' => wc_format_decimal( 0.00, 2 ), + 'discount' => wc_format_decimal( 0.00, 2 ), + 'customers' => $customer_count, + ); + } + + // add total sales, total order count, total tax and total shipping for each period + foreach ( $report_data->orders as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 ); + $period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 ); + $period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 ); + } + + foreach ( $report_data->order_counts as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['orders'] = (int) $order->count; + } + + // Add total order items for each period. + foreach ( $report_data->order_items as $order_item ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['items'] = (int) $order_item->order_item_count; + } + + // Add total discount for each period. + foreach ( $report_data->coupons as $discount ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 ); + } + + $sales_data = array( + 'total_sales' => $report_data->total_sales, + 'net_sales' => $report_data->net_sales, + 'average_sales' => $report_data->average_sales, + 'total_orders' => $report_data->total_orders, + 'total_items' => $report_data->total_items, + 'total_tax' => wc_format_decimal( $report_data->total_tax + $report_data->total_shipping_tax, 2 ), + 'total_shipping' => $report_data->total_shipping, + 'total_refunds' => $report_data->total_refunds, + 'total_discount' => $report_data->total_coupons, + 'totals_grouped_by' => $this->report->chart_groupby, + 'totals' => $period_totals, + 'total_customers' => $total_customers, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $sales_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( array( + 'about' => array( + 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), + ), + ) ); + + /** + * Filter a report sales returned from the API. + * + * Allows modification of the report sales data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $data The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_sales', $response, (object) $sales_data, $request ); + } + + /** + * Setup the report object and parse any date filtering. + * + * @param array $filter date filtering + */ + protected function setup_report( $filter ) { + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' ); + + $this->report = new WC_Report_Sales_By_Date(); + + if ( empty( $filter['period'] ) ) { + // Custom date range. + $filter['period'] = 'custom'; + + if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) { + + // Overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges. + $_GET['start_date'] = $filter['date_min']; + $_GET['end_date'] = isset( $filter['date_max'] ) ? $filter['date_max'] : null; + + } else { + + // Default custom range to today. + $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); + } + } else { + $filter['period'] = empty( $filter['period'] ) ? 'week' : $filter['period']; + + // Change "week" period to "7day". + if ( 'week' === $filter['period'] ) { + $filter['period'] = '7day'; + } + } + + $this->report->calculate_current_range( $filter['period'] ); + } + + /** + * 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' => 'sales_report', + 'type' => 'object', + 'properties' => array( + 'total_sales' => array( + 'description' => __( 'Gross sales in the period.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'net_sales' => array( + 'description' => __( 'Net sales in the period.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'average_sales' => array( + 'description' => __( 'Average net daily sales.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_orders' => array( + 'description' => __( 'Total of orders placed.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_items' => array( + 'description' => __( 'Total of items purchased.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Total charged for taxes.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_shipping' => array( + 'description' => __( 'Total charged for shipping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_refunds' => array( + 'description' => __( 'Total of refunded orders.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_discount' => array( + 'description' => __( 'Total of coupons used.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'totals_grouped_by' => array( + 'description' => __( 'Group type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'totals' => array( + 'description' => __( 'Totals.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'array', + ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + 'period' => array( + 'description' => __( 'Report period.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'week', 'month', 'last_month', 'year' ), + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'date_min' => array( + /* translators: %s: date format */ + 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), + 'type' => 'string', + 'format' => 'date', + 'validate_callback' => 'wc_rest_validate_reports_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'date_max' => array( + /* translators: %s: date format */ + 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), + 'type' => 'string', + 'format' => 'date', + 'validate_callback' => 'wc_rest_validate_reports_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-report-top-sellers-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-report-top-sellers-v1-controller.php new file mode 100644 index 00000000000..8d581540858 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-report-top-sellers-v1-controller.php @@ -0,0 +1,174 @@ + $request['period'], + 'date_min' => $request['date_min'], + 'date_max' => $request['date_max'], + ); + $this->setup_report( $filter ); + + $report_data = $this->report->get_order_report_data( array( + 'data' => array( + '_product_id' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => '', + 'name' => 'product_id', + ), + '_qty' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => 'SUM', + 'name' => 'order_item_qty', + ), + ), + 'order_by' => 'order_item_qty DESC', + 'group_by' => 'product_id', + 'limit' => isset( $filter['limit'] ) ? absint( $filter['limit'] ) : 12, + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + $top_sellers = array(); + + foreach ( $report_data as $item ) { + $product = wc_get_product( $item->product_id ); + + if ( $product ) { + $top_sellers[] = array( + 'name' => $product->get_name(), + 'product_id' => (int) $item->product_id, + 'quantity' => wc_stock_amount( $item->order_item_qty ), + ); + } + } + + $data = array(); + foreach ( $top_sellers as $top_seller ) { + $item = $this->prepare_item_for_response( (object) $top_seller, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report sales object for serialization. + * + * @param stdClass $top_seller + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $top_seller, $request ) { + $data = array( + 'name' => $top_seller->name, + 'product_id' => $top_seller->product_id, + 'quantity' => $top_seller->quantity, + ); + + $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( array( + 'about' => array( + 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), + ), + 'product' => array( + 'href' => rest_url( sprintf( '/%s/products/%s', $this->namespace, $top_seller->product_id ) ), + ), + ) ); + + /** + * Filter a report top sellers returned from the API. + * + * Allows modification of the report top sellers data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $top_seller The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_top_sellers', $response, $top_seller, $request ); + } + + /** + * 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' => 'top_sellers_report', + 'type' => 'object', + 'properties' => array( + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'quantity' => array( + 'description' => __( 'Total number of purchases.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-reports-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-reports-v1-controller.php new file mode 100644 index 00000000000..4b40f00875f --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-reports-v1-controller.php @@ -0,0 +1,184 @@ +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' ), + ) ); + } + + /** + * Check whether a given request has permission to read reports. + * + * @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( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get reports list. + * + * @since 3.5.0 + * @return array + */ + protected function get_reports() { + return array( + array( + 'slug' => 'sales', + 'description' => __( 'List of sales reports.', 'woocommerce' ), + ), + array( + 'slug' => 'top_sellers', + 'description' => __( 'List of top sellers products.', 'woocommerce' ), + ), + ); + } + + /** + * Get all reports. + * + * @param WP_REST_Request $request + * @return array|WP_Error + */ + public function get_items( $request ) { + $data = array(); + $reports = $this->get_reports(); + + foreach ( $reports as $report ) { + $item = $this->prepare_item_for_response( (object) $report, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'description' => $report->description, + ); + + $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( array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $report->slug ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), + ), + ) ); + + /** + * 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', $response, $report, $request ); + } + + /** + * 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', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-tax-classes-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-tax-classes-v1-controller.php new file mode 100644 index 00000000000..6e5b25d8cd6 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-tax-classes-v1-controller.php @@ -0,0 +1,364 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', array( + 'args' => array( + 'slug' => array( + 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read tax classes. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create tax classes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all tax classes. + * + * @param WP_REST_Request $request + * @return array + */ + public function get_items( $request ) { + $tax_classes = array(); + + // Add standard class. + $tax_classes[] = array( + 'slug' => 'standard', + 'name' => __( 'Standard rate', 'woocommerce' ), + ); + + $classes = WC_Tax::get_tax_classes(); + + foreach ( $classes as $class ) { + $tax_classes[] = array( + 'slug' => sanitize_title( $class ), + 'name' => $class, + ); + } + + $data = array(); + foreach ( $tax_classes as $tax_class ) { + $class = $this->prepare_item_for_response( $tax_class, $request ); + $class = $this->prepare_response_for_collection( $class ); + $data[] = $class; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + $exists = false; + $classes = WC_Tax::get_tax_classes(); + $tax_class = array( + 'slug' => sanitize_title( $request['name'] ), + 'name' => $request['name'], + ); + + // Check if class exists. + foreach ( $classes as $key => $class ) { + if ( sanitize_title( $class ) === $tax_class['slug'] ) { + $exists = true; + break; + } + } + + // Return error if tax class already exists. + if ( $exists ) { + return new WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Add the new class. + $classes[] = $tax_class['name']; + + update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); + + $this->update_additional_fields_for_object( $tax_class, $request ); + + /** + * Fires after a tax class is created or updated via the REST API. + * + * @param stdClass $tax_class Data used to create the tax class. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax class, false when updating tax class. + */ + do_action( 'woocommerce_rest_insert_tax_class', (object) $tax_class, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax_class, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $tax_class['slug'] ) ) ); + + return $response; + } + + /** + * Delete a single tax class. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + global $wpdb; + + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $tax_class = array( + 'slug' => sanitize_title( $request['slug'] ), + 'name' => '', + ); + $classes = WC_Tax::get_tax_classes(); + $deleted = false; + + foreach ( $classes as $key => $class ) { + if ( sanitize_title( $class ) === $tax_class['slug'] ) { + $tax_class['name'] = $class; + unset( $classes[ $key ] ); + $deleted = true; + break; + } + } + + if ( ! $deleted ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); + + // Delete tax rate locations locations from the selected class. + $wpdb->query( $wpdb->prepare( " + DELETE locations.* + FROM {$wpdb->prefix}woocommerce_tax_rate_locations AS locations + INNER JOIN + {$wpdb->prefix}woocommerce_tax_rates AS rates + ON rates.tax_rate_id = locations.tax_rate_id + WHERE rates.tax_rate_class = '%s' + ", $tax_class['slug'] ) ); + + // Delete tax rates in the selected class. + $wpdb->delete( $wpdb->prefix . 'woocommerce_tax_rates', array( 'tax_rate_class' => $tax_class['slug'] ), array( '%s' ) ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax_class, $request ); + + /** + * Fires after a tax class is deleted via the REST API. + * + * @param stdClass $tax_class The tax data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_tax', (object) $tax_class, $response, $request ); + + return $response; + } + + /** + * Prepare a single tax class output for response. + * + * @param array $tax_class Tax class data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $tax_class, $request ) { + $data = $tax_class; + + $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() ); + + /** + * Filter tax object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $tax_class Tax object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_tax', $response, (object) $tax_class, $request ); + } + + /** + * Prepare links for the request. + * + * @return array Links for the given tax class. + */ + protected function prepare_links() { + $links = array( + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Tax Classes schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'tax_class', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Tax class name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'required' => true, + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-taxes-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-taxes-v1-controller.php new file mode 100644 index 00000000000..278e87bd999 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-taxes-v1-controller.php @@ -0,0 +1,709 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read taxes. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create taxes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a tax. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all taxes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + global $wpdb; + + $prepared_args = array(); + $prepared_args['order'] = $request['order']; + $prepared_args['number'] = $request['per_page']; + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + $orderby_possibles = array( + 'id' => 'tax_rate_id', + 'order' => 'tax_rate_order', + ); + $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; + $prepared_args['class'] = $request['class']; + + /** + * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. + * + * @param array $prepared_args Array of arguments for $wpdb->get_results(). + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request ); + + $query = " + SELECT * + FROM {$wpdb->prefix}woocommerce_tax_rates + WHERE 1 = 1 + "; + + // Filter by tax class. + if ( ! empty( $prepared_args['class'] ) ) { + $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; + $query .= " AND tax_rate_class = '$class'"; + } + + // Order tax rates. + $order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) ); + + // Pagination. + $pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] ); + + // Query taxes. + $results = $wpdb->get_results( $query . $order_by . $pagination ); + + $taxes = array(); + foreach ( $results as $tax ) { + $data = $this->prepare_item_for_response( $tax, $request ); + $taxes[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $taxes ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + // Query only for ids. + $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); + + // Calculate totals. + $total_taxes = (int) $wpdb->num_rows; + $response->header( 'X-WP-Total', (int) $total_taxes ); + $max_pages = ceil( $total_taxes / $per_page ); + $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; + } + + /** + * Take tax data from the request and return the updated or newly created rate. + * + * @param WP_REST_Request $request Full details about the request. + * @param stdClass|null $current Existing tax object. + * @return object + */ + protected function create_or_update_tax( $request, $current = null ) { + $id = absint( isset( $request['id'] ) ? $request['id'] : 0 ); + $data = array(); + $fields = array( + 'tax_rate_country', + 'tax_rate_state', + 'tax_rate', + 'tax_rate_name', + 'tax_rate_priority', + 'tax_rate_compound', + 'tax_rate_shipping', + 'tax_rate_order', + 'tax_rate_class', + ); + + foreach ( $fields as $field ) { + // Keys via API differ from the stored names returned by _get_tax_rate. + $key = 'tax_rate' === $field ? 'rate' : str_replace( 'tax_rate_', '', $field ); + + // Remove data that was not posted. + if ( ! isset( $request[ $key ] ) ) { + continue; + } + + // Test new data against current data. + if ( $current && $current->$field === $request[ $key ] ) { + continue; + } + + // Add to data array. + switch ( $key ) { + case 'tax_rate_priority' : + case 'tax_rate_compound' : + case 'tax_rate_shipping' : + case 'tax_rate_order' : + $data[ $field ] = absint( $request[ $key ] ); + break; + case 'tax_rate_class' : + $data[ $field ] = 'standard' !== $request['tax_rate_class'] ? $request['tax_rate_class'] : ''; + break; + default : + $data[ $field ] = wc_clean( $request[ $key ] ); + break; + } + } + + if ( $id ) { + WC_Tax::_update_tax_rate( $id, $data ); + } else { + $id = WC_Tax::_insert_tax_rate( $data ); + } + + // Add locales. + if ( ! empty( $request['postcode'] ) ) { + WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) ); + } + if ( ! empty( $request['city'] ) ) { + WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) ); + } + + return WC_Tax::_get_tax_rate( $id, OBJECT ); + } + + /** + * Create a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $tax = $this->create_or_update_tax( $request ); + + $this->update_additional_fields_for_object( $tax, $request ); + + /** + * Fires after a tax is created or updated via the REST API. + * + * @param stdClass $tax Data used to create the tax. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax, false when updating tax. + */ + do_action( 'woocommerce_rest_insert_tax', $tax, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ) ); + + return $response; + } + + /** + * Get a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax_obj ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tax = $this->prepare_item_for_response( $tax_obj, $request ); + $response = rest_ensure_response( $tax ); + + return $response; + } + + /** + * Update a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax_obj ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tax = $this->create_or_update_tax( $request, $tax_obj ); + + $this->update_additional_fields_for_object( $tax, $request ); + + /** + * Fires after a tax is created or updated via the REST API. + * + * @param stdClass $tax Data used to create the tax. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax, false when updating tax. + */ + do_action( 'woocommerce_rest_insert_tax', $tax, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + $response = rest_ensure_response( $response ); + + return $response; + } + + /** + * Delete a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + global $wpdb; + + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $tax = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + + WC_Tax::_delete_tax_rate( $id ); + + if ( 0 === $wpdb->rows_affected ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a tax is deleted via the REST API. + * + * @param stdClass $tax The tax data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request ); + + return $response; + } + + /** + * Prepare a single tax output for response. + * + * @param stdClass $tax Tax object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $tax, $request ) { + global $wpdb; + + $id = (int) $tax->tax_rate_id; + $data = array( + 'id' => $id, + 'country' => $tax->tax_rate_country, + 'state' => $tax->tax_rate_state, + 'postcode' => '', + 'city' => '', + 'rate' => $tax->tax_rate, + 'name' => $tax->tax_rate_name, + 'priority' => (int) $tax->tax_rate_priority, + 'compound' => (bool) $tax->tax_rate_compound, + 'shipping' => (bool) $tax->tax_rate_shipping, + 'order' => (int) $tax->tax_rate_order, + 'class' => $tax->tax_rate_class ? $tax->tax_rate_class : 'standard', + ); + + // Get locales from a tax rate. + $locales = $wpdb->get_results( $wpdb->prepare( " + SELECT location_code, location_type + FROM {$wpdb->prefix}woocommerce_tax_rate_locations + WHERE tax_rate_id = %d + ", $id ) ); + + if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) { + foreach ( $locales as $locale ) { + $data[ $locale->location_type ] = $locale->location_code; + } + } + + $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( $tax ) ); + + /** + * Filter tax object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $tax Tax object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_tax', $response, $tax, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $tax Tax object. + * @return array Links for the given tax. + */ + protected function prepare_links( $tax ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Taxes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'tax', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'country' => array( + 'description' => __( 'Country ISO 3166 code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'State code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postcode / ZIP.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'rate' => array( + 'description' => __( 'Tax rate.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tax rate name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'priority' => array( + 'description' => __( 'Tax priority.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 1, + 'context' => array( 'view', 'edit' ), + ), + 'compound' => array( + 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'shipping' => array( + 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'standard', + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + 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(); + $params['context']['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['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( + 'default' => 'asc', + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'enum' => array( 'asc', 'desc' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'default' => 'order', + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'enum' => array( + 'id', + 'order', + ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['class'] = array( + 'description' => __( 'Sort by tax class.', 'woocommerce' ), + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'sanitize_callback' => 'sanitize_title', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-webhook-deliveries-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-webhook-deliveries-v1-controller.php new file mode 100644 index 00000000000..a3b2cd81981 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-webhook-deliveries-v1-controller.php @@ -0,0 +1,314 @@ +/deliveries endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Webhook Deliveries controller class. + * + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @package WooCommerce/RestApi + * @extends WC_REST_Controller + */ +class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'webhooks/(?P[\d]+)/deliveries'; + + /** + * Register the routes for webhook deliveries. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'webhook_id' => array( + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + 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( + 'webhook_id' => array( + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read taxes. + * + * @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( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a tax. + * + * @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( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all webhook deliveries. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $webhook = wc_get_webhook( (int) $request['webhook_id'] ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $logs = array(); + $data = array(); + foreach ( $logs as $log ) { + $delivery = $this->prepare_item_for_response( (object) $log, $request ); + $delivery = $this->prepare_response_for_collection( $delivery ); + $data[] = $delivery; + } + + return rest_ensure_response( $data ); + } + + /** + * Get a single webhook delivery. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $webhook = wc_get_webhook( (int) $request['webhook_id'] ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $log = array(); + + if ( empty( $id ) || empty( $log ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $delivery = $this->prepare_item_for_response( (object) $log, $request ); + $response = rest_ensure_response( $delivery ); + + return $response; + } + + /** + * Prepare a single webhook delivery output for response. + * + * @param stdClass $log Delivery log object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $log, $request ) { + $data = (array) $log; + $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( $log ) ); + + /** + * Filter webhook delivery object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $log Delivery log object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $log Delivery log object. + * @return array Links for the given webhook delivery. + */ + protected function prepare_links( $log ) { + $webhook_id = (int) $log->request_headers['X-WC-Webhook-ID']; + $base = str_replace( '(?P[\d]+)', $webhook_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $log->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/webhooks/%d', $this->namespace, $webhook_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook_delivery', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'duration' => array( + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'summary' => array( + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_url' => array( + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_headers' => array( + 'description' => __( 'Request headers.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'request_body' => array( + 'description' => __( 'Request body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_code' => array( + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_message' => array( + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_headers' => array( + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'response_body' => array( + 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + '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() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/src/RestApi/AllYourBase/class-wc-rest-webhooks-v1-controller.php b/src/RestApi/AllYourBase/class-wc-rest-webhooks-v1-controller.php new file mode 100644 index 00000000000..97b1640ac56 --- /dev/null +++ b/src/RestApi/AllYourBase/class-wc-rest-webhooks-v1-controller.php @@ -0,0 +1,763 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'topic' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook topic.', 'woocommerce' ), + ), + 'delivery_url' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read webhooks. + * + * @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( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create webhooks. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a webhook. + * + * @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( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a webhook. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a webhook. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get the default REST API version. + * + * @since 3.0.0 + * @return string + */ + protected function get_default_api_version() { + return 'wp_api_v1'; + } + + /** + * Get all webhooks. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $args = array(); + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['status'] = 'all' === $request['status'] ? '' : $request['status']; + $args['include'] = implode( ',', $request['include'] ); + $args['exclude'] = implode( ',', $request['exclude'] ); + $args['limit'] = $request['per_page']; + $args['search'] = $request['search']; + $args['before'] = $request['before']; + $args['after'] = $request['after']; + + if ( empty( $request['offset'] ) ) { + $args['offset'] = 1 < $request['page'] ? ( $request['page'] - 1 ) * $args['limit'] : 0; + } + + /** + * Filter arguments, before passing to WC_Webhook_Data_Store->search_webhooks, when querying webhooks via the REST API. + * + * @param array $args Array of arguments for $wpdb->get_results(). + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request ); + unset( $prepared_args['page'] ); + $prepared_args['paginate'] = true; + + // Get the webhooks. + $webhooks = array(); + $data_store = WC_Data_Store::load( 'webhook' ); + $results = $data_store->search_webhooks( $prepared_args ); + $webhook_ids = $results->webhooks; + + foreach ( $webhook_ids as $webhook_id ) { + $data = $this->prepare_item_for_response( $webhook_id, $request ); + $webhooks[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $webhooks ); + $per_page = (int) $prepared_args['limit']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + $total_webhooks = $results->total; + $max_pages = $results->max_num_pages; + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); + + $response->header( 'X-WP-Total', $total_webhooks ); + $response->header( 'X-WP-TotalPages', $max_pages ); + + 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; + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + + if ( empty( $id ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $id, $request ); + $response = rest_ensure_response( $data ); + + return $response; + } + + /** + * Create a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + // Validate topic. + if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Validate delivery URL. + if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + $webhook = new WC_Webhook(); + $webhook->set_name( $post->post_title ); + $webhook->set_user_id( $post->post_author ); + $webhook->set_status( 'publish' === $post->post_status ? 'active' : 'disabled' ); + $webhook->set_topic( $request['topic'] ); + $webhook->set_delivery_url( $request['delivery_url'] ); + $webhook->set_secret( ! empty( $request['secret'] ) ? $request['secret'] : wp_generate_password( 50, true, true ) ); + $webhook->set_api_version( $this->get_default_api_version() ); + $webhook->save(); + + $this->update_additional_fields_for_object( $webhook, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WC_Webhook $webhook Webhook data. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $webhook->get_id() ) ) ); + + // Send ping. + $webhook->deliver_ping(); + + return $response; + } + + /** + * Update a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Update topic. + if ( ! empty( $request['topic'] ) ) { + if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { + $webhook->set_topic( $request['topic'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update delivery URL. + if ( ! empty( $request['delivery_url'] ) ) { + if ( wc_is_valid_url( $request['delivery_url'] ) ) { + $webhook->set_delivery_url( $request['delivery_url'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update secret. + if ( ! empty( $request['secret'] ) ) { + $webhook->set_secret( $request['secret'] ); + } + + // Update status. + if ( ! empty( $request['status'] ) ) { + if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { + $webhook->set_status( $request['status'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + if ( isset( $post->post_title ) ) { + $webhook->set_name( $post->post_title ); + } + + $webhook->save(); + + $this->update_additional_fields_for_object( $webhook, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WC_Webhook $webhook Webhook data. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook, $request ); + $result = $webhook->delete( true ); + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param WC_Webhook $webhook The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_webhook_object", $webhook, $response, $request ); + + return $response; + } + + /** + * Prepare a single webhook for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $data = new stdClass; + + // Post ID. + if ( isset( $request['id'] ) ) { + $data->ID = absint( $request['id'] ); + } + + // Validate required POST fields. + if ( 'POST' === $request->get_method() && empty( $data->ID ) ) { + $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ); // @codingStandardsIgnoreLine + + // Post author. + $data->post_author = get_current_user_id(); + + // Post password. + $data->post_password = 'webhook_' . wp_generate_password(); + + // Post status. + $data->post_status = 'publish'; + } else { + + // Allow edit post title. + if ( ! empty( $request['name'] ) ) { + $data->post_title = $request['name']; + } + } + + // Comment status. + $data->comment_status = 'closed'; + + // Ping status. + $data->ping_status = 'closed'; + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param stdClass $data An object representing a single item prepared + * for inserting or updating the database. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $data, $request ); + } + + /** + * Prepare a single webhook output for response. + * + * @param int $id Webhook ID or object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $id, $request ) { + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $data = array( + 'id' => $webhook->get_id(), + 'name' => $webhook->get_name(), + 'status' => $webhook->get_status(), + 'topic' => $webhook->get_topic(), + 'resource' => $webhook->get_resource(), + 'event' => $webhook->get_event(), + 'hooks' => $webhook->get_hooks(), + 'delivery_url' => $webhook->get_delivery_url(), + 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), + ); + + $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( $webhook->get_id() ) ); + + /** + * Filter webhook object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Webhook $webhook Webhook object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); + } + + /** + * Prepare links for the request. + * + * @param int $id Webhook ID. + * @return array + */ + protected function prepare_links( $id ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Webhook status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'active', + 'enum' => array_keys( wc_get_webhook_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'topic' => array( + 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'resource' => array( + 'description' => __( 'Webhook resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'event' => array( + 'description' => __( 'Webhook event.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'hooks' => array( + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'delivery_url' => array( + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'secret' => array( + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $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['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' => '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', + 'id', + 'title', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['status'] = array( + 'default' => 'all', + 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'all', 'active', 'paused', 'disabled' ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-admin-notes-controller.php b/src/RestApi/Version4/class-wc-admin-rest-admin-notes-controller.php new file mode 100644 index 00000000000..6872f6b190b --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-admin-notes-controller.php @@ -0,0 +1,484 @@ +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-admin' ), + '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-admin' ), + 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-admin' ), 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-admin' ), 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-admin' ), + array( 'status' => 404 ) + ); + } + + // @todo Status is the only field that can be updated at the moment. We should also implement the "date reminder" setting. + $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-admin' ), 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 ( '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-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['type'] = array( + 'description' => __( 'Type of note.', 'woocommerce-admin' ), + 'type' => 'array', + 'sanitize_callback' => 'wp_parse_slug_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'enum' => WC_Admin_Note::get_allowed_types(), + 'type' => 'string', + ), + ); + $params['status'] = array( + 'description' => __( 'Status of note.', 'woocommerce-admin' ), + 'type' => 'array', + 'sanitize_callback' => 'wp_parse_slug_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'enum' => WC_Admin_Note::get_allowed_statuses(), + 'type' => 'string', + ), + ); + return $params; + } + + /** + * 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-admin' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Name of the note.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'The type of the note (e.g. error, warning, etc.).', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'locale' => array( + 'description' => __( 'Locale used for the note title and content.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Title of the note.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'content' => array( + 'description' => __( 'Content of the note.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'icon' => array( + 'description' => __( 'Icon (gridicon) for the note.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'content_data' => array( + 'description' => __( 'Content data for the note. JSON string. Available for re-localization.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'The status of the note (e.g. unactioned, actioned).', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'source' => array( + 'description' => __( 'Source of the note.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( 'Date the note was created.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'Date the note was created (GMT).', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, // @todo Allow date_reminder to be updated. + ), + 'date_reminder_gmt' => array( + 'description' => __( 'Date after which the user should be reminded of the note, if any (GMT).', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'actions' => array( + 'description' => __( 'An array of actions, if any, for the note.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-coupons-controller.php b/src/RestApi/Version4/class-wc-admin-rest-coupons-controller.php new file mode 100644 index 00000000000..dfde5b3ae8a --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-coupons-controller.php @@ -0,0 +1,93 @@ + __( 'Limit results to coupons with codes matching a given string.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } + + + /** + * Add coupon code searching to the WC API. + * + * @param WP_REST_Request $request Request data. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + if ( ! empty( $request['search'] ) ) { + $args['search'] = $request['search']; + $args['s'] = false; + } + + return $args; + } + + /** + * Get a collection of posts and add the code search option to WP_Query. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10, 2 ); + $response = parent::get_items( $request ); + remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10 ); + return $response; + } + + /** + * Add code searching to the WP Query + * + * @param string $where Where clause used to search posts. + * @param object $wp_query WP_Query object. + * @return string + */ + public static function add_wp_query_search_code_filter( $where, $wp_query ) { + global $wpdb; + + $search = $wp_query->get( 'search' ); + if ( $search ) { + $search = $wpdb->esc_like( $search ); + $search = "'%" . $search . "%'"; + $where .= ' AND ' . $wpdb->posts . '.post_title LIKE ' . $search; + } + + return $where; + } + +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-customers-controller.php b/src/RestApi/Version4/class-wc-admin-rest-customers-controller.php new file mode 100644 index 00000000000..d7cc898c812 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-customers-controller.php @@ -0,0 +1,50 @@ +data[] = $this->prepare_response_for_collection( + $this->prepare_item_for_response( + (object) array( + 'slug' => 'download-ips', + 'description' => __( 'An endpoint used for searching download logs for a specific IP address.', 'woocommerce-admin' ), + ), + $request + ) + ); + return $response; + } + +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php b/src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php new file mode 100644 index 00000000000..f4f7ea0bda8 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php @@ -0,0 +1,27 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Return the download IPs matching the passed parameters. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + global $wpdb; + + if ( isset( $request['match'] ) ) { + $downloads = $wpdb->get_results( + $wpdb->prepare( + "SELECT DISTINCT( user_ip_address ) FROM {$wpdb->prefix}wc_download_log + WHERE user_ip_address LIKE %s + LIMIT 10", + $request['match'] . '%' + ) + ); + } else { + return new WP_Error( 'woocommerce_rest_data_download_ips_invalid_request', __( 'Invalid request. Please pass the match parameter.', 'woocommerce-admin' ), array( 'status' => 400 ) ); + } + + $data = array(); + + if ( ! empty( $downloads ) ) { + foreach ( $downloads as $download ) { + $response = $this->prepare_item_for_response( $download, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare the data object for response. + * + * @since 3.5.0 + * @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 ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * 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_data_download_ip', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given object. + */ + protected function prepare_links( $item ) { + $links = array( + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + return $links; + } + + /** + * 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['match'] = array( + 'description' => __( 'A partial IP address can be passed and matching results will be returned.', 'woocommerce-admin' ), + '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' => 'data_download_ips', + 'type' => 'object', + 'properties' => array( + 'user_ip_address' => array( + 'type' => 'string', + 'description' => __( 'IP address.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php b/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php new file mode 100644 index 00000000000..d0016317749 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php @@ -0,0 +1,546 @@ +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' ), + ), + 'schema' => array( $this, 'get_public_allowed_item_schema' ), + ) + ); + } + + /** + * 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-admin' ), + 'headers' => array( + array( + 'label' => __( 'Coupon Code', 'woocommerce-admin' ), + ), + array( + 'label' => __( 'Orders', 'woocommerce-admin' ), + ), + array( + 'label' => __( 'Amount Discounted', 'woocommerce-admin' ), + ), + ), + '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-admin' ), + 'headers' => array( + array( + 'label' => __( 'Category', 'woocommerce-admin' ), + ), + array( + 'label' => __( 'Items Sold', 'woocommerce-admin' ), + ), + array( + 'label' => __( 'Net Revenue', 'woocommerce-admin' ), + ), + ), + '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-admin' ), + 'headers' => array( + array( + 'label' => __( 'Customer Name', 'woocommerce-admin' ), + ), + array( + 'label' => __( 'Orders', 'woocommerce-admin' ), + ), + array( + 'label' => __( 'Total Spend', 'woocommerce-admin' ), + ), + ), + '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-admin' ), + 'headers' => array( + array( + 'label' => __( 'Product', 'woocommerce-admin' ), + ), + array( + 'label' => __( 'Items Sold', 'woocommerce-admin' ), + ), + array( + 'label' => __( 'Net Revenue', 'woocommerce-admin' ), + ), + ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 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-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['persisted_query'] = array( + 'description' => __( 'URL query to persist across links.', 'woocommerce-admin' ), + '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-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'label' => array( + 'type' => 'string', + 'description' => __( 'Displayed title for the leaderboard.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'headers' => array( + 'type' => 'array', + 'description' => __( 'Table headers.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'array', + 'properties' => array( + 'label' => array( + 'description' => __( 'Table column header.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'rows' => array( + 'type' => 'array', + 'description' => __( 'Table rows.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'array', + 'properties' => array( + 'display' => array( + 'description' => __( 'Table cell display.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Table cell value.', 'woocommerce-admin' ), + '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/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php new file mode 100644 index 00000000000..29622add12e --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php @@ -0,0 +1,264 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get an array of all levels and child tasks. + * + * @todo Status values below should pull from the database task status once implemented. + */ + public function get_levels() { + $levels = array( + 'account' => array( + 'tasks' => array( + 'create_account' => array( + 'label' => __( 'Create an account', 'woocommerce-admin' ), + 'description' => __( 'Speed up & secure your store', 'woocommerce-admin' ), + 'illustration' => '', + 'status' => 'visible', + 'is_required' => false, + ), + ), + ), + 'storefront' => array( + 'tasks' => array( + 'add_products' => array( + 'label' => __( 'Add your products', 'woocommerce-admin' ), + 'description' => __( 'Bring your store to life', 'woocommerce-admin' ), + 'illustration' => '', + 'status' => 'visible', + 'is_required' => true, + ), + 'customize_appearance' => array( + 'label' => __( 'Customize Appearance', 'woocommerce-admin' ), + 'description' => __( 'Ensure your store is on-brand', 'woocommerce-admin' ), + 'illustration' => '', + 'status' => 'visible', + 'is_required' => false, + ), + ), + ), + 'checkout' => array( + 'id' => 'checkout', + 'tasks' => array( + 'configure_shipping' => array( + 'label' => __( 'Configure shipping', 'woocommerce-admin' ), + 'description' => __( 'Set up prices and destinations', 'woocommerce-admin' ), + 'illustration' => '', + 'status' => 'visible', + 'is_required' => true, + ), + 'configure_taxes' => array( + 'label' => __( 'Configure taxes', 'woocommerce-admin' ), + 'description' => __( 'Set up sales tax rates', 'woocommerce-admin' ), + 'illustration' => '', + 'status' => 'visible', + 'is_required' => false, + ), + 'configure_payments' => array( + 'label' => __( 'Configure payments', 'woocommerce-admin' ), + 'description' => __( 'Choose payment providers', 'woocommerce-admin' ), + 'illustration' => '', + 'status' => 'visible', + 'is_required' => true, + ), + ), + ), + ); + + return apply_filters( 'woocommerce_onboarding_levels', $levels ); + } + + /** + * Return all level items and child tasks. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + global $wpdb; + + $levels = $this->get_levels(); + $data = array(); + + if ( ! empty( $levels ) ) { + foreach ( $levels as $id => $level ) { + $level = $this->convert_to_non_associative( $level, $id ); + $response = $this->prepare_item_for_response( $level, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + } + + return rest_ensure_response( $data ); + } + + /** + * 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 ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * 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_onboarding_level', $response, $item, $request ); + } + + /** + * Convert the associative levels and tasks to non-associative for JSON use. + * + * @param array $item Level. + * @param string $id Level ID. + * @return array + */ + public function convert_to_non_associative( $item, $id ) { + $item = array( 'id' => $id ) + $item; + + $tasks = array(); + foreach ( $item['tasks'] as $key => $task ) { + $tasks[] = array( 'id' => $key ) + $task; + } + $item['tasks'] = $tasks; + + return $item; + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given object. + * @todo Check to make sure this generates a valid URL after #1897. + */ + protected function prepare_links( $item ) { + $links = array( + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/onboarding/tasks?level=%s', $this->namespace, $item['id'] ) ), + ), + ); + return $links; + } + + /** + * 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' => 'onboarding_level', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'type' => 'string', + 'description' => __( 'Level ID.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'tasks' => array( + 'type' => 'array', + 'description' => __( 'Array of tasks under the level.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Task ID.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Task label.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Task description.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'illustration' => array( + 'description' => __( 'URL for illustration used.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Task status.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'enum' => array( 'visible', 'hidden', 'in-progress', 'skipped', 'completed' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php new file mode 100644 index 00000000000..002010257de --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php @@ -0,0 +1,289 @@ +namespace, + '/' . $this->rest_base . '/install', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'install_plugin' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + ), + 'schema' => array( $this, 'get_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/activate', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'activate_plugin' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + ), + 'schema' => array( $this, 'get_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/connect-jetpack', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'connect_jetpack' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + ), + 'schema' => array( $this, 'get_connect_schema' ), + ) + ); + } + + /** + * Check if a given request has access to manage plugins. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + if ( ! current_user_can( 'install_plugins' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot manage plugins.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get an array of plugins that can be installed & activated via the endpoints. + */ + public function get_allowed_plugins() { + return apply_filters( + 'woocommerce_onboarding_plugins_whitelist', + array( + 'jetpack' => 'jetpack/jetpack.php', + 'woocommerce-services' => 'woocommerce-services/woocommerce-services.php', + ) + ); + } + + /** + * Installs the requested plugin. + * + * @param WP_REST_Request $request Full details about the request. + * @return array Plugin Status + */ + public function install_plugin( $request ) { + $allowed_plugins = $this->get_allowed_plugins(); + $plugin = sanitize_title_with_dashes( $request['plugin'] ); + if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) { + return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce-admin' ), 404 ); + } + + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + $slug = $plugin; + $path = $allowed_plugins[ $slug ]; + $installed_plugins = get_plugins(); + + if ( in_array( $path, array_keys( $installed_plugins ), true ) ) { + return( array( + 'slug' => $slug, + 'name' => $installed_plugins[ $path ]['Name'], + 'status' => 'success', + ) ); + } + + include_once ABSPATH . '/wp-admin/includes/admin.php'; + include_once ABSPATH . '/wp-admin/includes/plugin-install.php'; + include_once ABSPATH . '/wp-admin/includes/plugin.php'; + include_once ABSPATH . '/wp-admin/includes/class-wp-upgrader.php'; + include_once ABSPATH . '/wp-admin/includes/class-plugin-upgrader.php'; + + $api = plugins_api( + 'plugin_information', + array( + 'slug' => sanitize_key( $slug ), + 'fields' => array( + 'sections' => false, + ), + ) + ); + + if ( is_wp_error( $api ) ) { + return new WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce-admin' ), 500 ); + } + + $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); + $result = $upgrader->install( $api->download_link ); + + if ( is_wp_error( $result ) || is_null( $result ) ) { + return new WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce-admin' ), 500 ); + } + + return array( + 'slug' => $slug, + 'name' => $api->name, + 'status' => 'success', + ); + } + + /** + * Activate the requested plugin. + * + * @param WP_REST_Request $request Full details about the request. + * @return array Plugin Status + */ + public function activate_plugin( $request ) { + $allowed_plugins = $this->get_allowed_plugins(); + $plugin = sanitize_title_with_dashes( $request['plugin'] ); + if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) { + return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce-admin' ), 404 ); + } + + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + $slug = $plugin; + $path = $allowed_plugins[ $slug ]; + $installed_plugins = get_plugins(); + + if ( ! in_array( $path, array_keys( $installed_plugins ), true ) ) { + return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce-admin' ), 404 ); + } + + $result = activate_plugin( $path ); + if ( ! is_null( $result ) ) { + return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'The requested plugin could not be activated.', 'woocommerce-admin' ), 500 ); + } + + return( array( + 'slug' => $slug, + 'name' => $installed_plugins[ $path ]['Name'], + 'status' => 'success', + ) ); + } + + /** + * Generates a Jetpack Connect URL. + * + * @return array Connection URL for Jetpack + */ + public function connect_jetpack() { + if ( ! class_exists( 'Jetpack' ) ) { + return new WP_Error( 'woocommerce_rest_jetpack_not_active', __( 'Jetpack is not installed or active.', 'woocommerce-admin' ), 404 ); + } + + $next_step_slug = apply_filters( 'woocommerce_onboarding_after_jetpack_step', 'store-details' ); + $redirect_url = esc_url_raw( + add_query_arg( + array( + 'page' => 'wc-admin', + ), + admin_url( 'admin.php' ) + ) . '#/?step=' . $next_step_slug + ); + + $connect_url = Jetpack::init()->build_connect_url( true, $redirect_url, 'woocommerce-setup-wizard' ); + + // Redirect to local calypso instead of production. + if ( defined( 'WOOCOMMERCE_CALYPSO_LOCAL' ) && WOOCOMMERCE_CALYPSO_LOCAL ) { + $connect_url = add_query_arg( + array( + 'calypso_env' => 'development', + ), + $connect_url + ); + } + + return( array( + 'slug' => $slug, + 'name' => __( 'Jetpack', 'woocommerce-admin' ), + 'connectAction' => $connect_url, + ) ); + } + + /** + * 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' => 'onboarding_plugin', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'Plugin slug.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Plugin name.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Plugin status.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the schema, conforming to JSON Schema. + * + * @return array + */ + public function get_connect_schema() { + $schema = $this->get_item_schema(); + unset( $schema['properties']['status'] ); + $schema['properties']['connectAction'] = array( + 'description' => __( 'Action that should be completed to connect Jetpack.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ); + return $schema; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php new file mode 100644 index 00000000000..3cd2727e87f --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php @@ -0,0 +1,348 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to read onboarding profile data. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check whether a given request has permission to edit onboarding profile data. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot edit this resource.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Return all onboarding profile data. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $onboarding_data = get_option( 'wc_onboarding_profile', array() ); + $item_schema = $this->get_item_schema(); + + $items = array(); + foreach ( $item_schema['properties'] as $key => $property_schema ) { + $items[ $key ] = isset( $onboarding_data[ $key ] ) ? $onboarding_data[ $key ] : null; + } + + $item = $this->prepare_item_for_response( $items, $request ); + $data = $this->prepare_response_for_collection( $item ); + + return rest_ensure_response( $data ); + } + + /** + * Update onboarding profile data. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_items( $request ) { + $params = $request->get_json_params(); + $query_args = $this->prepare_objects_query( $params ); + $onboarding_data = get_option( 'wc_onboarding_profile', array() ); + update_option( 'wc_onboarding_profile', array_merge( $onboarding_data, $query_args ) ); + + $result = array( + 'status' => 'success', + 'message' => __( 'Onboarding profile data has been updated.', 'woocommerce-admin' ), + ); + + $response = $this->prepare_item_for_response( $result, $request ); + $data = $this->prepare_response_for_collection( $response ); + + return rest_ensure_response( $data ); + } + + /** + * Prepare objects query. + * + * @param array $params The params sent in the request. + * @return array + */ + protected function prepare_objects_query( $params ) { + $args = array(); + $properties = self::get_profile_properties(); + + foreach ( $properties as $key => $property ) { + if ( isset( $params[ $key ] ) ) { + $args[ $key ] = $params[ $key ]; + } + } + + /** + * 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 array $params The params sent in the request. + */ + $args = apply_filters( 'woocommerce_rest_onboarding_profile_object_query', $args, $params ); + + 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_onboarding_profile', $response, $item, $request ); + } + + /** + * Get onboarding profile properties. + * + * @return array + */ + public static function get_profile_properties() { + $properties = array( + 'completed' => array( + 'type' => 'boolean', + 'description' => __( 'Whether or not the profile was completed.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'validate_callback' => 'rest_validate_request_arg', + ), + 'skipped' => array( + 'type' => 'boolean', + 'description' => __( 'Whether or not the profile was skipped.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'validate_callback' => 'rest_validate_request_arg', + ), + 'account_type' => array( + 'type' => 'string', + 'description' => __( 'Account type used for Jetpack.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'validate_callback' => 'rest_validate_request_arg', + 'enum' => array( + 'new', + 'existing', + 'google', + ), + ), + 'industry' => array( + 'type' => 'array', + 'description' => __( 'Industry.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'sanitize_callback' => 'wp_parse_slug_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'enum' => array_keys( WC_Admin_Onboarding::get_allowed_industries() ), + 'type' => 'string', + ), + ), + 'product_types' => array( + 'type' => 'array', + 'description' => __( 'Types of products sold.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'sanitize_callback' => 'wp_parse_slug_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'enum' => array_keys( WC_Admin_Onboarding::get_allowed_product_types() ), + 'type' => 'string', + ), + ), + 'product_count' => array( + 'type' => 'string', + 'description' => __( 'Number of products to be added.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'validate_callback' => 'rest_validate_request_arg', + 'enum' => array( + '1-10', + '11-100', + '101-1000', + '1000+', + ), + ), + 'selling_venues' => array( + 'type' => 'string', + 'description' => __( 'Other places the store is selling products.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'validate_callback' => 'rest_validate_request_arg', + 'enum' => array( + 'no', + 'other', + 'brick-mortar', + 'brick-mortar-other', + ), + ), + 'other_platform' => array( + 'type' => 'string', + 'description' => __( 'Name of other platform used to sell.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'validate_callback' => 'rest_validate_request_arg', + 'enum' => array( + 'shopify', + 'bigcommerce', + 'magento', + 'wix', + 'other', + ), + ), + 'theme' => array( + 'type' => 'string', + 'description' => __( 'Selected store theme.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'sanitize_callback' => 'sanitize_title_with_dashes', + 'validate_callback' => 'rest_validate_request_arg', + ), + 'items_purchased' => array( + 'type' => 'boolean', + 'description' => __( 'Whether or not the user opted to purchase items now or later.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'validate_callback' => 'rest_validate_request_arg', + ), + ); + + return apply_filters( 'woocommerce_onboarding_profile_properties', $properties ); + } + + /** + * Get the schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + // Unset properties used for collection params. + $properties = self::get_profile_properties(); + foreach ( $properties as $key => $property ) { + unset( $properties[ $key ]['default'] ); + unset( $properties[ $key ]['items'] ); + unset( $properties[ $key ]['validate_callback'] ); + unset( $properties[ $key ]['sanitize_callback'] ); + } + + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'onboarding_profile', + 'type' => 'object', + 'properties' => $properties, + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + // Unset properties used for item schema. + $params = self::get_profile_properties(); + foreach ( $params as $key => $param ) { + unset( $params[ $key ]['context'] ); + unset( $params[ $key ]['readonly'] ); + } + + $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); + + return apply_filters( 'rest_onboarding_profile_collection_params', $params ); + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-orders-controller.php b/src/RestApi/Version4/class-wc-admin-rest-orders-controller.php new file mode 100644 index 00000000000..9769e5f4d32 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-orders-controller.php @@ -0,0 +1,75 @@ + __( 'Limit result set to orders matching part of an order number.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } + + /** + * Prepare objects query. + * + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + global $wpdb; + $args = parent::prepare_objects_query( $request ); + + // Search by partial order number. + if ( ! empty( $request['number'] ) ) { + $partial_number = trim( $request['number'] ); + $limit = intval( $args['posts_per_page'] ); + $order_ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT ID + FROM {$wpdb->prefix}posts + WHERE post_type = 'shop_order' + AND ID LIKE %s + LIMIT %d", + $wpdb->esc_like( absint( $partial_number ) ) . '%', + $limit + ) + ); + + // Force WP_Query return empty if don't found any order. + $order_ids = empty( $order_ids ) ? array( 0 ) : $order_ids; + $args['post__in'] = $order_ids; + } + + return $args; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-product-categories-controller.php b/src/RestApi/Version4/class-wc-admin-rest-product-categories-controller.php new file mode 100644 index 00000000000..672cd0c22ca --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-product-categories-controller.php @@ -0,0 +1,26 @@ + array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $review->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + if ( 0 !== (int) $review->comment_post_ID ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $review->comment_post_ID ) ), + 'embeddable' => true, + ); + } + if ( 0 !== (int) $review->user_id ) { + $links['reviewer'] = array( + 'href' => rest_url( 'wp/v2/users/' . $review->user_id ), + 'embeddable' => true, + ); + } + return $links; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php b/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php new file mode 100644 index 00000000000..92f4d866a28 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php @@ -0,0 +1,124 @@ + __( 'Search by similar product name or sku.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } + + /** + * Add product name and sku filtering to the WC API. + * + * @param WP_REST_Request $request Request data. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + if ( ! empty( $request['search'] ) ) { + $args['search'] = $request['search']; + unset( $args['s'] ); + } + + return $args; + } + + /** + * Get a collection of posts and add the post title filter option to WP_Query. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + add_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10, 2 ); + add_filter( 'posts_join', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_join' ), 10, 2 ); + add_filter( 'posts_groupby', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_group_by' ), 10, 2 ); + $response = parent::get_items( $request ); + remove_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10 ); + remove_filter( 'posts_join', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_join' ), 10 ); + remove_filter( 'posts_groupby', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_group_by' ), 10 ); + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = parent::get_item_schema(); + + $schema['properties']['name'] = array( + 'description' => __( 'Product parent name.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ); + $schema['properties']['type'] = array( + 'description' => __( 'Product type.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'variation', + 'enum' => array( 'variation' ), + 'context' => array( 'view', 'edit' ), + ); + $schema['properties']['parent_id'] = array( + 'description' => __( 'Product parent ID.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ); + + return $schema; + } + + /** + * Prepare a single variation output for response. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $response = parent::prepare_object_for_response( $object, $request ); + $data = $response->get_data(); + + $data['name'] = $object->get_name( $context ); + $data['type'] = $object->get_type(); + $data['parent_id'] = $object->get_parent_id( $context ); + + $response->set_data( $data ); + + return $response; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-products-controller.php b/src/RestApi/Version4/class-wc-admin-rest-products-controller.php new file mode 100644 index 00000000000..d19dec34741 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-products-controller.php @@ -0,0 +1,189 @@ + __( 'Limit result set to products that are low or out of stock.', 'woocommerce-admin' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + ); + $params['search'] = array( + 'description' => __( 'Search by similar product name or sku.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } + + + /** + * Add product name and sku filtering to the WC API. + * + * @param WP_REST_Request $request Request data. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + if ( ! empty( $request['search'] ) ) { + $args['search'] = trim( $request['search'] ); + unset( $args['s'] ); + } + if ( ! empty( $request['low_in_stock'] ) ) { + $args['low_in_stock'] = $request['low_in_stock']; + $args['post_type'] = array( 'product', 'product_variation' ); + } + + return $args; + } + + /** + * Get a collection of posts and add the post title filter option to WP_Query. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); + add_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10, 2 ); + add_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10, 2 ); + $response = parent::get_items( $request ); + remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10 ); + remove_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10 ); + remove_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10 ); + return $response; + } + + /** + * Add in conditional search filters for products. + * + * @param string $where Where clause used to search posts. + * @param object $wp_query WP_Query object. + * @return string + */ + public static function add_wp_query_filter( $where, $wp_query ) { + global $wpdb; + + $search = $wp_query->get( 'search' ); + if ( $search ) { + $search = $wpdb->esc_like( $search ); + $search = "'%" . $search . "%'"; + $where .= " AND ({$wpdb->posts}.post_title LIKE {$search}"; + $where .= wc_product_sku_enabled() ? ' OR ps_post_meta.meta_key = "_sku" AND ps_post_meta.meta_value LIKE ' . $search . ')' : ')'; + } + + if ( $wp_query->get( 'low_in_stock' ) ) { + $low_stock_amount = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) ); + $where .= " AND lis_postmeta2.meta_key = '_manage_stock' + AND lis_postmeta2.meta_value = 'yes' + AND lis_postmeta.meta_key = '_stock' + AND lis_postmeta.meta_value IS NOT NULL + AND lis_postmeta3.meta_key = '_low_stock_amount' + AND ( + lis_postmeta3.meta_value > '' + AND CAST(lis_postmeta.meta_value AS SIGNED) <= CAST(lis_postmeta3.meta_value AS SIGNED) + OR lis_postmeta3.meta_value <= '' + AND CAST(lis_postmeta.meta_value AS SIGNED) <= {$low_stock_amount} + )"; + } + + return $where; + } + + /** + * Join posts meta tables when product search or low stock query is present. + * + * @param string $join Join clause used to search posts. + * @param object $wp_query WP_Query object. + * @return string + */ + public static function add_wp_query_join( $join, $wp_query ) { + global $wpdb; + + $search = $wp_query->get( 'search' ); + if ( $search && wc_product_sku_enabled() ) { + $join .= " INNER JOIN {$wpdb->postmeta} AS ps_post_meta ON ps_post_meta.post_id = {$wpdb->posts}.ID"; + } + + if ( $wp_query->get( 'low_in_stock' ) ) { + $join .= " INNER JOIN {$wpdb->postmeta} AS lis_postmeta ON {$wpdb->posts}.ID = lis_postmeta.post_id + INNER JOIN {$wpdb->postmeta} AS lis_postmeta2 ON {$wpdb->posts}.ID = lis_postmeta2.post_id + INNER JOIN {$wpdb->postmeta} AS lis_postmeta3 ON {$wpdb->posts}.ID = lis_postmeta3.post_id"; + } + + return $join; + } + + /** + * Group by post ID to prevent duplicates. + * + * @param string $groupby Group by clause used to organize posts. + * @param object $wp_query WP_Query object. + * @return string + */ + public static function add_wp_query_group_by( $groupby, $wp_query ) { + global $wpdb; + + $search = $wp_query->get( 'search' ); + $low_in_stock = $wp_query->get( 'low_in_stock' ); + if ( empty( $groupby ) && ( $search || $low_in_stock ) ) { + $groupby = $wpdb->posts . '.ID'; + } + return $groupby; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-categories-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-categories-controller.php new file mode 100644 index 00000000000..ded3e478ffa --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-categories-controller.php @@ -0,0 +1,320 @@ +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-admin' ), 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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'items_sold' => array( + 'description' => __( 'Amount of items sold.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'net_revenue' => array( + 'description' => __( 'Gross revenue.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'orders_count' => array( + 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'products_count' => array( + 'description' => __( 'Amount of products.', 'woocommerce-admin' ), + '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-admin' ), + ), + ), + ), + ); + + 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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-controller.php new file mode 100644 index 00000000000..443e149c5c0 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-controller.php @@ -0,0 +1,303 @@ +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' ), + ) + ); + } + + /** + * Check whether a given request has permission to read reports. + * + * @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( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + + /** + * Get all reports. + * + * @param WP_REST_Request $request Request data. + * @return array|WP_Error + */ + public function get_items( $request ) { + $data = array(); + $reports = array( + array( + 'slug' => 'performance-indicators', + 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'revenue/stats', + 'description' => __( 'Stats about revenue.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'orders/stats', + 'description' => __( 'Stats about orders.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'products', + 'description' => __( 'Products detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'products/stats', + 'description' => __( 'Stats about products.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'categories', + 'description' => __( 'Product categories detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'categories/stats', + 'description' => __( 'Stats about product categories.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'coupons', + 'description' => __( 'Coupons detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'coupons/stats', + 'description' => __( 'Stats about coupons.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'taxes', + 'description' => __( 'Taxes detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'taxes/stats', + 'description' => __( 'Stats about taxes.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'downloads', + 'description' => __( 'Product downloads detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'downloads/files', + 'description' => __( 'Product download files detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'downloads/stats', + 'description' => __( 'Stats about product downloads.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'customers', + 'description' => __( 'Customers detailed reports.', 'woocommerce-admin' ), + ), + ); + + /** + * Filter the list of allowed reports, so that data can be loaded from third party extensions in addition to WooCommerce core. + * Array items should be in format of array( 'slug' => 'downloads/stats', 'description' => '', + * 'url' => '', and 'path' => '/wc-ext/v1/...'. + * + * @param array $endpoints The list of allowed reports.. + */ + $reports = apply_filters( 'woocommerce_admin_reports', $reports ); + + foreach ( $reports as $report ) { + if ( empty( $report['slug'] ) ) { + continue; + } + + if ( empty( $report['path'] ) ) { + $report['path'] = '/' . $this->namespace . '/reports/' . $report['slug']; + } + + // Allows a different admin page to be loaded here, + // or allows an empty url if no report exists for a set of performance indicators. + if ( ! isset( $report['url'] ) ) { + if ( '/stats' === substr( $report['slug'], -6 ) ) { + $url_slug = substr( $report['slug'], 0, -6 ); + } else { + $url_slug = $report['slug']; + } + + $report['url'] = '/analytics/' . $url_slug; + } + + $item = $this->prepare_item_for_response( (object) $report, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Get the order number for an order. If no filter is present for `woocommerce_order_number`, we can just return the ID. + * Returns the parent order number if the order is actually a refund. + * + * @param int $order_id Order ID. + * @return string + */ + public function get_order_number( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( 'shop_order_refund' === $order->get_type() ) { + $order = wc_get_order( $order->get_parent_id() ); + } + + if ( ! has_filter( 'woocommerce_order_number' ) ) { + return $order->get_id(); + } + + return $order->get_order_number(); + } + + /** + * 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 = array( + 'slug' => $report->slug, + 'description' => $report->description, + 'path' => $report->path, + ); + + $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( + array( + 'self' => array( + 'href' => rest_url( $report->path ), + ), + 'report' => array( + 'href' => $report->url, + ), + 'collection' => array( + 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), + ), + ) + ); + + /** + * 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', $response, $report, $request ); + } + + /** + * 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', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human-readable description of the resource.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'path' => array( + 'description' => __( 'API path.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + + /** + * Get order statuses without prefixes. + * + * @return array + */ + public function get_order_statuses() { + $order_statuses = array(); + + foreach ( array_keys( wc_get_order_statuses() ) as $status ) { + $order_statuses[] = str_replace( 'wc-', '', $status ); + } + + return $order_statuses; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-coupons-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-coupons-controller.php new file mode 100644 index 00000000000..8cc87aafcb4 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-coupons-controller.php @@ -0,0 +1,290 @@ +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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'amount' => array( + 'description' => __( 'Net discount amount.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'orders_count' => array( + 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + '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-admin' ), + ), + 'date_created' => array( + 'type' => 'date-time', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Coupon creation date.', 'woocommerce-admin' ), + ), + 'date_created_gmt' => array( + 'type' => 'date-time', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Coupon creation date in GMT.', 'woocommerce-admin' ), + ), + 'date_expires' => array( + 'type' => 'date-time', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Coupon expiration date.', 'woocommerce-admin' ), + ), + 'date_expires_gmt' => array( + 'type' => 'date-time', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Coupon expiration date in GMT.', 'woocommerce-admin' ), + ), + 'discount_type' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'enum' => array_keys( wc_get_coupon_types() ), + 'description' => __( 'Coupon discount type.', 'woocommerce-admin' ), + ), + ), + ), + ); + + 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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-coupons-stats-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-coupons-stats-controller.php new file mode 100644 index 00000000000..2b4e975b8c6 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-coupons-stats-controller.php @@ -0,0 +1,353 @@ +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-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'coupons_count' => array( + 'description' => __( 'Amount of coupons.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'orders_count' => array( + 'description' => __( 'Amount of discounted orders.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + ), + ); + + $segments = array( + 'segments' => array( + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'segment_id' => array( + 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $totals, + ), + 'intervals' => array( + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'interval' => array( + 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_start_gmt' => array( + 'description' => __( 'The date the report start, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end' => array( + 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end_gmt' => array( + 'description' => __( 'The date the report end, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'enum' => array( + 'product', + 'variation', + 'category', + 'coupon', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-customers-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-customers-controller.php new file mode 100644 index 00000000000..f29bde23d0b --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-customers-controller.php @@ -0,0 +1,517 @@ +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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'user_id' => array( + 'description' => __( 'User ID.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Name.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'username' => array( + 'description' => __( 'Username.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'country' => array( + 'description' => __( 'Country.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'city' => array( + 'description' => __( 'City.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_registered' => array( + 'description' => __( 'Date registered.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_registered_gmt' => array( + 'description' => __( 'Date registered GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_last_active' => array( + 'description' => __( 'Date last active.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_last_active_gmt' => array( + 'description' => __( 'Date last active GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'orders_count' => array( + 'description' => __( 'Order count.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_spend' => array( + 'description' => __( 'Total spend.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avg_order_value' => array( + 'description' => __( 'Avg order value.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['page'] = array( + 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['name_excludes'] = array( + 'description' => __( 'Limit response to objects excluding specfic names.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['username_includes'] = array( + 'description' => __( 'Limit response to objects with specfic usernames.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['username_excludes'] = array( + 'description' => __( 'Limit response to objects excluding specfic usernames.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['email_includes'] = array( + 'description' => __( 'Limit response to objects including emails.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['email_excludes'] = array( + 'description' => __( 'Limit response to objects excluding emails.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['country_includes'] = array( + 'description' => __( 'Limit response to objects with specfic countries.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['country_excludes'] = array( + 'description' => __( 'Limit response to objects excluding specfic countries.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), + ); + $params['registered_before'] = array( + 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['customers'] = array( + 'description' => __( 'Limit result to items with specified customer ids.', 'woocommerce-admin' ), + 'type' => 'array', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'type' => 'integer', + ), + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-customers-stats-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-customers-stats-controller.php new file mode 100644 index 00000000000..0012807e565 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-customers-stats-controller.php @@ -0,0 +1,364 @@ +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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avg_orders_count' => array( + 'description' => __( 'Average number of orders.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avg_total_spend' => array( + 'description' => __( 'Average total spend per customer.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'format' => 'currency', + ), + 'avg_avg_order_value' => array( + 'description' => __( 'Average AOV per customer.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['name_excludes'] = array( + 'description' => __( 'Limit response to objects excluding specfic names.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['username_includes'] = array( + 'description' => __( 'Limit response to objects with specfic usernames.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['username_excludes'] = array( + 'description' => __( 'Limit response to objects excluding specfic usernames.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['email_includes'] = array( + 'description' => __( 'Limit response to objects including emails.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['email_excludes'] = array( + 'description' => __( 'Limit response to objects excluding emails.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['country_includes'] = array( + 'description' => __( 'Limit response to objects with specfic countries.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['country_excludes'] = array( + 'description' => __( 'Limit response to objects excluding specfic countries.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), + ); + $params['registered_before'] = array( + 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['customers'] = array( + 'description' => __( 'Limit result to items with specified customer ids.', 'woocommerce-admin' ), + 'type' => 'array', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'type' => 'integer', + ), + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-controller.php new file mode 100644 index 00000000000..2b23d52b27c --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-controller.php @@ -0,0 +1,380 @@ +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-admin' ), + ), + 'product_id' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product ID.', 'woocommerce-admin' ), + ), + 'date' => array( + 'description' => __( "The date of the download, in the site's timezone.", 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_gmt' => array( + 'description' => __( 'The date of the download, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'download_id' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Download ID.', 'woocommerce-admin' ), + ), + 'file_name' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'File name.', 'woocommerce-admin' ), + ), + 'file_path' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'File URL.', 'woocommerce-admin' ), + ), + 'product_id' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product ID.', 'woocommerce-admin' ), + ), + 'order_id' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Order ID.', 'woocommerce-admin' ), + ), + 'order_number' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Order Number.', 'woocommerce-admin' ), + ), + 'user_id' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'User ID for the downloader.', 'woocommerce-admin' ), + ), + 'username' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'User name of the downloader.', 'woocommerce-admin' ), + ), + 'ip_address' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'IP address for the downloader.', 'woocommerce-admin' ), + ), + ), + ); + + 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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'array', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'type' => 'string', + ), + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-files-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-files-controller.php new file mode 100644 index 00000000000..d0f54fbdc66 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-files-controller.php @@ -0,0 +1,33 @@ +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-admin' ), + '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-admin' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $totals, + ), + 'intervals' => array( + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'interval' => array( + 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_start_gmt' => array( + 'description' => __( 'The date the report start, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end' => array( + 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end_gmt' => array( + 'description' => __( 'The date the report end, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'array', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'type' => 'string', + ), + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-import-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-import-controller.php new file mode 100644 index 00000000000..ad3c37af911 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-import-controller.php @@ -0,0 +1,315 @@ +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-admin' ), 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-admin' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['skip_existing'] = array( + 'description' => __( 'Skip importing existing order data.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'message' => array( + 'description' => __( 'Regenerate data message.', 'woocommerce-admin' ), + '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-admin' ), + ); + + $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/RestApi/Version4/class-wc-admin-rest-reports-orders-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-orders-controller.php new file mode 100644 index 00000000000..2e6f171709f --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-orders-controller.php @@ -0,0 +1,377 @@ +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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order_number' => array( + 'description' => __( 'Order Number.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( 'Date the order was created.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Order status.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_id' => array( + 'description' => __( 'Customer ID.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'num_items_sold' => array( + 'description' => __( 'Number of items sold.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'net_total' => array( + 'description' => __( 'Net total revenue.', 'woocommerce-admin' ), + 'type' => 'float', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_type' => array( + 'description' => __( 'Returning or new customer.', 'woocommerce-admin' ), + '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-admin' ), + ), + 'categories' => array( + 'type' => 'array', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Category IDs.', 'woocommerce-admin' ), + ), + ), + ), + ); + + 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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 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-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-orders-stats-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-orders-stats-controller.php new file mode 100644 index 00000000000..0e0f89243b9 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-orders-stats-controller.php @@ -0,0 +1,493 @@ +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-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'format' => 'currency', + ), + 'orders_count' => array( + 'description' => __( 'Amount of orders', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + ), + 'avg_order_value' => array( + 'description' => __( 'Average order value.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'avg_items_per_order' => array( + 'description' => __( 'Average items per order', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'num_items_sold' => array( + 'description' => __( 'Number of items sold', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'coupons' => array( + 'description' => __( 'Amount discounted by coupons.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'coupons_count' => array( + 'description' => __( 'Unique coupons count.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'num_returning_customers' => array( + 'description' => __( 'Number of orders done by returning customers', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'num_new_customers' => array( + 'description' => __( 'Number of orders done by new customers', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'products' => array( + 'description' => __( 'Number of distinct products sold.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ); + + $segments = array( + 'segments' => array( + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'segment_id' => array( + 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $totals, + ), + 'intervals' => array( + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'interval' => array( + 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_start_gmt' => array( + 'description' => __( 'The date the report start, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end' => array( + 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end_gmt' => array( + 'description' => __( 'The date the report end, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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/RestApi/Version4/class-wc-admin-rest-reports-performance-indicators-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-performance-indicators-controller.php new file mode 100644 index 00000000000..1e4cf18a06b --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-performance-indicators-controller.php @@ -0,0 +1,505 @@ +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-admin' ) ); + } + + 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-admin' ), 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-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'enum' => $allowed_stats, + ), + 'chart' => array( + 'description' => __( 'The specific chart this stat referrers to.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Human readable label for the stat.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'format' => array( + 'description' => __( 'Format of the stat.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ); + } 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-admin' ), + $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-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-products-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-products-controller.php new file mode 100644 index 00000000000..0e34901149d --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-products-controller.php @@ -0,0 +1,344 @@ + '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-admin' ), + ), + 'items_sold' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Number of items sold.', 'woocommerce-admin' ), + ), + 'net_revenue' => array( + 'type' => 'number', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Total net revenue of all items sold.', 'woocommerce-admin' ), + ), + 'orders_count' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Number of orders product appeared in.', 'woocommerce-admin' ), + ), + 'extended_info' => array( + 'name' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product name.', 'woocommerce-admin' ), + ), + 'price' => array( + 'type' => 'number', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product price.', 'woocommerce-admin' ), + ), + 'image' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product image.', 'woocommerce-admin' ), + ), + 'permalink' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product link.', 'woocommerce-admin' ), + ), + 'attributes' => array( + 'type' => 'array', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product attributes.', 'woocommerce-admin' ), + ), + 'stock_status' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product inventory status.', 'woocommerce-admin' ), + ), + 'stock_quantity' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product inventory quantity.', 'woocommerce-admin' ), + ), + 'low_stock_amount' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product inventory threshold for low stock.', 'woocommerce-admin' ), + ), + 'variations' => array( + 'type' => 'array', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product variations IDs.', 'woocommerce-admin' ), + ), + 'sku' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product SKU.', 'woocommerce-admin' ), + ), + ), + ), + ); + + 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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-products-stats-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-products-stats-controller.php new file mode 100644 index 00000000000..fd9fd4bd390 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-products-stats-controller.php @@ -0,0 +1,416 @@ + '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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + ), + 'net_revenue' => array( + 'description' => __( 'Net revenue.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'format' => 'currency', + ), + 'orders_count' => array( + 'description' => __( 'Number of orders.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ); + + $segments = array( + 'segments' => array( + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'segment_id' => array( + 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'segment_label' => array( + 'description' => __( 'Human readable segment label, either product or variation name.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'enum' => array( 'day', 'week', 'month', 'year' ), + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $totals, + ), + 'intervals' => array( + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'interval' => array( + 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_start_gmt' => array( + 'description' => __( 'The date the report start, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end' => array( + 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end_gmt' => array( + 'description' => __( 'The date the report end, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'enum' => array( + 'product', + 'category', + 'variation', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-revenue-stats-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-revenue-stats-controller.php new file mode 100644 index 00000000000..9d9c72c5b93 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-revenue-stats-controller.php @@ -0,0 +1,402 @@ +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-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'net_revenue' => array( + 'description' => __( 'Net revenue.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'coupons' => array( + 'description' => __( 'Amount discounted by coupons.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'coupons_count' => array( + 'description' => __( 'Unique coupons count.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'format' => 'currency', + ), + 'shipping' => array( + 'description' => __( 'Total of shipping.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'taxes' => array( + 'description' => __( 'Total of taxes.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'format' => 'currency', + ), + 'refunds' => array( + 'description' => __( 'Total of refunds.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'orders_count' => array( + 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'num_items_sold' => array( + 'description' => __( 'Items sold.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'products' => array( + 'description' => __( 'Products sold.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ); + + $segments = array( + 'segments' => array( + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'segment_id' => array( + 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $totals, + ), + 'intervals' => array( + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'interval' => array( + 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_start_gmt' => array( + 'description' => __( 'The date the report start, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end' => array( + 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end_gmt' => array( + 'description' => __( 'The date the report end, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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/RestApi/Version4/class-wc-admin-rest-reports-stock-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-stock-controller.php new file mode 100644 index 00000000000..1fc5eefbbb3 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-stock-controller.php @@ -0,0 +1,419 @@ + '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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'stock_status' => array( + 'description' => __( 'Stock status.', 'woocommerce-admin' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'manage_stock' => array( + 'description' => __( 'Manage stock.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'asc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'default' => 'all', + 'enum' => array_merge( array( 'all', 'lowstock' ), array_keys( wc_get_product_stock_status_options() ) ), + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-stock-stats-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-stock-stats-controller.php new file mode 100644 index 00000000000..c4782dd8e9d --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-stock-stats-controller.php @@ -0,0 +1,138 @@ +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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'lowstock' => array( + 'description' => __( 'Number of low stock products.', 'woocommerce-admin' ), + '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-admin' ), $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-admin' ), + '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/RestApi/Version4/class-wc-admin-rest-reports-taxes-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-taxes-controller.php new file mode 100644 index 00000000000..6729c9a3e89 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-taxes-controller.php @@ -0,0 +1,288 @@ +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-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Tax rate name.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_rate' => array( + 'description' => __( 'Tax rate.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'country' => array( + 'description' => __( 'Country.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'state' => array( + 'description' => __( 'State.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'priority' => array( + 'description' => __( 'Priority.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Total tax.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order_tax' => array( + 'description' => __( 'Order tax.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax' => array( + 'description' => __( 'Shipping tax.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'orders_count' => array( + 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'array', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'type' => 'string', + ), + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-taxes-stats-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-taxes-stats-controller.php new file mode 100644 index 00000000000..340f142a795 --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-taxes-stats-controller.php @@ -0,0 +1,391 @@ +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-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'order_tax' => array( + 'description' => __( 'Order tax.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'shipping_tax' => array( + 'description' => __( 'Shipping tax.', 'woocommerce-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + 'format' => 'currency', + ), + 'orders_count' => array( + 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_codes' => array( + 'description' => __( 'Amount of tax codes.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ); + + $segments = array( + 'segments' => array( + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'segment_id' => array( + 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $totals, + ), + 'intervals' => array( + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'interval' => array( + 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_start_gmt' => array( + 'description' => __( 'The date the report start, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end' => array( + 'description' => __( "The date the report end, in the site's timezone.", 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end_gmt' => array( + 'description' => __( 'The date the report end, as GMT.', 'woocommerce-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'string', + 'enum' => array( + 'tax_rate_id', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-variations-controller.php b/src/RestApi/Version4/class-wc-admin-rest-reports-variations-controller.php new file mode 100644 index 00000000000..a64e187e9da --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-reports-variations-controller.php @@ -0,0 +1,328 @@ + '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-admin' ), + ), + 'variation_id' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product ID.', 'woocommerce-admin' ), + ), + 'items_sold' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Number of items sold.', 'woocommerce-admin' ), + ), + 'net_revenue' => array( + 'type' => 'number', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Total net revenue of all items sold.', 'woocommerce-admin' ), + ), + 'orders_count' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Number of orders product appeared in.', 'woocommerce-admin' ), + ), + 'extended_info' => array( + 'name' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product name.', 'woocommerce-admin' ), + ), + 'price' => array( + 'type' => 'number', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product price.', 'woocommerce-admin' ), + ), + 'image' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product image.', 'woocommerce-admin' ), + ), + 'permalink' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product link.', 'woocommerce-admin' ), + ), + 'attributes' => array( + 'type' => 'array', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product attributes.', 'woocommerce-admin' ), + ), + 'stock_status' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product inventory status.', 'woocommerce-admin' ), + ), + 'stock_quantity' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product inventory quantity.', 'woocommerce-admin' ), + ), + 'low_stock_amount' => array( + 'type' => 'integer', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Product inventory threshold for low stock.', 'woocommerce-admin' ), + ), + ), + ), + ); + + 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-admin' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php b/src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php new file mode 100644 index 00000000000..bfa1a2fe6ec --- /dev/null +++ b/src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php @@ -0,0 +1,27 @@ + __( 'Search by similar tax code.', 'woocommerce-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['include'] = array( + 'description' => __( 'Limit result set to items that have the specified rate ID(s) assigned.', 'woocommerce-admin' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } + + /** + * Get all taxes and allow filtering by tax code. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + global $wpdb; + + $prepared_args = array(); + $prepared_args['order'] = $request['order']; + $prepared_args['number'] = $request['per_page']; + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + $orderby_possibles = array( + 'id' => 'tax_rate_id', + 'order' => 'tax_rate_order', + ); + $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; + $prepared_args['class'] = $request['class']; + $prepared_args['code'] = $request['code']; + $prepared_args['include'] = $request['include']; + + /** + * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. + * + * @param array $prepared_args Array of arguments for $wpdb->get_results(). + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request ); + + $query = " + SELECT * + FROM {$wpdb->prefix}woocommerce_tax_rates + WHERE 1 = 1 + "; + + // Filter by tax class. + if ( ! empty( $prepared_args['class'] ) ) { + $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; + $query .= " AND tax_rate_class = '$class'"; + } + + // Filter by tax code. + $tax_code_search = $prepared_args['code']; + if ( $tax_code_search ) { + $tax_code_search = $wpdb->esc_like( $tax_code_search ); + $tax_code_search = ' \'%' . $tax_code_search . '%\''; + $query .= ' AND CONCAT_WS( "-", NULLIF(tax_rate_country, ""), NULLIF(tax_rate_state, ""), NULLIF(tax_rate_name, ""), NULLIF(tax_rate_priority, "") ) LIKE ' . $tax_code_search; + } + + // Filter by included tax rate IDs. + $included_taxes = $prepared_args['include']; + if ( ! empty( $included_taxes ) ) { + $included_taxes = implode( ',', $prepared_args['include'] ); + $query .= " AND tax_rate_id IN ({$included_taxes})"; + } + + // Order tax rates. + $order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) ); + + // Pagination. + $pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] ); + + // Query taxes. + $results = $wpdb->get_results( $query . $order_by . $pagination ); // @codingStandardsIgnoreLine. + + $taxes = array(); + foreach ( $results as $tax ) { + $data = $this->prepare_item_for_response( $tax, $request ); + $taxes[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $taxes ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + // Query only for ids. + $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); // @codingStandardsIgnoreLine. + + // Calculate totals. + $total_taxes = (int) $wpdb->num_rows; + $response->header( 'X-WP-Total', (int) $total_taxes ); + $max_pages = ceil( $total_taxes / $per_page ); + $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; + } +} From 7ab7157725710430c5b531ef5b901a032d496675 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 11:48:40 +0100 Subject: [PATCH 014/440] v4 rejig/namespace --- .../Controllers/Coupons.php} | 59 ++++++++++++++++--- ...-rest-customer-downloads-v1-controller.php | 0 .../class-wc-rest-customers-v1-controller.php | 0 ...lass-wc-rest-order-notes-v1-controller.php | 0 ...ss-wc-rest-order-refunds-v1-controller.php | 0 .../class-wc-rest-orders-v1-controller.php | 0 ...-product-attribute-terms-v1-controller.php | 0 ...-rest-product-attributes-v1-controller.php | 0 ...-rest-product-categories-v1-controller.php | 0 ...-wc-rest-product-reviews-v1-controller.php | 0 ...product-shipping-classes-v1-controller.php | 0 ...ass-wc-rest-product-tags-v1-controller.php | 0 .../class-wc-rest-products-v1-controller.php | 0 ...ass-wc-rest-report-sales-v1-controller.php | 0 ...-rest-report-top-sellers-v1-controller.php | 0 .../class-wc-rest-reports-v1-controller.php | 0 ...lass-wc-rest-tax-classes-v1-controller.php | 0 .../class-wc-rest-taxes-v1-controller.php | 0 ...-rest-webhook-deliveries-v1-controller.php | 0 .../class-wc-rest-webhooks-v1-controller.php | 0 ...s-wc-admin-rest-admin-notes-controller.php | 0 ...class-wc-admin-rest-coupons-controller.php | 0 ...ass-wc-admin-rest-customers-controller.php | 0 .../class-wc-admin-rest-data-controller.php | 0 ...c-admin-rest-data-countries-controller.php | 0 ...dmin-rest-data-download-ips-controller.php | 0 ...-wc-admin-rest-leaderboards-controller.php | 0 ...dmin-rest-onboarding-levels-controller.php | 0 ...min-rest-onboarding-plugins-controller.php | 0 ...min-rest-onboarding-profile-controller.php | 0 .../class-wc-admin-rest-orders-controller.php | 0 ...min-rest-product-categories-controller.php | 0 ...-admin-rest-product-reviews-controller.php | 0 ...min-rest-product-variations-controller.php | 0 ...lass-wc-admin-rest-products-controller.php | 0 ...min-rest-reports-categories-controller.php | 0 ...class-wc-admin-rest-reports-controller.php | 0 ...-admin-rest-reports-coupons-controller.php | 0 ...-rest-reports-coupons-stats-controller.php | 0 ...dmin-rest-reports-customers-controller.php | 0 ...est-reports-customers-stats-controller.php | 0 ...dmin-rest-reports-downloads-controller.php | 0 ...est-reports-downloads-files-controller.php | 0 ...est-reports-downloads-stats-controller.php | 0 ...c-admin-rest-reports-import-controller.php | 0 ...c-admin-rest-reports-orders-controller.php | 0 ...n-rest-reports-orders-stats-controller.php | 0 ...orts-performance-indicators-controller.php | 0 ...admin-rest-reports-products-controller.php | 0 ...rest-reports-products-stats-controller.php | 0 ...-rest-reports-revenue-stats-controller.php | 0 ...wc-admin-rest-reports-stock-controller.php | 0 ...in-rest-reports-stock-stats-controller.php | 0 ...wc-admin-rest-reports-taxes-controller.php | 0 ...in-rest-reports-taxes-stats-controller.php | 0 ...min-rest-reports-variations-controller.php | 0 ...-admin-rest-setting-options-controller.php | 0 .../class-wc-admin-rest-taxes-controller.php | 0 58 files changed, 51 insertions(+), 8 deletions(-) rename src/RestApi/{AllYourBase/class-wc-rest-coupons-v1-controller.php => Version4/Controllers/Coupons.php} (94%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-customer-downloads-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-customers-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-order-notes-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-order-refunds-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-orders-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-product-attribute-terms-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-product-attributes-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-product-categories-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-product-reviews-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-product-shipping-classes-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-product-tags-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-products-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-report-sales-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-report-top-sellers-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-reports-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-tax-classes-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-taxes-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-webhook-deliveries-v1-controller.php (100%) rename src/RestApi/{AllYourBase => Version4}/class-wc-rest-webhooks-v1-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-admin-notes-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-coupons-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-customers-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-data-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-data-countries-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-data-download-ips-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-leaderboards-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-onboarding-levels-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-onboarding-plugins-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-onboarding-profile-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-orders-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-product-categories-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-product-reviews-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-product-variations-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-products-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-categories-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-coupons-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-coupons-stats-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-customers-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-customers-stats-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-downloads-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-downloads-files-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-downloads-stats-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-import-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-orders-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-orders-stats-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-performance-indicators-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-products-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-products-stats-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-revenue-stats-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-stock-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-stock-stats-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-taxes-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-taxes-stats-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-reports-variations-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-setting-options-controller.php (100%) rename src/RestApi/{Version4 => Version4_temp}/class-wc-admin-rest-taxes-controller.php (100%) diff --git a/src/RestApi/AllYourBase/class-wc-rest-coupons-v1-controller.php b/src/RestApi/Version4/Controllers/Coupons.php similarity index 94% rename from src/RestApi/AllYourBase/class-wc-rest-coupons-v1-controller.php rename to src/RestApi/Version4/Controllers/Coupons.php index 832bbe1993c..c71704ab234 100644 --- a/src/RestApi/AllYourBase/class-wc-rest-coupons-v1-controller.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -7,24 +7,23 @@ * @package WooCommerce/RestApi */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Posts_Controller; /** * REST API Coupons controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Posts_Controller */ -class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { +class Coupons extends WC_REST_Posts_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -252,6 +251,11 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { $args['post__in'] = array( $id ); } + if ( ! empty( $request['search'] ) ) { + $args['search'] = $request['search']; + $args['s'] = false; + } + // Get only ids. $args['fields'] = 'ids'; @@ -542,6 +546,12 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'validate_callback' => 'rest_validate_request_arg', ); + $params['search'] = array( + 'description' => __( 'Limit results to coupons with codes matching a given string.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; } @@ -798,4 +808,37 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } + + /** + * Get a collection of posts and add the code search option to WP_Query. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10, 2 ); + $response = parent::get_items( $request ); + remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10 ); + return $response; + } + + /** + * Add code searching to the WP Query + * + * @param string $where Where clause used to search posts. + * @param object $wp_query WP_Query object. + * @return string + */ + public static function add_wp_query_search_code_filter( $where, $wp_query ) { + global $wpdb; + + $search = $wp_query->get( 'search' ); + if ( $search ) { + $search = $wpdb->esc_like( $search ); + $search = "'%" . $search . "%'"; + $where .= ' AND ' . $wpdb->posts . '.post_title LIKE ' . $search; + } + + return $where; + } } diff --git a/src/RestApi/AllYourBase/class-wc-rest-customer-downloads-v1-controller.php b/src/RestApi/Version4/class-wc-rest-customer-downloads-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-customer-downloads-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-customer-downloads-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-customers-v1-controller.php b/src/RestApi/Version4/class-wc-rest-customers-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-customers-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-customers-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-order-notes-v1-controller.php b/src/RestApi/Version4/class-wc-rest-order-notes-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-order-notes-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-order-notes-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-order-refunds-v1-controller.php b/src/RestApi/Version4/class-wc-rest-order-refunds-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-order-refunds-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-order-refunds-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-orders-v1-controller.php b/src/RestApi/Version4/class-wc-rest-orders-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-orders-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-orders-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-attribute-terms-v1-controller.php b/src/RestApi/Version4/class-wc-rest-product-attribute-terms-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-product-attribute-terms-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-product-attribute-terms-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-attributes-v1-controller.php b/src/RestApi/Version4/class-wc-rest-product-attributes-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-product-attributes-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-product-attributes-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-categories-v1-controller.php b/src/RestApi/Version4/class-wc-rest-product-categories-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-product-categories-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-product-categories-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-reviews-v1-controller.php b/src/RestApi/Version4/class-wc-rest-product-reviews-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-product-reviews-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-product-reviews-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-shipping-classes-v1-controller.php b/src/RestApi/Version4/class-wc-rest-product-shipping-classes-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-product-shipping-classes-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-product-shipping-classes-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-product-tags-v1-controller.php b/src/RestApi/Version4/class-wc-rest-product-tags-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-product-tags-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-product-tags-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-products-v1-controller.php b/src/RestApi/Version4/class-wc-rest-products-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-products-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-products-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-report-sales-v1-controller.php b/src/RestApi/Version4/class-wc-rest-report-sales-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-report-sales-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-report-sales-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-report-top-sellers-v1-controller.php b/src/RestApi/Version4/class-wc-rest-report-top-sellers-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-report-top-sellers-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-report-top-sellers-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-reports-v1-controller.php b/src/RestApi/Version4/class-wc-rest-reports-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-reports-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-reports-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-tax-classes-v1-controller.php b/src/RestApi/Version4/class-wc-rest-tax-classes-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-tax-classes-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-tax-classes-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-taxes-v1-controller.php b/src/RestApi/Version4/class-wc-rest-taxes-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-taxes-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-taxes-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-webhook-deliveries-v1-controller.php b/src/RestApi/Version4/class-wc-rest-webhook-deliveries-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-webhook-deliveries-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-webhook-deliveries-v1-controller.php diff --git a/src/RestApi/AllYourBase/class-wc-rest-webhooks-v1-controller.php b/src/RestApi/Version4/class-wc-rest-webhooks-v1-controller.php similarity index 100% rename from src/RestApi/AllYourBase/class-wc-rest-webhooks-v1-controller.php rename to src/RestApi/Version4/class-wc-rest-webhooks-v1-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-admin-notes-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-admin-notes-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-admin-notes-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-admin-notes-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-coupons-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-coupons-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-coupons-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-coupons-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-customers-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-customers-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-customers-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-customers-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-data-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-data-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-data-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-data-countries-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-data-countries-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-data-download-ips-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-data-download-ips-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-leaderboards-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-leaderboards-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-levels-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-levels-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-plugins-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-plugins-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-profile-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-profile-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-orders-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-orders-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-orders-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-orders-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-product-categories-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-product-categories-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-product-categories-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-product-categories-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-product-reviews-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-product-reviews-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-product-reviews-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-product-reviews-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-product-variations-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-product-variations-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-products-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-products-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-products-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-products-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-categories-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-categories-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-categories-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-categories-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-coupons-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-coupons-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-coupons-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-coupons-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-coupons-stats-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-coupons-stats-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-coupons-stats-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-coupons-stats-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-customers-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-customers-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-customers-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-customers-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-customers-stats-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-customers-stats-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-customers-stats-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-customers-stats-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-downloads-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-files-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-files-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-downloads-files-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-files-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-downloads-stats-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-stats-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-downloads-stats-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-stats-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-import-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-import-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-import-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-import-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-orders-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-orders-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-orders-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-orders-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-orders-stats-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-orders-stats-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-orders-stats-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-orders-stats-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-performance-indicators-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-performance-indicators-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-performance-indicators-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-performance-indicators-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-products-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-products-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-products-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-products-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-products-stats-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-products-stats-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-products-stats-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-products-stats-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-revenue-stats-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-revenue-stats-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-revenue-stats-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-revenue-stats-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-stock-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-stock-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-stock-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-stock-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-stock-stats-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-stock-stats-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-stock-stats-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-stock-stats-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-taxes-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-taxes-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-taxes-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-taxes-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-taxes-stats-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-taxes-stats-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-taxes-stats-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-taxes-stats-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-reports-variations-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-reports-variations-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-reports-variations-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-reports-variations-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-setting-options-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-setting-options-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-taxes-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-taxes-controller.php similarity index 100% rename from src/RestApi/Version4/class-wc-admin-rest-taxes-controller.php rename to src/RestApi/Version4_temp/class-wc-admin-rest-taxes-controller.php From a01fcb881d2caa4cf421c3ac4717a53edace1d4e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 12:08:49 +0100 Subject: [PATCH 015/440] Customers --- phpcs.xml | 3 +- .../Customers.php} | 436 ++++++++++-------- 2 files changed, 246 insertions(+), 193 deletions(-) rename src/RestApi/Version4/{class-wc-rest-customers-v1-controller.php => Controllers/Customers.php} (74%) diff --git a/phpcs.xml b/phpcs.xml index bec59ea7d5d..9df96537e9c 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -26,7 +26,7 @@ - tests/* + * @@ -35,5 +35,6 @@ i18n/ + * diff --git a/src/RestApi/Version4/class-wc-rest-customers-v1-controller.php b/src/RestApi/Version4/Controllers/Customers.php similarity index 74% rename from src/RestApi/Version4/class-wc-rest-customers-v1-controller.php rename to src/RestApi/Version4/Controllers/Customers.php index 04b12cd4e47..762fd18e72d 100644 --- a/src/RestApi/Version4/class-wc-rest-customers-v1-controller.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -4,30 +4,26 @@ * * Handles requests to the /customers endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Controller; /** - * REST API Customers controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller + * REST API Coupons controller class. */ -class WC_REST_Customers_V1_Controller extends WC_REST_Controller { +class Customers extends WC_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -40,88 +36,103 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { * Register the routes for customers. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'email' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'New user email address.', 'woocommerce' ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( + 'email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'New user email address.', 'woocommerce' ), + ), + 'username' => array( + 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), + 'description' => __( 'New user username.', 'woocommerce' ), + 'type' => 'string', + ), + 'password' => array( + 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), + 'description' => __( 'New user password.', 'woocommerce' ), + 'type' => 'string', + ), + ) ), - 'username' => array( - 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), - 'description' => __( 'New user username.', 'woocommerce' ), - 'type' => 'string', - ), - 'password' => array( - 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), - 'description' => __( 'New user password.', 'woocommerce' ), - 'type' => 'string', - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), - ), - 'reassign' => array( - 'default' => 0, + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', - 'description' => __( 'ID to reassign posts to.', 'woocommerce' ), ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + 'reassign' => array( + 'default' => 0, + 'type' => 'integer', + 'description' => __( 'ID to reassign posts to.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); } /** @@ -218,6 +229,45 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { return true; } + /** + * Get formatted item data. + * + * @param WC_Data $object WC_Data instance. + * + * @since 3.0.0 + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + // Date created is stored UTC, date modified is stored WP local time. + $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => $data['email'], + 'first_name' => $data['first_name'], + 'last_name' => $data['last_name'], + 'role' => $data['role'], + 'username' => $data['username'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'is_paying_customer' => $data['is_paying_customer'], + 'avatar_url' => $object->get_avatar_url(), + 'meta_data' => $data['meta_data'], + ); + } + /** * Get all customers. * @@ -318,6 +368,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { /** * Create a single customer. * + * @throws WC_REST_Exception On invalid params. * @param WP_REST_Request $request Full details about the request. * @return WP_Error|WP_REST_Response */ @@ -334,7 +385,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $request['password'] = ! empty( $request['password'] ) ? $request['password'] : ''; // Create customer. - $customer = new WC_Customer; + $customer = new WC_Customer(); $customer->set_username( $request['username'] ); $customer->set_password( $request['password'] ); $customer->set_email( $request['email'] ); @@ -392,6 +443,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { /** * Update a single user. * + * @throws WC_REST_Exception On invalid params. * @param WP_REST_Request $request Full details about the request. * @return WP_Error|WP_REST_Response */ @@ -510,40 +562,13 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { /** * Prepare a single customer output for response. * - * @param WP_User $user_data User object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @param WP_User $user_data User object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $user_data, $request ) { - $customer = new WC_Customer( $user_data->ID ); - $_data = $customer->get_data(); - $last_order = wc_get_customer_last_order( $customer->get_id() ); - $format_date = array( 'date_created', 'date_modified' ); - - // Format date values. - foreach ( $format_date as $key ) { - $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; // v1 API used UTC. - } - - $data = array( - 'id' => $_data['id'], - 'date_created' => $_data['date_created'], - 'date_modified' => $_data['date_modified'], - 'email' => $_data['email'], - 'first_name' => $_data['first_name'], - 'last_name' => $_data['last_name'], - 'username' => $_data['username'], - 'last_order' => array( - 'id' => is_object( $last_order ) ? $last_order->get_id() : null, - 'date' => is_object( $last_order ) ? wc_rest_prepare_date_response( $last_order->get_date_created() ) : null, // v1 API used UTC. - ), - 'orders_count' => $customer->get_order_count(), - 'total_spent' => $customer->get_total_spent(), - 'avatar_url' => $customer->get_avatar_url(), - 'billing' => $_data['billing'], - 'shipping' => $_data['shipping'], - ); - + $customer = new WC_Customer( $user_data->ID ); + $data = $this->get_formatted_item_data( $customer ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); @@ -563,8 +588,8 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { /** * Update customer meta fields. * - * @param WC_Customer $customer - * @param WP_REST_Request $request + * @param WC_Customer $customer Customer being updated. + * @param WP_REST_Request $request Request params. */ protected function update_customer_meta_fields( $customer, $request ) { $schema = $this->get_item_schema(); @@ -596,6 +621,15 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { } } } + + // Meta data. + if ( isset( $request['meta_data'] ) ) { + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $customer->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } } /** @@ -628,31 +662,43 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'title' => 'customer', 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_created' => array( + 'date_created' => array( + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_modified' => array( + 'date_modified' => array( + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'email' => array( + 'email' => array( 'description' => __( 'The email address for the customer.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), - 'first_name' => array( + 'first_name' => array( 'description' => __( 'Customer first name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -660,7 +706,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'sanitize_text_field', ), ), - 'last_name' => array( + 'last_name' => array( 'description' => __( 'Customer last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -668,7 +714,13 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'sanitize_text_field', ), ), - 'username' => array( + 'role' => array( + 'description' => __( 'Customer role.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'username' => array( 'description' => __( 'Customer login name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -676,164 +728,164 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'sanitize_user', ), ), - 'password' => array( + 'password' => array( 'description' => __( 'Customer password.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'edit' ), ), - 'last_order' => array( - 'description' => __( 'Last order data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => array( - 'id' => array( - 'description' => __( 'Last order ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date' => array( - 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - 'orders_count' => array( - 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_spent' => array( - 'description' => __( 'Total amount spent.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'billing' => array( + 'billing' => array( 'description' => __( 'List of billing address data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), - 'properties' => array( + 'properties' => array( 'first_name' => array( 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'last_name' => array( + 'last_name' => array( 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'company' => array( + 'company' => array( 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce' ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce' ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'city' => array( + 'city' => array( 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'state' => array( + 'state' => array( 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'postcode' => array( + 'postcode' => array( 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'country' => array( + 'country' => array( 'description' => __( 'ISO code of the country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'email' => array( + 'email' => array( 'description' => __( 'Email address.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), - 'phone' => array( + 'phone' => array( 'description' => __( 'Phone number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), - 'shipping' => array( + 'shipping' => array( 'description' => __( 'List of shipping address data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), - 'properties' => array( + 'properties' => array( 'first_name' => array( 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'last_name' => array( + 'last_name' => array( 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'company' => array( + 'company' => array( 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce' ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce' ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'city' => array( + 'city' => array( 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'state' => array( + 'state' => array( 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'postcode' => array( + 'postcode' => array( 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'country' => array( + 'country' => array( 'description' => __( 'ISO code of the country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), + 'is_paying_customer' => array( + 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), + 'type' => 'bool', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avatar_url' => array( + 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), ), ); From 2b83abe5402941c025c60b2b40934977711092ca Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 12:24:33 +0100 Subject: [PATCH 016/440] Orders --- .../Orders.php} | 1576 +++++++++-------- 1 file changed, 844 insertions(+), 732 deletions(-) rename src/RestApi/Version4/{class-wc-rest-orders-v1-controller.php => Controllers/Orders.php} (53%) diff --git a/src/RestApi/Version4/class-wc-rest-orders-v1-controller.php b/src/RestApi/Version4/Controllers/Orders.php similarity index 53% rename from src/RestApi/Version4/class-wc-rest-orders-v1-controller.php rename to src/RestApi/Version4/Controllers/Orders.php index 8ee59793536..21504eb461c 100644 --- a/src/RestApi/Version4/class-wc-rest-orders-v1-controller.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -4,30 +4,27 @@ * * Handles requests to the /orders endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_CRUD_Controller; /** - * REST API Orders controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Posts_Controller + * REST API Coupons controller class. */ -class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { +class Orders extends WC_REST_CRUD_Controller { + /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -44,431 +41,414 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { protected $post_type = 'shop_order'; /** - * Initialize orders actions. + * If object is hierarchical. + * + * @var bool */ - public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 ); - } + protected $hierarchical = true; + + /** + * Stores the request. + * + * @var array + */ + protected $request = array(); /** * Register the routes for orders. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. Return false if object is not of required type. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data|bool + */ + protected function get_object( $id ) { + $order = wc_get_order( $id ); + // In case id is a refund's id (or it's not an order at all), don't expose it via /orders/ path. + if ( ! $order || 'shop_order_refund' === $order->get_type() ) { + return false; + } + + return $order; + } + + /** + * Expands an order item to get its data. + * + * @param WC_Order_item $item Order item data. + * @return array + */ + protected function get_order_item_data( $item ) { + $data = $item->get_data(); + $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + if ( isset( $data[ $key ] ) ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + } + + // Add SKU and PRICE to products. + if ( is_callable( array( $item, 'get_product' ) ) ) { + $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; + $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; + } + + // Format taxes. + if ( ! empty( $data['taxes']['total'] ) ) { + $taxes = array(); + + foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { + $taxes[] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', + ); + } + $data['taxes'] = $taxes; + } elseif ( isset( $data['taxes'] ) ) { + $data['taxes'] = array(); + } + + // Remove names for coupons, taxes and shipping. + if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { + unset( $data['name'] ); + } + + // Remove props we don't want to expose. + unset( $data['order_id'] ); + unset( $data['type'] ); + + return $data; + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + $format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' ); + $format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' ); + $format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format the order status. + $data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status']; + + // Format line items. + foreach ( $format_line_items as $key ) { + $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); + } + + // Refunds. + $data['refunds'] = array(); + foreach ( $object->get_refunds() as $refund ) { + $data['refunds'][] = array( + 'id' => $refund->get_id(), + 'reason' => $refund->get_reason() ? $refund->get_reason() : '', + 'total' => '-' . wc_format_decimal( $refund->get_amount(), $this->request['dp'] ), + ); + } + + return array( + 'id' => $object->get_id(), + 'parent_id' => $data['parent_id'], + 'number' => $data['number'], + 'order_key' => $data['order_key'], + 'created_via' => $data['created_via'], + 'version' => $data['version'], + 'status' => $data['status'], + 'currency' => $data['currency'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_total' => $data['discount_total'], + 'discount_tax' => $data['discount_tax'], + 'shipping_total' => $data['shipping_total'], + 'shipping_tax' => $data['shipping_tax'], + 'cart_tax' => $data['cart_tax'], + 'total' => $data['total'], + 'total_tax' => $data['total_tax'], + 'prices_include_tax' => $data['prices_include_tax'], + 'customer_id' => $data['customer_id'], + 'customer_ip_address' => $data['customer_ip_address'], + 'customer_user_agent' => $data['customer_user_agent'], + 'customer_note' => $data['customer_note'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'payment_method' => $data['payment_method'], + 'payment_method_title' => $data['payment_method_title'], + 'transaction_id' => $data['transaction_id'], + 'date_paid' => $data['date_paid'], + 'date_paid_gmt' => $data['date_paid_gmt'], + 'date_completed' => $data['date_completed'], + 'date_completed_gmt' => $data['date_completed_gmt'], + 'cart_hash' => $data['cart_hash'], + 'meta_data' => $data['meta_data'], + 'line_items' => $data['line_items'], + 'tax_lines' => $data['tax_lines'], + 'shipping_lines' => $data['shipping_lines'], + 'fee_lines' => $data['fee_lines'], + 'coupon_lines' => $data['coupon_lines'], + 'refunds' => $data['refunds'], + ); } /** * Prepare a single order output for response. * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $data + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response */ - public function prepare_item_for_response( $post, $request ) { - $order = wc_get_order( $post ); - $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); - - $data = array( - 'id' => $order->get_id(), - 'parent_id' => $order->get_parent_id(), - 'status' => $order->get_status(), - 'order_key' => $order->get_order_key(), - 'number' => $order->get_order_number(), - 'currency' => $order->get_currency(), - 'version' => $order->get_version(), - 'prices_include_tax' => $order->get_prices_include_tax(), - 'date_created' => wc_rest_prepare_date_response( $order->get_date_created() ), // v1 API used UTC. - 'date_modified' => wc_rest_prepare_date_response( $order->get_date_modified() ), // v1 API used UTC. - 'customer_id' => $order->get_customer_id(), - 'discount_total' => wc_format_decimal( $order->get_total_discount(), $dp ), - 'discount_tax' => wc_format_decimal( $order->get_discount_tax(), $dp ), - 'shipping_total' => wc_format_decimal( $order->get_shipping_total(), $dp ), - 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), $dp ), - 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), $dp ), - 'total' => wc_format_decimal( $order->get_total(), $dp ), - 'total_tax' => wc_format_decimal( $order->get_total_tax(), $dp ), - 'billing' => array(), - 'shipping' => array(), - 'payment_method' => $order->get_payment_method(), - 'payment_method_title' => $order->get_payment_method_title(), - 'transaction_id' => $order->get_transaction_id(), - 'customer_ip_address' => $order->get_customer_ip_address(), - 'customer_user_agent' => $order->get_customer_user_agent(), - 'created_via' => $order->get_created_via(), - 'customer_note' => $order->get_customer_note(), - 'date_completed' => wc_rest_prepare_date_response( $order->get_date_completed(), false ), // v1 API used local time. - 'date_paid' => wc_rest_prepare_date_response( $order->get_date_paid(), false ), // v1 API used local time. - 'cart_hash' => $order->get_cart_hash(), - 'line_items' => array(), - 'tax_lines' => array(), - 'shipping_lines' => array(), - 'fee_lines' => array(), - 'coupon_lines' => array(), - 'refunds' => array(), - ); - - // Add addresses. - $data['billing'] = $order->get_address( 'billing' ); - $data['shipping'] = $order->get_address( 'shipping' ); - - // Add line items. - foreach ( $order->get_items() as $item_id => $item ) { - $product = $order->get_product_from_item( $item ); - $product_id = 0; - $variation_id = 0; - $product_sku = null; - - // Check if the product exists. - if ( is_object( $product ) ) { - $product_id = $item->get_product_id(); - $variation_id = $item->get_variation_id(); - $product_sku = $product->get_sku(); - } - - $item_meta = array(); - - $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; - - foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { - $item_meta[] = array( - 'key' => $formatted_meta->key, - 'label' => $formatted_meta->display_key, - 'value' => wc_clean( $formatted_meta->display_value ), - ); - } - - $line_item = array( - 'id' => $item_id, - 'name' => $item['name'], - 'sku' => $product_sku, - 'product_id' => (int) $product_id, - 'variation_id' => (int) $variation_id, - 'quantity' => wc_stock_amount( $item['qty'] ), - 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', - 'price' => wc_format_decimal( $order->get_item_total( $item, false, false ), $dp ), - 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item, false, false ), $dp ), - 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), - 'total' => wc_format_decimal( $order->get_line_total( $item, false, false ), $dp ), - 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), - 'taxes' => array(), - 'meta' => $item_meta, - ); - - $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); - if ( isset( $item_line_taxes['total'] ) ) { - $line_tax = array(); - - foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { - $line_tax[ $tax_rate_id ] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => '', - ); - } - - foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { - $line_tax[ $tax_rate_id ]['subtotal'] = $tax; - } - - $line_item['taxes'] = array_values( $line_tax ); - } - - $data['line_items'][] = $line_item; - } - - // Add taxes. - foreach ( $order->get_items( 'tax' ) as $key => $tax ) { - $tax_line = array( - 'id' => $key, - 'rate_code' => $tax['name'], - 'rate_id' => $tax['rate_id'], - 'label' => isset( $tax['label'] ) ? $tax['label'] : $tax['name'], - 'compound' => (bool) $tax['compound'], - 'tax_total' => wc_format_decimal( $tax['tax_amount'], $dp ), - 'shipping_tax_total' => wc_format_decimal( $tax['shipping_tax_amount'], $dp ), - ); - - $data['tax_lines'][] = $tax_line; - } - - // Add shipping. - foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { - $shipping_line = array( - 'id' => $shipping_item_id, - 'method_title' => $shipping_item['name'], - 'method_id' => $shipping_item['method_id'], - 'total' => wc_format_decimal( $shipping_item['cost'], $dp ), - 'total_tax' => wc_format_decimal( '', $dp ), - 'taxes' => array(), - ); - - $shipping_taxes = $shipping_item->get_taxes(); - - if ( ! empty( $shipping_taxes['total'] ) ) { - $shipping_line['total_tax'] = wc_format_decimal( array_sum( $shipping_taxes['total'] ), $dp ); - - foreach ( $shipping_taxes['total'] as $tax_rate_id => $tax ) { - $shipping_line['taxes'][] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - ); - } - } - - $data['shipping_lines'][] = $shipping_line; - } - - // Add fees. - foreach ( $order->get_fees() as $fee_item_id => $fee_item ) { - $fee_line = array( - 'id' => $fee_item_id, - 'name' => $fee_item['name'], - 'tax_class' => ! empty( $fee_item['tax_class'] ) ? $fee_item['tax_class'] : '', - 'tax_status' => 'taxable', - 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), $dp ), - 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), $dp ), - 'taxes' => array(), - ); - - $fee_line_taxes = maybe_unserialize( $fee_item['line_tax_data'] ); - if ( isset( $fee_line_taxes['total'] ) ) { - $fee_tax = array(); - - foreach ( $fee_line_taxes['total'] as $tax_rate_id => $tax ) { - $fee_tax[ $tax_rate_id ] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => '', - ); - } - - if ( isset( $fee_line_taxes['subtotal'] ) ) { - foreach ( $fee_line_taxes['subtotal'] as $tax_rate_id => $tax ) { - $fee_tax[ $tax_rate_id ]['subtotal'] = $tax; - } - } - - $fee_line['taxes'] = array_values( $fee_tax ); - } - - $data['fee_lines'][] = $fee_line; - } - - // Add coupons. - foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) { - $coupon_line = array( - 'id' => $coupon_item_id, - 'code' => $coupon_item['name'], - 'discount' => wc_format_decimal( $coupon_item['discount_amount'], $dp ), - 'discount_tax' => wc_format_decimal( $coupon_item['discount_amount_tax'], $dp ), - ); - - $data['coupon_lines'][] = $coupon_line; - } - - // Add refunds. - foreach ( $order->get_refunds() as $refund ) { - $data['refunds'][] = array( - 'id' => $refund->get_id(), - 'refund' => $refund->get_reason() ? $refund->get_reason() : '', - 'total' => '-' . wc_format_decimal( $refund->get_amount(), $dp ), - ); - } - - $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( $order, $request ) ); + public function prepare_object_for_response( $object, $request ) { + $this->request = $request; + $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); + $data = $this->get_formatted_item_data( $object ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); /** * Filter the data for a response. * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. * - * @param WP_REST_Response $response The response object. - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } /** * Prepare links for the request. * - * @param WC_Order $order Order object. + * @param WC_Data $object Object data. * @param WP_REST_Request $request Request object. - * @return array Links for the given order. + * @return array Links for the given post. */ - protected function prepare_links( $order, $request ) { + protected function prepare_links( $object, $request ) { $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $order->get_id() ) ), + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), ), ); - if ( 0 !== (int) $order->get_user_id() ) { + + if ( 0 !== (int) $object->get_customer_id() ) { $links['customer'] = array( - 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $order->get_user_id() ) ), + 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object->get_customer_id() ) ), ); } - if ( 0 !== (int) $order->get_parent_id() ) { + + if ( 0 !== (int) $object->get_parent_id() ) { $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order->get_parent_id() ) ), + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), ); } + return $links; } /** - * Query args. + * Prepare objects query. * - * @param array $args - * @param WP_REST_Request $request + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. * @return array */ - public function query_args( $args, $request ) { + protected function prepare_objects_query( $request ) { global $wpdb; - // Set post_status. - if ( 'any' !== $request['status'] ) { - $args['post_status'] = 'wc-' . $request['status']; - } else { - $args['post_status'] = 'any'; - } + // This is needed to get around an array to string notice in WC_REST_Orders_V2_Controller::prepare_objects_query. + $statuses = $request['status']; + unset( $request['status'] ); + $args = parent::prepare_objects_query( $request ); - if ( isset( $request['customer'] ) ) { - if ( ! empty( $args['meta_query'] ) ) { - $args['meta_query'] = array(); + $args['post_status'] = array(); + foreach ( $statuses as $status ) { + if ( in_array( $status, $this->get_order_statuses(), true ) ) { + $args['post_status'][] = 'wc-' . $status; + } elseif ( 'any' === $status ) { + // Set status to "any" and short-circuit out. + $args['post_status'] = 'any'; + break; + } else { + $args['post_status'][] = $status; } - - $args['meta_query'][] = array( - 'key' => '_customer_user', - 'value' => $request['customer'], - 'type' => 'NUMERIC', - ); } - // Search by product. - if ( ! empty( $request['product'] ) ) { - $order_ids = $wpdb->get_col( $wpdb->prepare( " - SELECT order_id - FROM {$wpdb->prefix}woocommerce_order_items - WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) - AND order_item_type = 'line_item' - ", $request['product'] ) ); + // Put the statuses back for further processing (next/prev links, etc). + $request['status'] = $statuses; + + // Search by partial order number. + if ( ! empty( $request['number'] ) ) { + $partial_number = trim( $request['number'] ); + $limit = intval( $args['posts_per_page'] ); + $order_ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT ID + FROM {$wpdb->prefix}posts + WHERE post_type = 'shop_order' + AND ID LIKE %s + LIMIT %d", + $wpdb->esc_like( absint( $partial_number ) ) . '%', + $limit + ) + ); // Force WP_Query return empty if don't found any order. - $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); - + $order_ids = empty( $order_ids ) ? array( 0 ) : $order_ids; $args['post__in'] = $order_ids; } - // Search. - if ( ! empty( $args['s'] ) ) { - $order_ids = wc_order_search( $args['s'] ); - - if ( ! empty( $order_ids ) ) { - unset( $args['s'] ); - $args['post__in'] = array_merge( $order_ids, array( 0 ) ); - } - } - return $args; } /** - * Prepare a single order for create. + * Only return writable props from schema. * - * @param WP_REST_Request $request Request object. - * @return WP_Error|WC_Order $data Object. + * @param array $schema Schema. + * @return bool */ - protected function prepare_item_for_database( $request ) { + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + + /** + * Prepare a single order for create or update. + * + * @throws WC_REST_Exception When fails to set any item. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; $order = new WC_Order( $id ); $schema = $this->get_item_schema(); $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - // Handle all writable props + // Handle all writable props. foreach ( $data_keys as $key ) { $value = $request[ $key ]; if ( ! is_null( $value ) ) { switch ( $key ) { - case 'billing' : - case 'shipping' : + case 'coupon_lines': + case 'status': + // Change should be done later so transitions have new data. + break; + case 'billing': + case 'shipping': $this->update_address( $order, $value, $key ); break; - case 'line_items' : - case 'shipping_lines' : - case 'fee_lines' : - case 'coupon_lines' : + case 'line_items': + case 'shipping_lines': + case 'fee_lines': if ( is_array( $value ) ) { foreach ( $value as $item ) { if ( is_array( $item ) ) { @@ -481,7 +461,14 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } } break; - default : + case 'meta_data': + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + default: if ( is_callable( array( $order, "set_{$key}" ) ) ) { $order->{"set_{$key}"}( $value ); } @@ -491,95 +478,79 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } /** - * Filter the data for the insert. + * Filters an object before it is inserted via the REST API. * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. * - * @param WC_Order $order The order object. - * @param WP_REST_Request $request Request object. + * @param WC_Data $order Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $order, $request ); + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); } /** - * Create base WC Order object. - * @deprecated 3.0.0 - * @param array $data - * @return WC_Order - */ - protected function create_base_order( $data ) { - return wc_create_order( $data ); - } - - /** - * Only return writable props from schema. - * @param array $schema - * @return bool - */ - protected function filter_writable_props( $schema ) { - return empty( $schema['readonly'] ); - } - - /** - * Create order. + * Save an object data. * - * @param WP_REST_Request $request Full details about the request. - * @return int|WP_Error + * @since 3.0.0 + * @throws WC_REST_Exception But all errors are validated before returning any data. + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error */ - protected function create_order( $request ) { + protected function save_object( $request, $creating = false ) { try { - // Make sure customer exists. - if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] && false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; } - // Make sure customer is part of blog. - if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { - add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + // Make sure gateways are loaded so hooks from gateways fire on save/create. + WC()->payment_gateways(); + + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { + // Make sure customer exists. + if ( false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } } - $order = $this->prepare_item_for_database( $request ); - $order->set_created_via( 'rest-api' ); - $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); - $order->calculate_totals(); - $order->save(); + if ( $creating ) { + $object->set_created_via( 'rest-api' ); + $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $object->calculate_totals(); + } else { + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $object->calculate_totals( true ); + } + } - // Handle set paid. + // Set coupons. + $this->calculate_coupons( $request, $object ); + + // Set status. + if ( ! empty( $request['status'] ) ) { + $object->set_status( $request['status'] ); + } + + $object->save(); + + // Actions for after the order is saved. if ( true === $request['set_paid'] ) { - $order->payment_complete( $request['transaction_id'] ); + if ( $creating || $object->needs_payment() ) { + $object->payment_complete( $request['transaction_id'] ); + } } - return $order->get_id(); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Update order. - * - * @param WP_REST_Request $request Full details about the request. - * @return int|WP_Error - */ - protected function update_order( $request ) { - try { - $order = $this->prepare_item_for_database( $request ); - $order->save(); - - // Handle set paid. - if ( $order->needs_payment() && true === $request['set_paid'] ) { - $order->payment_complete( $request['transaction_id'] ); - } - - // If items have changed, recalculate order totals. - if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { - $order->calculate_totals( true ); - } - - return $order->get_id(); + return $this->get_object( $object->get_id() ); } catch ( WC_Data_Exception $e ) { return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); } catch ( WC_REST_Exception $e ) { @@ -590,9 +561,9 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { /** * Update address. * - * @param WC_Order $order - * @param array $posted - * @param string $type + * @param WC_Order $order Order data. + * @param array $posted Posted data. + * @param string $type Address type. */ protected function update_address( $order, $posted, $type = 'billing' ) { foreach ( $posted as $key => $value ) { @@ -605,10 +576,9 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { /** * Gets the product ID from the SKU or posted ID. * - * @param array $posted Request data - * + * @throws WC_REST_Exception When SKU or ID is not valid. + * @param array $posted Request data. * @return int - * @throws WC_REST_Exception */ protected function get_product_id( $posted ) { if ( ! empty( $posted['sku'] ) ) { @@ -625,9 +595,10 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { /** * Maybe set an item prop if the value was posted. - * @param WC_Order_Item $item - * @param string $prop - * @param array $posted Request data. + * + * @param WC_Order_Item $item Order item. + * @param string $prop Order property. + * @param array $posted Request data. */ protected function maybe_set_item_prop( $item, $prop, $posted ) { if ( isset( $posted[ $prop ] ) ) { @@ -637,9 +608,10 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { /** * Maybe set item props if the values were posted. - * @param WC_Order_Item $item - * @param string[] $props - * @param array $posted Request data. + * + * @param WC_Order_Item $item Order item data. + * @param string[] $props Properties. + * @param array $posted Request data. */ protected function maybe_set_item_props( $item, $props, $posted ) { foreach ( $props as $prop ) { @@ -647,17 +619,34 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } } + /** + * Maybe set item meta if posted. + * + * @param WC_Order_Item $item Order item data. + * @param array $posted Request data. + */ + protected function maybe_set_item_meta_data( $item, $posted ) { + if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { + foreach ( $posted['meta_data'] as $meta ) { + if ( isset( $meta['key'] ) ) { + $value = isset( $meta['value'] ) ? $meta['value'] : null; + $item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } + } + /** * Create or update a line item. * - * @param array $posted Line item data. + * @param array $posted Line item data. * @param string $action 'create' to add line item or 'update' to update it. - * + * @param object $item Passed when updating an item. Null during creation. * @return WC_Order_Item_Product * @throws WC_REST_Exception Invalid data, server error. */ - protected function prepare_line_items( $posted, $action = 'create' ) { - $item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + protected function prepare_line_items( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; $product = wc_get_product( $this->get_product_id( $posted ) ); if ( $product !== $item->get_product() ) { @@ -672,6 +661,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); return $item; } @@ -679,14 +669,14 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { /** * Create or update an order shipping method. * - * @param $posted $shipping Item data. + * @param array $posted $shipping Item data. * @param string $action 'create' to add shipping or 'update' to update it. - * + * @param object $item Passed when updating an item. Null during creation. * @return WC_Order_Item_Shipping * @throws WC_REST_Exception Invalid data, server error. */ - protected function prepare_shipping_lines( $posted, $action ) { - $item = new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; if ( 'create' === $action ) { if ( empty( $posted['method_id'] ) ) { @@ -695,6 +685,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); return $item; } @@ -702,14 +693,14 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { /** * Create or update an order fee. * - * @param array $posted Item data. + * @param array $posted Item data. * @param string $action 'create' to add fee or 'update' to update it. - * + * @param object $item Passed when updating an item. Null during creation. * @return WC_Order_Item_Fee * @throws WC_REST_Exception Invalid data, server error. */ - protected function prepare_fee_lines( $posted, $action ) { - $item = new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; if ( 'create' === $action ) { if ( empty( $posted['name'] ) ) { @@ -718,6 +709,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); return $item; } @@ -725,14 +717,14 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { /** * Create or update an order coupon. * - * @param array $posted Item data. + * @param array $posted Item data. * @param string $action 'create' to add coupon or 'update' to update it. - * + * @param object $item Passed when updating an item. Null during creation. * @return WC_Order_Item_Coupon * @throws WC_REST_Exception Invalid data, server error. */ - protected function prepare_coupon_lines( $posted, $action ) { - $item = new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; if ( 'create' === $action ) { if ( empty( $posted['code'] ) ) { @@ -741,6 +733,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); return $item; } @@ -750,10 +743,10 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { * When updating, the item ID provided is checked to ensure it is associated * with the order. * - * @param WC_Order $order order - * @param string $item_type - * @param array $posted item provided in the request body - * @throws WC_REST_Exception If item ID is not associated with order + * @param WC_Order $order order object. + * @param string $item_type The item type. + * @param array $posted item provided in the request body. + * @throws WC_REST_Exception If item ID is not associated with order. */ protected function set_item( $order, $item_type, $posted ) { global $wpdb; @@ -765,29 +758,23 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } $method = 'prepare_' . $item_type; + $item = null; // Verify provided line item ID is associated with order. if ( 'update' === $action ) { - $result = $wpdb->get_row( - $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d", - absint( $posted['id'] ), - absint( $order->get_id() ) - ) ); - if ( is_null( $result ) ) { + $item = $order->get_item( absint( $posted['id'] ), false ); + + if ( ! $item ) { throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); } } - // Prepare item data - $item = $this->$method( $posted, $action ); + // Prepare item data. + $item = $this->$method( $posted, $action, $item ); - /** - * Action hook to adjust item before save. - * @since 3.0.0 - */ do_action( 'woocommerce_rest_set_order_item', $item, $posted ); - // Save or add to order + // If creating the order, add the item to it. if ( 'create' === $action ) { $order->add_item( $item ); } else { @@ -814,84 +801,9 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { return false; } - /** - * Create a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $order_id = $this->create_order( $request ); - if ( is_wp_error( $order_id ) ) { - return $order_id; - } - - $post = get_post( $order_id ); - $this->update_additional_fields_for_object( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); - - return $response; - } - - /** - * Update a single order. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - try { - $post_id = (int) $request['id']; - - if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - $order_id = $this->update_order( $request ); - if ( is_wp_error( $order_id ) ) { - return $order_id; - } - - $post = get_post( $order_id ); - $this->update_additional_fields_for_object( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - return rest_ensure_response( $response ); - - } catch ( Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - /** * Get order statuses without prefixes. + * * @return array */ protected function get_order_statuses() { @@ -915,116 +827,151 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'title' => $this->post_type, 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'parent_id' => array( + 'parent_id' => array( 'description' => __( 'Parent order ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'status' => array( + 'number' => array( + 'description' => __( 'Order number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'created_via' => array( + 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'version' => array( + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( 'description' => __( 'Order status.', 'woocommerce' ), 'type' => 'string', 'default' => 'pending', 'enum' => $this->get_order_statuses(), 'context' => array( 'view', 'edit' ), ), - 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'number' => array( - 'description' => __( 'Order number.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'currency' => array( + 'currency' => array( 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), 'type' => 'string', 'default' => get_woocommerce_currency(), 'enum' => array_keys( get_woocommerce_currencies() ), 'context' => array( 'view', 'edit' ), ), - 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order was created, as GMT.", 'woocommerce' ), + 'date_created' => array( + 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_modified' => array( - 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce' ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), - 'type' => 'integer', - 'default' => 0, + 'date_modified' => array( + 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', 'context' => array( 'view', 'edit' ), + 'readonly' => true, ), - 'discount_total' => array( + 'date_modified_gmt' => array( + 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_total' => array( 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'discount_tax' => array( + 'discount_tax' => array( 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'shipping_total' => array( + 'shipping_total' => array( 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'shipping_tax' => array( + 'shipping_tax' => array( 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'cart_tax' => array( + 'cart_tax' => array( 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'total' => array( + 'total' => array( 'description' => __( 'Grand total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'total_tax' => array( + 'total_tax' => array( 'description' => __( 'Sum of all taxes.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'billing' => array( + 'prices_include_tax' => array( + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_id' => array( + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 0, + 'context' => array( 'view', 'edit' ), + ), + 'customer_ip_address' => array( + 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_user_agent' => array( + 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_note' => array( + 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'billing' => array( 'description' => __( 'Billing address.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), @@ -1034,60 +981,60 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'last_name' => array( + 'last_name' => array( 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'company' => array( + 'company' => array( 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce' ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce' ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'city' => array( + 'city' => array( 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'state' => array( + 'state' => array( 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'postcode' => array( + 'postcode' => array( 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'country' => array( + 'country' => array( 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'email' => array( + 'email' => array( 'description' => __( 'Email address.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), - 'phone' => array( + 'phone' => array( 'description' => __( 'Phone number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), - 'shipping' => array( + 'shipping' => array( 'description' => __( 'Shipping address.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), @@ -1097,49 +1044,49 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'last_name' => array( + 'last_name' => array( 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'company' => array( + 'company' => array( 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce' ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce' ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'city' => array( + 'city' => array( 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'state' => array( + 'state' => array( 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'postcode' => array( + 'postcode' => array( 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'country' => array( + 'country' => array( 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), - 'payment_method' => array( + 'payment_method' => array( 'description' => __( 'Payment method ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -1152,84 +1099,86 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'sanitize_text_field', ), ), - 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'edit' ), - ), - 'transaction_id' => array( + 'transaction_id' => array( 'description' => __( 'Unique transaction ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_paid' => array( + 'date_paid' => array( 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'cart_hash' => array( + 'date_paid_gmt' => array( + 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_completed' => array( + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_completed_gmt' => array( + 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_hash' => array( 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'line_items' => array( + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'line_items' => array( 'description' => __( 'Line items data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'name' => array( + 'name' => array( 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), - 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'product_id' => array( + 'product_id' => array( 'description' => __( 'Product ID.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), @@ -1239,24 +1188,17 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'quantity' => array( + 'quantity' => array( 'description' => __( 'Quantity ordered.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'tax_class' => array( + 'tax_class' => array( 'description' => __( 'Tax class of product.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), - 'price' => array( - 'description' => __( 'Product price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( + 'subtotal' => array( 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -1265,18 +1207,20 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), + 'readonly' => true, ), - 'total' => array( + 'total' => array( 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'total_tax' => array( + 'total_tax' => array( 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), + 'readonly' => true, ), - 'taxes' => array( + 'taxes' => array( 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), @@ -1284,60 +1228,66 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), - 'total' => array( + 'total' => array( 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), 'subtotal' => array( 'description' => __( 'Tax subtotal.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), ), ), ), - 'meta' => array( - 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), - 'readonly' => true, 'items' => array( 'type' => 'object', 'properties' => array( - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), - 'type' => 'string', + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'label' => array( - 'description' => __( 'Meta label.', 'woocommerce' ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), ), ), ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), ), ), ), - 'tax_lines' => array( + 'tax_lines' => array( 'description' => __( 'Tax lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), @@ -1345,37 +1295,37 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'rate_code' => array( + 'rate_code' => array( 'description' => __( 'Tax rate code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'rate_id' => array( + 'rate_id' => array( 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'label' => array( + 'label' => array( 'description' => __( 'Tax rate label.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'compound' => array( + 'compound' => array( 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'tax_total' => array( + 'tax_total' => array( 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -1387,17 +1337,43 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), 'readonly' => true, ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), ), ), ), - 'shipping_lines' => array( + 'shipping_lines' => array( 'description' => __( 'Shipping lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), @@ -1408,23 +1384,28 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), - 'method_id' => array( + 'method_id' => array( 'description' => __( 'Shipping method ID.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), - 'total' => array( + 'instance_id' => array( + 'description' => __( 'Shipping instance ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'total_tax' => array( + 'total_tax' => array( 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'taxes' => array( + 'taxes' => array( 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), @@ -1432,7 +1413,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), @@ -1447,28 +1428,54 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), ), ), ), - 'fee_lines' => array( + 'fee_lines' => array( 'description' => __( 'Fee lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'name' => array( + 'name' => array( 'description' => __( 'Fee name.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), - 'tax_class' => array( + 'tax_class' => array( 'description' => __( 'Tax class of fee.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -1479,17 +1486,18 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), 'enum' => array( 'taxable', 'none' ), ), - 'total' => array( + 'total' => array( 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'total_tax' => array( + 'total_tax' => array( 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), + 'readonly' => true, ), - 'taxes' => array( + 'taxes' => array( 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), @@ -1497,13 +1505,13 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'total' => array( + 'total' => array( 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -1518,31 +1526,58 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), ), ), ), - 'coupon_lines' => array( + 'coupon_lines' => array( 'description' => __( 'Coupons line data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'code' => array( + 'code' => array( 'description' => __( 'Coupon code.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), - 'discount' => array( + 'discount' => array( 'description' => __( 'Discount total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), + 'readonly' => true, ), 'discount_tax' => array( 'description' => __( 'Discount total tax.', 'woocommerce' ), @@ -1550,10 +1585,36 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), 'readonly' => true, ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), ), ), ), - 'refunds' => array( + 'refunds' => array( 'description' => __( 'List of refunds.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), @@ -1561,7 +1622,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Refund ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), @@ -1573,7 +1634,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'total' => array( + 'total' => array( 'description' => __( 'Refund total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -1582,6 +1643,12 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), ), + 'set_paid' => array( + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), ), ); @@ -1598,10 +1665,12 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array_merge( array( 'any' ), $this->get_order_statuses() ), - 'sanitize_callback' => 'sanitize_key', + 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), + ), 'validate_callback' => 'rest_validate_request_arg', ); $params['customer'] = array( @@ -1610,20 +1679,63 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); - $params['product'] = array( + $params['product'] = array( 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); - $params['dp'] = array( + $params['dp'] = array( 'default' => wc_get_price_decimals(), 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); + // This needs to remain a string to support extensions that filter Order Number. + $params['number'] = array( + 'description' => __( 'Limit result set to orders matching part of an order number.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); return $params; } + + /** + * Calculate coupons. + * + * @throws WC_REST_Exception When fails to set any item. + * @param WP_REST_Request $request Request object. + * @param WC_Order $order Order data. + * @return bool + */ + protected function calculate_coupons( $request, $order ) { + if ( ! isset( $request['coupon_lines'] ) || ! is_array( $request['coupon_lines'] ) ) { + return false; + } + + // Remove all coupons first to ensure calculation is correct. + foreach ( $order->get_items( 'coupon' ) as $coupon ) { + $order->remove_coupon( $coupon->get_code() ); + } + + foreach ( $request['coupon_lines'] as $item ) { + if ( is_array( $item ) ) { + if ( empty( $item['id'] ) ) { + if ( empty( $item['code'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + + $results = $order->apply_coupon( wc_clean( $item['code'] ) ); + + if ( is_wp_error( $results ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); + } + } + } + } + + return true; + } } From b90af4675496916a331dbf26a6b0ccbc257e882f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 12:45:14 +0100 Subject: [PATCH 017/440] Products --- .../Version4/Controllers/Customers.php | 2 +- src/RestApi/Version4/Controllers/Orders.php | 2 +- .../Products.php} | 2953 ++++++++--------- 3 files changed, 1297 insertions(+), 1660 deletions(-) rename src/RestApi/Version4/{class-wc-rest-products-v1-controller.php => Controllers/Products.php} (52%) diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/RestApi/Version4/Controllers/Customers.php index 762fd18e72d..221f64c2069 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -14,7 +14,7 @@ defined( 'ABSPATH' ) || exit; use \WC_REST_Controller; /** - * REST API Coupons controller class. + * REST API Customers controller class. */ class Customers extends WC_REST_Controller { diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index 21504eb461c..96920472531 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -14,7 +14,7 @@ defined( 'ABSPATH' ) || exit; use \WC_REST_CRUD_Controller; /** - * REST API Coupons controller class. + * REST API Orders controller class. */ class Orders extends WC_REST_CRUD_Controller { diff --git a/src/RestApi/Version4/class-wc-rest-products-v1-controller.php b/src/RestApi/Version4/Controllers/Products.php similarity index 52% rename from src/RestApi/Version4/class-wc-rest-products-v1-controller.php rename to src/RestApi/Version4/Controllers/Products.php index 6ca69c397c0..d60b523df75 100644 --- a/src/RestApi/Version4/class-wc-rest-products-v1-controller.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -4,30 +4,26 @@ * * Handles requests to the /products endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_CRUD_Controller; /** * REST API Products controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Posts_Controller */ -class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { +class Products extends WC_REST_CRUD_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -43,626 +39,123 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { */ protected $post_type = 'product'; + /** + * If object is hierarchical. + * + * @var bool + */ + protected $hierarchical = true; + /** * Initialize product actions. */ public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 ); - add_action( "woocommerce_rest_insert_{$this->post_type}", array( $this, 'clear_transients' ) ); + add_action( "woocommerce_rest_insert_{$this->post_type}_object", array( $this, 'clear_transients' ) ); } /** * Register the routes for products. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), - 'type' => 'boolean', + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Get post types. - * - * @return array - */ - protected function get_post_types() { - return array( 'product', 'product_variation' ); - } - - /** - * Query args. - * - * @param array $args Request args. - * @param WP_REST_Request $request Request data. - * @return array - */ - public function query_args( $args, $request ) { - // Set post_status. - $args['post_status'] = $request['status']; - - // Taxonomy query to filter products by type, category, - // tag, shipping class, and attribute. - $tax_query = array(); - - // Map between taxonomy name and arg's key. - $taxonomies = array( - 'product_cat' => 'category', - 'product_tag' => 'tag', - 'product_shipping_class' => 'shipping_class', - ); - - // Set tax_query for each passed arg. - foreach ( $taxonomies as $taxonomy => $key ) { - if ( ! empty( $request[ $key ] ) && is_array( $request[ $key ] ) ) { - $request[ $key ] = array_filter( $request[ $key ] ); - } - - if ( ! empty( $request[ $key ] ) ) { - $tax_query[] = array( - 'taxonomy' => $taxonomy, - 'field' => 'term_id', - 'terms' => $request[ $key ], - ); - } - } - - // Filter product type by slug. - if ( ! empty( $request['type'] ) ) { - $tax_query[] = array( - 'taxonomy' => 'product_type', - 'field' => 'slug', - 'terms' => $request['type'], - ); - } - - // Filter by attribute and term. - if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { - if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { - $tax_query[] = array( - 'taxonomy' => $request['attribute'], - 'field' => 'term_id', - 'terms' => $request['attribute_term'], - ); - } - } - - if ( ! empty( $tax_query ) ) { - $args['tax_query'] = $tax_query; - } - - // Filter by sku. - if ( ! empty( $request['sku'] ) ) { - $skus = explode( ',', $request['sku'] ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $request['sku']; - } - - $args['meta_query'] = $this->add_meta_query( $args, array( - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', - ) ); - } - - // Apply all WP_Query filters again. - if ( is_array( $request['filter'] ) ) { - $args = array_merge( $args, $request['filter'] ); - unset( $args['filter'] ); - } - - // Force the post_type argument, since it's not a user input variable. - if ( ! empty( $request['sku'] ) ) { - $args['post_type'] = array( 'product', 'product_variation' ); - } else { - $args['post_type'] = $this->post_type; - } - - return $args; - } - - /** - * Get the downloads for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * @return array - */ - protected function get_downloads( $product ) { - $downloads = array(); - - if ( $product->is_downloadable() ) { - foreach ( $product->get_downloads() as $file_id => $file ) { - $downloads[] = array( - 'id' => $file_id, // MD5 hash. - 'name' => $file['name'], - 'file' => $file['file'], - ); - } - } - - return $downloads; - } - - /** - * Get taxonomy terms. - * - * @param WC_Product $product Product instance. - * @param string $taxonomy Taxonomy slug. - * @return array - */ - protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { - $terms = array(); - - foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { - $terms[] = array( - 'id' => $term->term_id, - 'name' => $term->name, - 'slug' => $term->slug, - ); - } - - return $terms; - } - - /** - * Get the images for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * @return array - */ - protected function get_images( $product ) { - $images = array(); - $attachment_ids = array(); - - // Add featured image. - if ( $product->get_image_id() ) { - $attachment_ids[] = $product->get_image_id(); - } - - // Add gallery images. - $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); - - // Build image data. - foreach ( $attachment_ids as $position => $attachment_id ) { - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - continue; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - continue; - } - - $images[] = array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified_gmt ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - 'position' => (int) $position, - ); - } - - // Set a placeholder image if the product has no images set. - if ( empty( $images ) ) { - $images[] = array( - 'id' => 0, - 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), // Default to now. - 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), - 'src' => wc_placeholder_img_src(), - 'name' => __( 'Placeholder', 'woocommerce' ), - 'alt' => __( 'Placeholder', 'woocommerce' ), - 'position' => 0, - ); - } - - return $images; - } - - /** - * Get attribute taxonomy label. - * - * @param string $name Taxonomy name. - * @return string - */ - protected function get_attribute_taxonomy_label( $name ) { - $tax = get_taxonomy( $name ); - $labels = get_taxonomy_labels( $tax ); - - return $labels->singular_name; - } - - /** - * Get default attributes. - * - * @param WC_Product $product Product instance. - * @return array - */ - protected function get_default_attributes( $product ) { - $default = array(); - - if ( $product->is_type( 'variable' ) ) { - foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { - if ( 0 === strpos( $key, 'pa_' ) ) { - $default[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $key ), - 'name' => $this->get_attribute_taxonomy_label( $key ), - 'option' => $value, - ); - } else { - $default[] = array( - 'id' => 0, - 'name' => wc_attribute_taxonomy_slug( $key ), - 'option' => $value, - ); - } - } - } - - return $default; - } - - /** - * Get attribute options. - * - * @param int $product_id Product ID. - * @param array $attribute Attribute data. - * @return array - */ - protected function get_attribute_options( $product_id, $attribute ) { - if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { - return wc_get_product_terms( $product_id, $attribute['name'], array( 'fields' => 'names' ) ); - } elseif ( isset( $attribute['value'] ) ) { - return array_map( 'trim', explode( '|', $attribute['value'] ) ); - } - - return array(); - } - - /** - * Get the attributes for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * @return array - */ - protected function get_attributes( $product ) { - $attributes = array(); - - if ( $product->is_type( 'variation' ) ) { - // Variation attributes. - foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { - $name = str_replace( 'attribute_', '', $attribute_name ); - - if ( ! $attribute ) { - continue; - } - - // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. - if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { - $option_term = get_term_by( 'slug', $attribute, $name ); - $attributes[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $name ), - 'name' => $this->get_attribute_taxonomy_label( $name ), - 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, - ); - } else { - $attributes[] = array( - 'id' => 0, - 'name' => $name, - 'option' => $attribute, - ); - } - } - } else { - foreach ( $product->get_attributes() as $attribute ) { - if ( $attribute['is_taxonomy'] ) { - $attributes[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $attribute['name'] ), - 'name' => $this->get_attribute_taxonomy_label( $attribute['name'] ), - 'position' => (int) $attribute['position'], - 'visible' => (bool) $attribute['is_visible'], - 'variation' => (bool) $attribute['is_variation'], - 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), - ); - } else { - $attributes[] = array( - 'id' => 0, - 'name' => $attribute['name'], - 'position' => (int) $attribute['position'], - 'visible' => (bool) $attribute['is_visible'], - 'variation' => (bool) $attribute['is_variation'], - 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), - ); - } - } - } - - return $attributes; - } - - /** - * Get product menu order. - * - * @deprecated 3.0.0 - * @param WC_Product $product Product instance. - * @return int - */ - protected function get_product_menu_order( $product ) { - return $product->get_menu_order(); - } - - /** - * Get product data. - * - * @param WC_Product $product Product instance. - * @return array - */ - protected function get_product_data( $product ) { - $data = array( - 'id' => $product->get_id(), - 'name' => $product->get_name(), - 'slug' => $product->get_slug(), - 'permalink' => $product->get_permalink(), - 'date_created' => wc_rest_prepare_date_response( $product->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified() ), - 'type' => $product->get_type(), - 'status' => $product->get_status(), - 'featured' => $product->is_featured(), - 'catalog_visibility' => $product->get_catalog_visibility(), - 'description' => wpautop( do_shortcode( $product->get_description() ) ), - 'short_description' => apply_filters( 'woocommerce_short_description', $product->get_short_description() ), - 'sku' => $product->get_sku(), - 'price' => $product->get_price(), - 'regular_price' => $product->get_regular_price(), - 'sale_price' => $product->get_sale_price() ? $product->get_sale_price() : '', - 'date_on_sale_from' => $product->get_date_on_sale_from() ? date( 'Y-m-d', $product->get_date_on_sale_from()->getTimestamp() ) : '', - 'date_on_sale_to' => $product->get_date_on_sale_to() ? date( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ) : '', - 'price_html' => $product->get_price_html(), - 'on_sale' => $product->is_on_sale(), - 'purchasable' => $product->is_purchasable(), - 'total_sales' => $product->get_total_sales(), - 'virtual' => $product->is_virtual(), - 'downloadable' => $product->is_downloadable(), - 'downloads' => $this->get_downloads( $product ), - 'download_limit' => $product->get_download_limit(), - 'download_expiry' => $product->get_download_expiry(), - 'download_type' => 'standard', - 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url() : '', - 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text() : '', - 'tax_status' => $product->get_tax_status(), - 'tax_class' => $product->get_tax_class(), - 'manage_stock' => $product->managing_stock(), - 'stock_quantity' => $product->get_stock_quantity(), - 'in_stock' => $product->is_in_stock(), - 'backorders' => $product->get_backorders(), - 'backorders_allowed' => $product->backorders_allowed(), - 'backordered' => $product->is_on_backorder(), - 'sold_individually' => $product->is_sold_individually(), - 'weight' => $product->get_weight(), - 'dimensions' => array( - 'length' => $product->get_length(), - 'width' => $product->get_width(), - 'height' => $product->get_height(), - ), - 'shipping_required' => $product->needs_shipping(), - 'shipping_taxable' => $product->is_shipping_taxable(), - 'shipping_class' => $product->get_shipping_class(), - 'shipping_class_id' => $product->get_shipping_class_id(), - 'reviews_allowed' => $product->get_reviews_allowed(), - 'average_rating' => wc_format_decimal( $product->get_average_rating(), 2 ), - 'rating_count' => $product->get_rating_count(), - 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), - 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids() ), - 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids() ), - 'parent_id' => $product->get_parent_id(), - 'purchase_note' => wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ), - 'categories' => $this->get_taxonomy_terms( $product ), - 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), - 'images' => $this->get_images( $product ), - 'attributes' => $this->get_attributes( $product ), - 'default_attributes' => $this->get_default_attributes( $product ), - 'variations' => array(), - 'grouped_products' => array(), - 'menu_order' => $product->get_menu_order(), - ); - - return $data; - } - - /** - * Get an individual variation's data. - * - * @param WC_Product $product Product instance. - * @return array - */ - protected function get_variation_data( $product ) { - $variations = array(); - - foreach ( $product->get_children() as $child_id ) { - $variation = wc_get_product( $child_id ); - if ( ! $variation || ! $variation->exists() ) { - continue; - } - - $variations[] = array( - 'id' => $variation->get_id(), - 'date_created' => wc_rest_prepare_date_response( $variation->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $variation->get_date_modified() ), - 'permalink' => $variation->get_permalink(), - 'sku' => $variation->get_sku(), - 'price' => $variation->get_price(), - 'regular_price' => $variation->get_regular_price(), - 'sale_price' => $variation->get_sale_price(), - 'date_on_sale_from' => $variation->get_date_on_sale_from() ? date( 'Y-m-d', $variation->get_date_on_sale_from()->getTimestamp() ) : '', - 'date_on_sale_to' => $variation->get_date_on_sale_to() ? date( 'Y-m-d', $variation->get_date_on_sale_to()->getTimestamp() ) : '', - 'on_sale' => $variation->is_on_sale(), - 'purchasable' => $variation->is_purchasable(), - 'visible' => $variation->is_visible(), - 'virtual' => $variation->is_virtual(), - 'downloadable' => $variation->is_downloadable(), - 'downloads' => $this->get_downloads( $variation ), - 'download_limit' => '' !== $variation->get_download_limit() ? (int) $variation->get_download_limit() : -1, - 'download_expiry' => '' !== $variation->get_download_expiry() ? (int) $variation->get_download_expiry() : -1, - 'tax_status' => $variation->get_tax_status(), - 'tax_class' => $variation->get_tax_class(), - 'manage_stock' => $variation->managing_stock(), - 'stock_quantity' => $variation->get_stock_quantity(), - 'in_stock' => $variation->is_in_stock(), - 'backorders' => $variation->get_backorders(), - 'backorders_allowed' => $variation->backorders_allowed(), - 'backordered' => $variation->is_on_backorder(), - 'weight' => $variation->get_weight(), - 'dimensions' => array( - 'length' => $variation->get_length(), - 'width' => $variation->get_width(), - 'height' => $variation->get_height(), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), ), - 'shipping_class' => $variation->get_shipping_class(), - 'shipping_class_id' => $variation->get_shipping_class_id(), - 'image' => $this->get_images( $variation ), - 'attributes' => $this->get_attributes( $variation ), - ); - } - - return $variations; - } - - /** - * Prepare a single product output for response. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_item_for_response( $post, $request ) { - $product = wc_get_product( $post ); - $data = $this->get_product_data( $product ); - - // Add variations to variable products. - if ( $product->is_type( 'variable' ) && $product->has_child() ) { - $data['variations'] = $this->get_variation_data( $product ); - } - - // Add grouped products data. - if ( $product->is_type( 'grouped' ) && $product->has_child() ) { - $data['grouped_products'] = $product->get_children(); - } - - $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, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Product $product Product object. - * @param WP_REST_Request $request Request object. - * @return array Links for the given product. - */ - protected function prepare_links( $product, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $product->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'type' => 'boolean', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); - if ( $product->get_parent_id() ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_parent_id() ) ), - ); - } + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } - return $links; + /** + * Get object. + * + * @param int $id Object ID. + * + * @since 3.0.0 + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_product( $id ); } /** * Prepare a single product for create or update. * - * @param WP_REST_Request $request Request object. - * @return WP_Error|stdClass $data Post object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data */ - protected function prepare_item_for_database( $request ) { + protected function prepare_object_for_database( $request, $creating = false ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; // Type is the most important part here because we need to be using the correct class and methods. @@ -680,6 +173,16 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $product = new WC_Product_Simple(); } + if ( 'variation' === $product->get_type() ) { + return new WP_Error( + "woocommerce_rest_invalid_{$this->post_type}_id", + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + // Post title. if ( isset( $request['name'] ) ) { $product->set_name( wp_filter_post_kses( $request['name'] ) ); @@ -715,366 +218,6 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $product->set_reviews_allowed( $request['reviews_allowed'] ); } - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for insertion. - * - * @param WC_Product $product An object representing a single item prepared - * for inserting or updating the database. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $product, $request ); - } - - /** - * Create a single product. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $product_id = 0; - - try { - $product_id = $this->save_product( $request ); - $post = get_post( $product_id ); - $this->update_additional_fields_for_object( $post, $request ); - $this->update_post_meta_fields( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post data. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_product', $post, $request, true ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); - - return $response; - } catch ( WC_Data_Exception $e ) { - $this->delete_post( $product_id ); - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - $this->delete_post( $product_id ); - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Update a single product. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $post_id = (int) $request['id']; - - if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - try { - $product_id = $this->save_product( $request ); - $post = get_post( $product_id ); - $this->update_additional_fields_for_object( $post, $request ); - $this->update_post_meta_fields( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post data. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_product', $post, $request, false ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - - return rest_ensure_response( $response ); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Saves a product to the database. - * - * @param WP_REST_Request $request Full details about the request. - * @return int - */ - public function save_product( $request ) { - $product = $this->prepare_item_for_database( $request ); - return $product->save(); - } - - /** - * Save product images. - * - * @deprecated 3.0.0 - * @param int $product_id - * @param array $images - * @throws WC_REST_Exception - */ - protected function save_product_images( $product_id, $images ) { - $product = wc_get_product( $product_id ); - - return set_product_images( $product, $images ); - } - - /** - * Set product images. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product $product Product instance. - * @param array $images Images data. - * @return WC_Product - */ - protected function set_product_images( $product, $images ) { - if ( is_array( $images ) ) { - $gallery = array(); - - foreach ( $images as $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { - throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); - } else { - continue; - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); - } - - if ( isset( $image['position'] ) && 0 === absint( $image['position'] ) ) { - $product->set_image_id( $attachment_id ); - } else { - $gallery[] = $attachment_id; - } - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( array( 'ID' => $attachment_id, 'post_title' => $image['name'] ) ); - } - } - - if ( ! empty( $gallery ) ) { - $product->set_gallery_image_ids( $gallery ); - } - } else { - $product->set_image_id( '' ); - $product->set_gallery_image_ids( array() ); - } - - return $product; - } - - /** - * Save product shipping data. - * - * @param WC_Product $product Product instance. - * @param array $data Shipping data. - * @return WC_Product - */ - protected function save_product_shipping_data( $product, $data ) { - // Virtual. - if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { - $product->set_weight( '' ); - $product->set_height( '' ); - $product->set_length( '' ); - $product->set_width( '' ); - } else { - if ( isset( $data['weight'] ) ) { - $product->set_weight( $data['weight'] ); - } - - // Height. - if ( isset( $data['dimensions']['height'] ) ) { - $product->set_height( $data['dimensions']['height'] ); - } - - // Width. - if ( isset( $data['dimensions']['width'] ) ) { - $product->set_width( $data['dimensions']['width'] ); - } - - // Length. - if ( isset( $data['dimensions']['length'] ) ) { - $product->set_length( $data['dimensions']['length'] ); - } - } - - // Shipping class. - if ( isset( $data['shipping_class'] ) ) { - $data_store = $product->get_data_store(); - $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); - $product->set_shipping_class_id( $shipping_class_id ); - } - - return $product; - } - - /** - * Save downloadable files. - * - * @param WC_Product $product Product instance. - * @param array $downloads Downloads data. - * @param int $deprecated Deprecated since 3.0. - * @return WC_Product - */ - protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { - if ( $deprecated ) { - wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); - } - - $files = array(); - foreach ( $downloads as $key => $file ) { - if ( empty( $file['file'] ) ) { - continue; - } - - $download = new WC_Product_Download(); - $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); - $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); - $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); - $files[] = $download; - } - $product->set_downloads( $files ); - - return $product; - } - - /** - * Save taxonomy terms. - * - * @param WC_Product $product Product instance. - * @param array $terms Terms data. - * @param string $taxonomy Taxonomy name. - * @return WC_Product - */ - protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { - $term_ids = wp_list_pluck( $terms, 'id' ); - - if ( 'cat' === $taxonomy ) { - $product->set_category_ids( $term_ids ); - } elseif ( 'tag' === $taxonomy ) { - $product->set_tag_ids( $term_ids ); - } - - return $product; - } - - /** - * Save default attributes. - * - * @since 3.0.0 - * - * @param WC_Product $product Product instance. - * @param WP_REST_Request $request Request data. - * @return WC_Product - */ - protected function save_default_attributes( $product, $request ) { - if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { - $attributes = $product->get_attributes(); - $default_attributes = array(); - - foreach ( $request['default_attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( isset( $attributes[ $attribute_name ] ) ) { - $_attribute = $attributes[ $attribute_name ]; - - if ( $_attribute['is_variation'] ) { - $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( ! empty( $_attribute['is_taxonomy'] ) ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $value = $term->slug; - } else { - $value = sanitize_title( $value ); - } - } - - if ( $value ) { - $default_attributes[ $attribute_name ] = $value; - } - } - } - } - - $product->set_default_attributes( $default_attributes ); - } - - return $product; - } - - /** - * Save product meta. - * - * @deprecated 3.0.0 - * @param WC_Product $product - * @param WP_REST_Request $request - * @return bool - * @throws WC_REST_Exception - */ - protected function save_product_meta( $product, $request ) { - $product = $this->set_product_meta( $product, $request ); - $product->save(); - - return true; - } - - /** - * Set product meta. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product $product Product instance. - * @param WP_REST_Request $request Request data. - * @return WC_Product - */ - protected function set_product_meta( $product, $request ) { // Virtual. if ( isset( $request['virtual'] ) ) { $product->set_virtual( $request['virtual'] ); @@ -1201,12 +344,20 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $product->set_date_on_sale_from( $request['date_on_sale_from'] ); } + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + if ( isset( $request['date_on_sale_to'] ) ) { $product->set_date_on_sale_to( $request['date_on_sale_to'] ); } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } } - // Product parent ID for groups. + // Product parent ID. if ( isset( $request['parent_id'] ) ) { $product->set_parent_id( $request['parent_id'] ); } @@ -1216,9 +367,9 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $product->set_sold_individually( $request['sold_individually'] ); } - // Stock status. - if ( isset( $request['in_stock'] ) ) { - $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; + // Stock status; stock_status has priority over in_stock. + if ( isset( $request['stock_status'] ) ) { + $stock_status = $request['stock_status']; } else { $stock_status = $product->get_stock_status(); } @@ -1351,318 +502,967 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $product = $this->save_default_attributes( $product, $request ); } - return $product; - } - - /** - * Save variations. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product $product Product instance. - * @param WP_REST_Request $request Request data. - * @return bool - */ - protected function save_variations_data( $product, $request ) { - foreach ( $request['variations'] as $menu_order => $data ) { - $variation = new WC_Product_Variation( isset( $data['id'] ) ? absint( $data['id'] ) : 0 ); - - // Create initial name and status. - if ( ! $variation->get_slug() ) { - /* translators: 1: variation id 2: product name */ - $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); - $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); - } - - // Parent ID. - $variation->set_parent_id( $product->get_id() ); - - // Menu order. - $variation->set_menu_order( $menu_order ); - - // Status. - if ( isset( $data['visible'] ) ) { - $variation->set_status( false === $data['visible'] ? 'private' : 'publish' ); - } - - // SKU. - if ( isset( $data['sku'] ) ) { - $variation->set_sku( wc_clean( $data['sku'] ) ); - } - - // Thumbnail. - if ( isset( $data['image'] ) && is_array( $data['image'] ) ) { - $image = $data['image']; - $image = current( $image ); - if ( is_array( $image ) ) { - $image['position'] = 0; - } - - $variation = $this->set_product_images( $variation, array( $image ) ); - } - - // Virtual variation. - if ( isset( $data['virtual'] ) ) { - $variation->set_virtual( $data['virtual'] ); - } - - // Downloadable variation. - if ( isset( $data['downloadable'] ) ) { - $variation->set_downloadable( $data['downloadable'] ); - } - - // Downloads. - if ( $variation->get_downloadable() ) { - // Downloadable files. - if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { - $variation = $this->save_downloadable_files( $variation, $data['downloads'] ); - } - - // Download limit. - if ( isset( $data['download_limit'] ) ) { - $variation->set_download_limit( $data['download_limit'] ); - } - - // Download expiry. - if ( isset( $data['download_expiry'] ) ) { - $variation->set_download_expiry( $data['download_expiry'] ); - } - } - - // Shipping data. - $variation = $this->save_product_shipping_data( $variation, $data ); - - // Stock handling. - if ( isset( $data['manage_stock'] ) ) { - $variation->set_manage_stock( $data['manage_stock'] ); - } - - if ( isset( $data['in_stock'] ) ) { - $variation->set_stock_status( true === $data['in_stock'] ? 'instock' : 'outofstock' ); - } - - if ( isset( $data['backorders'] ) ) { - $variation->set_backorders( $data['backorders'] ); - } - - if ( $variation->get_manage_stock() ) { - if ( isset( $data['stock_quantity'] ) ) { - $variation->set_stock_quantity( $data['stock_quantity'] ); - } elseif ( isset( $data['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $data['inventory_delta'] ); - $variation->set_stock_quantity( $stock_quantity ); - } - } else { - $variation->set_backorders( 'no' ); - $variation->set_stock_quantity( '' ); - } - - // Regular Price. - if ( isset( $data['regular_price'] ) ) { - $variation->set_regular_price( $data['regular_price'] ); - } - - // Sale Price. - if ( isset( $data['sale_price'] ) ) { - $variation->set_sale_price( $data['sale_price'] ); - } - - if ( isset( $data['date_on_sale_from'] ) ) { - $variation->set_date_on_sale_from( $data['date_on_sale_from'] ); - } - - if ( isset( $data['date_on_sale_to'] ) ) { - $variation->set_date_on_sale_to( $data['date_on_sale_to'] ); - } - - // Tax class. - if ( isset( $data['tax_class'] ) ) { - $variation->set_tax_class( $data['tax_class'] ); - } - - // Description. - if ( isset( $data['description'] ) ) { - $variation->set_description( wp_kses_post( $data['description'] ) ); - } - - // Update taxonomies. - if ( isset( $data['attributes'] ) ) { - $attributes = array(); - $parent_attributes = $product->get_attributes(); - - foreach ( $data['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { - continue; - } - - $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); - $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $attribute_value = $term->slug; - } else { - $attribute_value = sanitize_title( $attribute_value ); - } - } - - $attributes[ $attribute_key ] = $attribute_value; - } - - $variation->set_attributes( $attributes ); - } - - $variation->save(); - - do_action( 'woocommerce_rest_save_product_variation', $variation->get_id(), $menu_order, $data ); + // Set children for a grouped product. + if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { + $product->set_children( $request['grouped_products'] ); } - return true; - } - - /** - * Add post meta fields. - * - * @param WP_Post $post Post data. - * @param WP_REST_Request $request Request data. - * @return bool|WP_Error - */ - protected function add_post_meta_fields( $post, $request ) { - return $this->update_post_meta_fields( $post, $request ); - } - - /** - * Update post meta fields. - * - * @param WP_Post $post Post data. - * @param WP_REST_Request $request Request data. - * @return bool|WP_Error - */ - protected function update_post_meta_fields( $post, $request ) { - $product = wc_get_product( $post ); - // Check for featured/gallery images, upload it and set it. if ( isset( $request['images'] ) ) { $product = $this->set_product_images( $product, $request['images'] ); } - // Save product meta fields. - $product = $this->set_product_meta( $product, $request ); - - // Save the product data. - $product->save(); - - // Save variations. - if ( $product->is_type( 'variable' ) ) { - if ( isset( $request['variations'] ) && is_array( $request['variations'] ) ) { - $this->save_variations_data( $product, $request ); + // Allow set meta_data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); } } - // Clear caches here so in sync with any new variations/children. - wc_delete_product_transients( $product->get_id() ); - wp_cache_delete( 'product-' . $product->get_id(), 'products' ); + if ( ! empty( $request['date_created'] ) ) { + $date = rest_parse_date( $request['date_created'] ); - return true; + if ( $date ) { + $product->set_date_created( $date ); + } + } + + if ( ! empty( $request['date_created_gmt'] ) ) { + $date = rest_parse_date( $request['date_created_gmt'], true ); + + if ( $date ) { + $product->set_date_created( $date ); + } + } + + if ( ! empty( $request['search'] ) ) { + $args['search'] = trim( $request['search'] ); + unset( $args['s'] ); + } + + if ( ! empty( $request['low_in_stock'] ) ) { + $args['low_in_stock'] = $request['low_in_stock']; + $args['post_type'] = array( 'product', 'product_variation' ); + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $product Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); } /** - * Clear cache/transients. + * Get a collection of posts and add the post title filter option to WP_Query. * - * @param WP_Post $post Post data. + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response */ - public function clear_transients( $post ) { - wc_delete_product_transients( $post->ID ); + public function get_items( $request ) { + add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); + add_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10, 2 ); + add_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10, 2 ); + $response = parent::get_items( $request ); + remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10 ); + remove_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10 ); + remove_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10 ); + return $response; } /** - * Delete post. + * Add in conditional search filters for products. * - * @param int|WP_Post $id Post ID or WP_Post instance. + * @param string $where Where clause used to search posts. + * @param object $wp_query WP_Query object. + * @return string */ - protected function delete_post( $id ) { - if ( ! empty( $id->ID ) ) { - $id = $id->ID; - } elseif ( ! is_numeric( $id ) || 0 >= $id ) { - return; + public static function add_wp_query_filter( $where, $wp_query ) { + global $wpdb; + + $search = $wp_query->get( 'search' ); + if ( $search ) { + $search = $wpdb->esc_like( $search ); + $search = "'%" . $search . "%'"; + $where .= " AND ({$wpdb->posts}.post_title LIKE {$search}"; + $where .= wc_product_sku_enabled() ? ' OR ps_post_meta.meta_key = "_sku" AND ps_post_meta.meta_value LIKE ' . $search . ')' : ')'; } - // Delete product attachments. - $attachments = get_posts( array( - 'post_parent' => $id, - 'post_status' => 'any', - 'post_type' => 'attachment', - ) ); - - foreach ( (array) $attachments as $attachment ) { - wp_delete_attachment( $attachment->ID, true ); + if ( $wp_query->get( 'low_in_stock' ) ) { + $low_stock_amount = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) ); + $where .= " AND lis_postmeta2.meta_key = '_manage_stock' + AND lis_postmeta2.meta_value = 'yes' + AND lis_postmeta.meta_key = '_stock' + AND lis_postmeta.meta_value IS NOT NULL + AND lis_postmeta3.meta_key = '_low_stock_amount' + AND ( + lis_postmeta3.meta_value > '' + AND CAST(lis_postmeta.meta_value AS SIGNED) <= CAST(lis_postmeta3.meta_value AS SIGNED) + OR lis_postmeta3.meta_value <= '' + AND CAST(lis_postmeta.meta_value AS SIGNED) <= {$low_stock_amount} + )"; } - // Delete product. - $product = wc_get_product( $id ); - $product->delete( true ); + return $where; + } + + /** + * Join posts meta tables when product search or low stock query is present. + * + * @param string $join Join clause used to search posts. + * @param object $wp_query WP_Query object. + * @return string + */ + public static function add_wp_query_join( $join, $wp_query ) { + global $wpdb; + + $search = $wp_query->get( 'search' ); + if ( $search && wc_product_sku_enabled() ) { + $join .= " INNER JOIN {$wpdb->postmeta} AS ps_post_meta ON ps_post_meta.post_id = {$wpdb->posts}.ID"; + } + + if ( $wp_query->get( 'low_in_stock' ) ) { + $join .= " INNER JOIN {$wpdb->postmeta} AS lis_postmeta ON {$wpdb->posts}.ID = lis_postmeta.post_id + INNER JOIN {$wpdb->postmeta} AS lis_postmeta2 ON {$wpdb->posts}.ID = lis_postmeta2.post_id + INNER JOIN {$wpdb->postmeta} AS lis_postmeta3 ON {$wpdb->posts}.ID = lis_postmeta3.post_id"; + } + + return $join; + } + + /** + * Group by post ID to prevent duplicates. + * + * @param string $groupby Group by clause used to organize posts. + * @param object $wp_query WP_Query object. + * @return string + */ + public static function add_wp_query_group_by( $groupby, $wp_query ) { + global $wpdb; + + $search = $wp_query->get( 'search' ); + $low_in_stock = $wp_query->get( 'low_in_stock' ); + if ( empty( $groupby ) && ( $search || $low_in_stock ) ) { + $groupby = $wpdb->posts . '.ID'; + } + return $groupby; + } + + /** + * Make extra product orderby features supported by WooCommerce available to the WC API. + * This includes 'price', 'popularity', and 'rating'. + * + * @param WP_REST_Request $request Request data. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); + + // Set post_status. + $args['post_status'] = $request['status']; + + // Taxonomy query to filter products by type, category, + // tag, shipping class, and attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies = array( + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + // Build tax_query if taxonomies are set. + if ( ! empty( $tax_query ) ) { + if ( ! empty( $args['tax_query'] ) ) { + $args['tax_query'] = array_merge( $tax_query, $args['tax_query'] ); // WPCS: slow query ok. + } else { + $args['tax_query'] = $tax_query; // WPCS: slow query ok. + } + } + + // Filter featured. + if ( is_bool( $request['featured'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'featured', + 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', + ); + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product by stock_status. + if ( ! empty( $request['stock_status'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_stock_status', + 'value' => $request['stock_status'], + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + $orderby = $request->get_param( 'orderby' ); + $order = $request->get_param( 'order' ); + + $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); + $args['orderby'] = $ordering_args['orderby']; + $args['order'] = $ordering_args['order']; + if ( $ordering_args['meta_key'] ) { + $args['meta_key'] = $ordering_args['meta_key']; // WPCS: slow query ok. + } + + return $args; + } + + /** + * Get the downloads for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * + * @return array + */ + protected function get_downloads( $product ) { + $downloads = array(); + + if ( $product->is_downloadable() ) { + foreach ( $product->get_downloads() as $file_id => $file ) { + $downloads[] = array( + 'id' => $file_id, // MD5 hash. + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param string $taxonomy Taxonomy slug. + * + * @return array + */ + protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { + $terms = array(); + + foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { + $terms[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + ); + } + + return $terms; + } + + /** + * Get the images for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_images( $product ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( $product->get_image_id() ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + + return $images; + } + + /** + * Get attribute taxonomy label. + * + * @param string $name Taxonomy name. + * + * @deprecated 3.0.0 + * @return string + */ + protected function get_attribute_taxonomy_label( $name ) { + $tax = get_taxonomy( $name ); + $labels = get_taxonomy_labels( $tax ); + + return $labels->singular_name; + } + + /** + * Get product attribute taxonomy name. + * + * @param string $slug Taxonomy name. + * @param WC_Product $product Product data. + * + * @since 3.0.0 + * @return string + */ + protected function get_attribute_taxonomy_name( $slug, $product ) { + // Format slug so it matches attributes of the product. + $slug = wc_attribute_taxonomy_slug( $slug ); + $attributes = $product->get_attributes(); + $attribute = false; + + // pa_ attributes. + if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { + $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; + } elseif ( isset( $attributes[ $slug ] ) ) { + $attribute = $attributes[ $slug ]; + } + + if ( ! $attribute ) { + return $slug; + } + + // Taxonomy attribute name. + if ( $attribute->is_taxonomy() ) { + $taxonomy = $attribute->get_taxonomy_object(); + return $taxonomy->attribute_label; + } + + // Custom product attribute name. + return $attribute->get_name(); + } + + /** + * Get default attributes. + * + * @param WC_Product $product Product instance. + * + * @return array + */ + protected function get_default_attributes( $product ) { + $default = array(); + + if ( $product->is_type( 'variable' ) ) { + foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { + if ( 0 === strpos( $key, 'pa_' ) ) { + $default[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $key ), + 'name' => $this->get_attribute_taxonomy_name( $key, $product ), + 'option' => $value, + ); + } else { + $default[] = array( + 'id' => 0, + 'name' => $this->get_attribute_taxonomy_name( $key, $product ), + 'option' => $value, + ); + } + } + } + + return $default; + } + + /** + * Get attribute options. + * + * @param int $product_id Product ID. + * @param array $attribute Attribute data. + * + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( + $product_id, + $attribute['name'], + array( + 'fields' => 'names', + ) + ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * + * @return array + */ + protected function get_attributes( $product ) { + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + $_product = wc_get_product( $product->get_parent_id() ); + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + $name = str_replace( 'attribute_', '', $attribute_name ); + + if ( empty( $attribute ) && '0' !== $attribute ) { + continue; + } + + // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. + if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $name ); + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $name ), + 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), + 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), + 'option' => $attribute, + ); + } + } + } else { + foreach ( $product->get_attributes() as $attribute ) { + $attributes[] = array( + 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, + 'name' => $this->get_attribute_taxonomy_name( $attribute['name'], $product ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + + return $attributes; + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @param string $context Request context. + * Options: 'view' and 'edit'. + * + * @return array + */ + protected function get_product_data( $product, $context = 'view' ) { + $data = array( + 'id' => $product->get_id(), + 'name' => $product->get_name( $context ), + 'slug' => $product->get_slug( $context ), + 'permalink' => $product->get_permalink(), + 'date_created' => wc_rest_prepare_date_response( $product->get_date_created( $context ), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $product->get_date_created( $context ) ), + 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified( $context ), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $product->get_date_modified( $context ) ), + 'type' => $product->get_type(), + 'status' => $product->get_status( $context ), + 'featured' => $product->is_featured(), + 'catalog_visibility' => $product->get_catalog_visibility( $context ), + 'description' => 'view' === $context ? wpautop( do_shortcode( $product->get_description() ) ) : $product->get_description( $context ), + 'short_description' => 'view' === $context ? apply_filters( 'woocommerce_short_description', $product->get_short_description() ) : $product->get_short_description( $context ), + 'sku' => $product->get_sku( $context ), + 'price' => $product->get_price( $context ), + 'regular_price' => $product->get_regular_price( $context ), + 'sale_price' => $product->get_sale_price( $context ) ? $product->get_sale_price( $context ) : '', + 'date_on_sale_from' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ) ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ) ), + 'price_html' => $product->get_price_html(), + 'on_sale' => $product->is_on_sale( $context ), + 'purchasable' => $product->is_purchasable(), + 'total_sales' => $product->get_total_sales( $context ), + 'virtual' => $product->is_virtual(), + 'downloadable' => $product->is_downloadable(), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit( $context ), + 'download_expiry' => $product->get_download_expiry( $context ), + 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url( $context ) : '', + 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text( $context ) : '', + 'tax_status' => $product->get_tax_status( $context ), + 'tax_class' => $product->get_tax_class( $context ), + 'manage_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity( $context ), + 'stock_status' => $product->get_stock_status( $context ), + 'backorders' => $product->get_backorders( $context ), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'weight' => $product->get_weight( $context ), + 'dimensions' => array( + 'length' => $product->get_length( $context ), + 'width' => $product->get_width( $context ), + 'height' => $product->get_height( $context ), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => $product->get_shipping_class_id( $context ), + 'reviews_allowed' => $product->get_reviews_allowed( $context ), + 'average_rating' => 'view' === $context ? wc_format_decimal( $product->get_average_rating(), 2 ) : $product->get_average_rating( $context ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids( $context ) ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids( $context ) ), + 'parent_id' => $product->get_parent_id( $context ), + 'purchase_note' => 'view' === $context ? wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ) : $product->get_purchase_note( $context ), + 'categories' => $this->get_taxonomy_terms( $product ), + 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), + 'images' => $this->get_images( $product ), + 'attributes' => $this->get_attributes( $product ), + 'default_attributes' => $this->get_default_attributes( $product ), + 'variations' => array(), + 'grouped_products' => array(), + 'menu_order' => $product->get_menu_order( $context ), + 'meta_data' => $product->get_meta_data(), + ); + + return $data; + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), // @codingStandardsIgnoreLine. + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), // @codingStandardsIgnoreLine. + ), + ); + + if ( $object->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $object->get_parent_id() ) ), // @codingStandardsIgnoreLine. + ); + } + + return $links; + } + + /** + * Set product images. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param array $images Images data. + * @return WC_Product + */ + protected function set_product_images( $product, $images ) { + $images = is_array( $images ) ? array_filter( $images ) : array(); + + if ( ! empty( $images ) ) { + $gallery = array(); + + foreach ( $images as $index => $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { + throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: image ID */ + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $featured_image = $product->get_image_id(); + + if ( 0 === $index ) { + $product->set_image_id( $attachment_id ); + } else { + $gallery[] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + } + + $product->set_gallery_image_ids( $gallery ); + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Save product shipping data. + * + * @param WC_Product $product Product instance. + * @param array $data Shipping data. + * + * @return WC_Product + */ + protected function save_product_shipping_data( $product, $data ) { + // Virtual. + if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { + $product->set_weight( '' ); + $product->set_height( '' ); + $product->set_length( '' ); + $product->set_width( '' ); + } else { + if ( isset( $data['weight'] ) ) { + $product->set_weight( $data['weight'] ); + } + + // Height. + if ( isset( $data['dimensions']['height'] ) ) { + $product->set_height( $data['dimensions']['height'] ); + } + + // Width. + if ( isset( $data['dimensions']['width'] ) ) { + $product->set_width( $data['dimensions']['width'] ); + } + + // Length. + if ( isset( $data['dimensions']['length'] ) ) { + $product->set_length( $data['dimensions']['length'] ); + } + } + + // Shipping class. + if ( isset( $data['shipping_class'] ) ) { + $data_store = $product->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + + return $product; + } + + /** + * Save downloadable files. + * + * @param WC_Product $product Product instance. + * @param array $downloads Downloads data. + * @param int $deprecated Deprecated since 3.0. + * + * @return WC_Product + */ + protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { + if ( $deprecated ) { + wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); + } + + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); + $files[] = $download; + } + $product->set_downloads( $files ); + + return $product; + } + + /** + * Save taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param array $terms Terms data. + * @param string $taxonomy Taxonomy name. + * + * @return WC_Product + */ + protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { + $term_ids = wp_list_pluck( $terms, 'id' ); + + if ( 'cat' === $taxonomy ) { + $product->set_category_ids( $term_ids ); + } elseif ( 'tag' === $taxonomy ) { + $product->set_tag_ids( $term_ids ); + } + + return $product; + } + + /** + * Save default attributes. + * + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * + * @since 3.0.0 + * @return WC_Product + */ + protected function save_default_attributes( $product, $request ) { + if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { + + $attributes = $product->get_attributes(); + $default_attributes = array(); + + foreach ( $request['default_attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( isset( $attributes[ $attribute_name ] ) ) { + $_attribute = $attributes[ $attribute_name ]; + + if ( $_attribute['is_variation'] ) { + $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( ! empty( $_attribute['is_taxonomy'] ) ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $value = $term->slug; + } else { + $value = sanitize_title( $value ); + } + } + + if ( $value ) { + $default_attributes[ $attribute_name ] = $value; + } + } + } + } + + $product->set_default_attributes( $default_attributes ); + } + + return $product; + } + + /** + * Clear caches here so in sync with any new variations/children. + * + * @param WC_Data $object Object data. + */ + public function clear_transients( $object ) { + wc_delete_product_transients( $object->get_id() ); + wp_cache_delete( 'product-' . $object->get_id(), 'products' ); } /** * Delete a single item. * * @param WP_REST_Request $request Full details about the request. + * * @return WP_REST_Response|WP_Error */ public function delete_item( $request ) { - $id = (int) $request['id']; - $force = (bool) $request['force']; - $post = get_post( $id ); - $product = wc_get_product( $id ); + $id = (int) $request['id']; + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; - if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); - } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce' ), array( 'status' => 404 ) ); + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( + "woocommerce_rest_{$this->post_type}_invalid_id", + __( 'Invalid ID.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); } - $supports_trash = EMPTY_TRASH_DAYS > 0; + if ( 'variation' === $object->get_type() ) { + return new WP_Error( + "woocommerce_rest_invalid_{$this->post_type}_id", + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); /** - * Filter whether an item is trashable. + * Filter whether an object is trashable. * - * Return false to disable trash support for the item. + * Return false to disable trash support for the object. * - * @param boolean $supports_trash Whether the item type support trashing. - * @param WP_Post $post The Post object being considered for trashing support. + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( + "woocommerce_rest_user_cannot_delete_{$this->post_type}", + /* translators: %s: post type */ + sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), + array( + 'status' => rest_authorization_required_code(), + ) + ); } $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); + $response = $this->prepare_object_for_response( $object, $request ); // If we're forcing, then delete permanently. if ( $force ) { - if ( $product->is_type( 'variable' ) ) { - foreach ( $product->get_children() as $child_id ) { + if ( $object->is_type( 'variable' ) ) { + foreach ( $object->get_children() as $child_id ) { $child = wc_get_product( $child_id ); if ( ! empty( $child ) ) { $child->delete( true ); @@ -1670,7 +1470,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { } } else { // For other product types, if the product has children, remove the relationship. - foreach ( $product->get_children() as $child_id ) { + foreach ( $object->get_children() as $child_id ) { $child = wc_get_product( $child_id ); if ( ! empty( $child ) ) { $child->set_parent_id( 0 ); @@ -1679,45 +1479,63 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { } } - $product->delete( true ); - $result = ! ( $product->get_id() > 0 ); + $object->delete( true ); + $result = 0 === $object->get_id(); } else { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + return new WP_Error( + 'woocommerce_rest_trash_not_supported', + /* translators: %s: post type */ + sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 501, + ) + ); } // Otherwise, only trash if we haven't already. - if ( 'trash' === $post->post_status ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); - } + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + return new WP_Error( + 'woocommerce_rest_already_trashed', + /* translators: %s: post type */ + sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 410, + ) + ); + } - // (Note that internally this falls through to `wp_delete_post` if - // the trash is disabled.) - $product->delete(); - $result = 'trash' === $product->get_status(); + $object->delete(); + $result = 'trash' === $object->get_status(); + } } if ( ! $result ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( + 'woocommerce_rest_cannot_delete', + /* translators: %s: post type */ + sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 500, + ) + ); } // Delete parent product transients. - if ( $parent_id = wp_get_post_parent_id( $id ) ) { - wc_delete_product_transients( $parent_id ); + if ( 0 !== $object->get_parent_id() ) { + wc_delete_product_transients( $object->get_parent_id() ); } /** - * Fires after a single item is deleted or trashed via the REST API. + * Fires after a single object is deleted or trashed via the REST API. * - * @param object $post The deleted or trashed item. + * @param WC_Data $object The deleted or trashed object. * @param WP_REST_Response $response The response data. * @param WP_REST_Request $request The request sent to the API. */ - do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); return $response; } @@ -1735,153 +1553,173 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'title' => $this->post_type, 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', - 'context' => array( 'view', 'edit' ), + 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), - 'name' => array( + 'name' => array( 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view', 'edit' ), + 'context' => array( 'view', 'edit', 'embed' ), ), - 'slug' => array( + 'slug' => array( 'description' => __( 'Product slug.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view', 'edit' ), + 'context' => array( 'view', 'edit', 'embed' ), ), - 'permalink' => array( + 'permalink' => array( 'description' => __( 'Product URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', - 'context' => array( 'view', 'edit' ), + 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), - 'date_created' => array( + 'date_created' => array( 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), - 'date_modified' => array( + 'date_created_gmt' => array( + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_modified' => array( 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'type' => array( + 'date_modified_gmt' => array( + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( 'description' => __( 'Product type.', 'woocommerce' ), 'type' => 'string', 'default' => 'simple', 'enum' => array_keys( wc_get_product_types() ), 'context' => array( 'view', 'edit' ), ), - 'status' => array( + 'status' => array( 'description' => __( 'Product status (post status).', 'woocommerce' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), 'context' => array( 'view', 'edit' ), ), - 'featured' => array( + 'featured' => array( 'description' => __( 'Featured product.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), - 'catalog_visibility' => array( + 'catalog_visibility' => array( 'description' => __( 'Catalog visibility.', 'woocommerce' ), 'type' => 'string', 'default' => 'visible', 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), 'context' => array( 'view', 'edit' ), ), - 'description' => array( + 'description' => array( 'description' => __( 'Product description.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view', 'edit' ), + 'context' => array( 'view', 'edit', 'embed' ), ), - 'short_description' => array( + 'short_description' => array( 'description' => __( 'Product short description.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view', 'edit' ), + 'context' => array( 'view', 'edit', 'embed' ), ), - 'sku' => array( + 'sku' => array( 'description' => __( 'Unique identifier.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'price' => array( + 'price' => array( 'description' => __( 'Current product price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'regular_price' => array( + 'regular_price' => array( 'description' => __( 'Product regular price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'sale_price' => array( + 'sale_price' => array( 'description' => __( 'Product sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'date_on_sale_from' => array( - 'description' => __( 'Start date of sale price.', 'woocommerce' ), - 'type' => 'string', + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), - 'date_on_sale_to' => array( - 'description' => __( 'End date of sale price.', 'woocommerce' ), - 'type' => 'string', + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), - 'price_html' => array( + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'on_sale' => array( + 'on_sale' => array( 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'purchasable' => array( + 'purchasable' => array( 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'total_sales' => array( + 'total_sales' => array( 'description' => __( 'Amount of sales.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'virtual' => array( + 'virtual' => array( 'description' => __( 'If the product is virtual.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), - 'downloadable' => array( + 'downloadable' => array( 'description' => __( 'If the product is downloadable.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), - 'downloads' => array( + 'downloads' => array( 'description' => __( 'List of downloadable files.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'File ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -1899,97 +1737,91 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), ), - 'download_limit' => array( + 'download_limit' => array( 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), - 'download_expiry' => array( + 'download_expiry' => array( 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), - 'download_type' => array( - 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'standard', - 'enum' => array( 'standard' ), - 'context' => array( 'view', 'edit' ), - ), - 'external_url' => array( + 'external_url' => array( 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), - 'button_text' => array( + 'button_text' => array( 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'tax_status' => array( + 'tax_status' => array( 'description' => __( 'Tax status.', 'woocommerce' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), - 'tax_class' => array( + 'tax_class' => array( 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'manage_stock' => array( + 'manage_stock' => array( 'description' => __( 'Stock management at product level.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), - 'stock_quantity' => array( + 'stock_quantity' => array( 'description' => __( 'Stock quantity.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'in_stock' => array( - 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => true, + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), 'context' => array( 'view', 'edit' ), ), - 'backorders' => array( + 'backorders' => array( 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), - 'backorders_allowed' => array( + 'backorders_allowed' => array( 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'backordered' => array( + 'backordered' => array( 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'sold_individually' => array( + 'sold_individually' => array( 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), - 'weight' => array( + 'weight' => array( /* translators: %s: weight unit */ 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'dimensions' => array( + 'dimensions' => array( 'description' => __( 'Product dimensions.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), @@ -2000,7 +1832,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'width' => array( + 'width' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', @@ -2014,90 +1846,90 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), ), - 'shipping_required' => array( + 'shipping_required' => array( 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'shipping_taxable' => array( + 'shipping_taxable' => array( 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'shipping_class' => array( + 'shipping_class' => array( 'description' => __( 'Shipping class slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'shipping_class_id' => array( + 'shipping_class_id' => array( 'description' => __( 'Shipping class ID.', 'woocommerce' ), - 'type' => 'integer', + 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'reviews_allowed' => array( + 'reviews_allowed' => array( 'description' => __( 'Allow reviews.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), - 'average_rating' => array( + 'average_rating' => array( 'description' => __( 'Reviews average rating.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'rating_count' => array( + 'rating_count' => array( 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'related_ids' => array( + 'related_ids' => array( 'description' => __( 'List of related products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + 'type' => 'integer', ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'upsell_ids' => array( - 'description' => __( 'List of upsell products IDs.', 'woocommerce' ), + 'upsell_ids' => array( + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + 'type' => 'integer', ), 'context' => array( 'view', 'edit' ), ), - 'cross_sell_ids' => array( + 'cross_sell_ids' => array( 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + 'type' => 'integer', ), 'context' => array( 'view', 'edit' ), ), - 'parent_id' => array( + 'parent_id' => array( 'description' => __( 'Product parent ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'purchase_note' => array( + 'purchase_note' => array( 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'categories' => array( + 'categories' => array( 'description' => __( 'List of categories.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Category ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), @@ -2117,14 +1949,14 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), ), - 'tags' => array( + 'tags' => array( 'description' => __( 'List of tags.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Tag ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), @@ -2144,77 +1976,84 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), ), - 'images' => array( + 'images' => array( 'description' => __( 'List of images.', 'woocommerce' ), 'type' => 'object', - 'context' => array( 'view', 'edit' ), + 'context' => array( 'view', 'edit', 'embed' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'date_created' => array( + 'date_created' => array( 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_modified' => array( + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'src' => array( + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), - 'name' => array( + 'name' => array( 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'alt' => array( + 'alt' => array( 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), ), ), ), - 'attributes' => array( + 'attributes' => array( 'description' => __( 'List of attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'name' => array( + 'name' => array( 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'position' => array( + 'position' => array( 'description' => __( 'Attribute position.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'visible' => array( + 'visible' => array( 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), 'type' => 'boolean', 'default' => false, @@ -2226,27 +2065,30 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'default' => false, 'context' => array( 'view', 'edit' ), ), - 'options' => array( + 'options' => array( 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), 'context' => array( 'view', 'edit' ), ), ), ), ), - 'default_attributes' => array( + 'default_attributes' => array( 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'name' => array( + 'name' => array( 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -2259,315 +2101,57 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), ), - 'variations' => array( - 'description' => __( 'List of variations.', 'woocommerce' ), + 'variations' => array( + 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + 'readonly' => true, + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( - 'description' => __( 'Variation ID.', 'woocommerce' ), + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce' ), - 'type' => 'string', + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( 'Start date of sale price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( 'End date of sale price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'visible' => array( - 'description' => __( 'If the variation is visible.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - ), - 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), - 'type' => 'integer', - 'default' => null, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), - 'type' => 'integer', - 'default' => null, - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'in_stock' => array( - 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), ), ), ), ), - 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), ), ); - return $this->add_additional_fields_schema( $schema ); } @@ -2579,12 +2163,12 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { public function get_collection_params() { $params = parent::get_collection_params(); - $params['slug'] = array( + $params['slug'] = array( 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); - $params['status'] = array( + $params['status'] = array( 'default' => 'any', 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), 'type' => 'string', @@ -2592,20 +2176,32 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); - $params['type'] = array( + $params['type'] = array( 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_types() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); - $params['category'] = array( + $params['sku'] = array( + 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['featured'] = array( + 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['category'] = array( 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); - $params['tag'] = array( + $params['tag'] = array( 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', @@ -2617,8 +2213,8 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); - $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce' ), + $params['attribute'] = array( + 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', @@ -2629,12 +2225,53 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); - $params['sku'] = array( - 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce' ), + + if ( wc_tax_enabled() ) { + $params['tax_class'] = array( + 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + } + $params['on_sale'] = array( + 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['min_price'] = array( + 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); + $params['max_price'] = array( + 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['low_in_stock'] = array( + 'description' => __( 'Limit result set to products that are low or out of stock.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + ); + $params['search'] = array( + 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); return $params; } From 9f989dcdce7a603703286123c1c794f22a3183f3 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 12:54:40 +0100 Subject: [PATCH 018/440] CustomerDownloads --- .../CustomerDownloads.php} | 119 ++++++++++-------- 1 file changed, 69 insertions(+), 50 deletions(-) rename src/RestApi/Version4/{class-wc-rest-customer-downloads-v1-controller.php => Controllers/CustomerDownloads.php} (68%) diff --git a/src/RestApi/Version4/class-wc-rest-customer-downloads-v1-controller.php b/src/RestApi/Version4/Controllers/CustomerDownloads.php similarity index 68% rename from src/RestApi/Version4/class-wc-rest-customer-downloads-v1-controller.php rename to src/RestApi/Version4/Controllers/CustomerDownloads.php index 904f32fa68d..07331636d4b 100644 --- a/src/RestApi/Version4/class-wc-rest-customer-downloads-v1-controller.php +++ b/src/RestApi/Version4/Controllers/CustomerDownloads.php @@ -4,30 +4,26 @@ * * Handles requests to the /customers//downloads endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Controller; /** - * REST API Customers controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller + * REST API Customer Downloads controller class. */ -class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { +class CustomerDownloads extends WC_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -40,21 +36,25 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { * Register the routes for customers. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'customer_id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base, 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' ), - ) ); + 'args' => array( + 'customer_id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + 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' ), + ) + ); } /** @@ -80,7 +80,7 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { /** * Get all customer downloads. * - * @param WP_REST_Request $request + * @param WP_REST_Request $request Request params. * @return array */ public function get_items( $request ) { @@ -99,17 +99,24 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { /** * Prepare a single download output for response. * - * @param stdObject $download Download object. + * @param stdClass $download Download object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $download, $request ) { - $data = (array) $download; - $data['access_expires'] = $data['access_expires'] ? wc_rest_prepare_date_response( $data['access_expires'] ) : 'never'; - $data['downloads_remaining'] = '' === $data['downloads_remaining'] ? 'unlimited' : $data['downloads_remaining']; - - // Remove "product_name" since it's new in 3.0. - unset( $data['product_name'] ); + $data = array( + 'download_id' => $download->download_id, + 'download_url' => $download->download_url, + 'product_id' => $download->product_id, + 'product_name' => $download->product_name, + 'download_name' => $download->download_name, + 'order_id' => $download->order_id, + 'order_key' => $download->order_key, + 'downloads_remaining' => '' === $download->downloads_remaining ? 'unlimited' : $download->downloads_remaining, + 'access_expires' => $download->access_expires ? wc_rest_prepare_date_response( $download->access_expires ) : 'never', + 'access_expires_gmt' => $download->access_expires ? wc_rest_prepare_date_response( get_gmt_from_date( $download->access_expires ) ) : 'never', + 'file' => $download->file, + ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); @@ -124,7 +131,7 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { * Filter customer download data returned from the REST API. * * @param WP_REST_Response $response The response object. - * @param stdObject $download Download object used to create response. + * @param stdClass $download Download object used to create response. * @param WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); @@ -133,7 +140,7 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { /** * Prepare links for the request. * - * @param stdClass $download Download object. + * @param stdClass $download Download object. * @param WP_REST_Request $request Request object. * @return array Links for the given customer download. */ @@ -165,37 +172,43 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { 'title' => 'customer_download', 'type' => 'object', 'properties' => array( - 'download_url' => array( + 'download_id' => array( + 'description' => __( 'Download ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_url' => array( 'description' => __( 'Download file URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), - 'download_id' => array( - 'description' => __( 'Download ID (MD5).', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'product_id' => array( + 'product_id' => array( 'description' => __( 'Downloadable product ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), - 'download_name' => array( + 'product_name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_name' => array( 'description' => __( 'Downloadable file name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), - 'order_id' => array( + 'order_id' => array( 'description' => __( 'Order ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), - 'order_key' => array( + 'order_key' => array( 'description' => __( 'Order key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), @@ -207,18 +220,24 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { 'context' => array( 'view' ), 'readonly' => true, ), - 'access_expires' => array( + 'access_expires' => array( 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), - 'file' => array( + 'access_expires_gmt' => array( + 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( 'description' => __( 'File details.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, - 'properties' => array( + 'properties' => array( 'name' => array( 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', From 837ed25a73129e3bc525b91eb535ad527e174396 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 12:59:14 +0100 Subject: [PATCH 019/440] OrderNotes --- .../OrderNotes.php} | 95 ++++++++++++++----- 1 file changed, 69 insertions(+), 26 deletions(-) rename src/RestApi/Version4/{class-wc-rest-order-notes-v1-controller.php => Controllers/OrderNotes.php} (82%) diff --git a/src/RestApi/Version4/class-wc-rest-order-notes-v1-controller.php b/src/RestApi/Version4/Controllers/OrderNotes.php similarity index 82% rename from src/RestApi/Version4/class-wc-rest-order-notes-v1-controller.php rename to src/RestApi/Version4/Controllers/OrderNotes.php index 4eac1bd38e0..30121db7203 100644 --- a/src/RestApi/Version4/class-wc-rest-order-notes-v1-controller.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -4,30 +4,26 @@ * * Handles requests to the /orders//notes endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Controller; /** * REST API Order Notes controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller */ -class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { +class OrderNotes extends WC_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -175,7 +171,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { /** * Get order notes from an order. * - * @param WP_REST_Request $request + * @param WP_REST_Request $request Request data. * * @return array|WP_Error */ @@ -192,6 +188,24 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { 'type' => 'order_note', ); + // Allow filter by order note type. + if ( 'customer' === $request['type'] ) { + $args['meta_query'] = array( // WPCS: slow query ok. + array( + 'key' => 'is_customer_note', + 'value' => 1, + 'compare' => '=', + ), + ); + } elseif ( 'internal' === $request['type'] ) { + $args['meta_query'] = array( // WPCS: slow query ok. + array( + 'key' => 'is_customer_note', + 'compare' => 'NOT EXISTS', + ), + ); + } + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); $notes = get_comments( $args ); @@ -227,7 +241,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { } // Create the note. - $note_id = $order->add_order_note( $request['note'], $request['customer_note'] ); + $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); if ( ! $note_id ) { return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); @@ -331,16 +345,18 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { /** * Prepare a single order note output for response. * - * @param WP_Comment $note Order note object. + * @param WP_Comment $note Order note object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $note, $request ) { $data = array( - 'id' => (int) $note->comment_ID, - 'date_created' => wc_rest_prepare_date_response( $note->comment_date_gmt ), - 'note' => $note->comment_content, - 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + 'id' => (int) $note->comment_ID, + 'author' => __( 'WooCommerce', 'woocommerce' ) === $note->comment_author ? 'system' : $note->comment_author, + 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; @@ -397,29 +413,47 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { 'title' => 'order_note', 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_created' => array( + 'author' => array( + 'description' => __( 'Order note author.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'note' => array( - 'description' => __( 'Order note.', 'woocommerce' ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'note' => array( + 'description' => __( 'Order note content.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'customer_note' => array( - 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce' ), + 'customer_note' => array( + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), + 'added_by_user' => array( + 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), ), ); @@ -432,8 +466,17 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { * @return array */ public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + $params = array(); + $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); + $params['type'] = array( + 'default' => 'any', + 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'any', 'customer', 'internal' ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', ); + + return $params; } } From 5cd250f2d6d9c6f386ad3d577657be8595b45562 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 13:11:59 +0100 Subject: [PATCH 020/440] OrderRefunds --- .../OrderRefunds.php} | 491 +++++++++++++----- 1 file changed, 369 insertions(+), 122 deletions(-) rename src/RestApi/Version4/{class-wc-rest-order-refunds-v1-controller.php => Controllers/OrderRefunds.php} (51%) diff --git a/src/RestApi/Version4/class-wc-rest-order-refunds-v1-controller.php b/src/RestApi/Version4/Controllers/OrderRefunds.php similarity index 51% rename from src/RestApi/Version4/class-wc-rest-order-refunds-v1-controller.php rename to src/RestApi/Version4/Controllers/OrderRefunds.php index 03b55bfe7da..9a88b320052 100644 --- a/src/RestApi/Version4/class-wc-rest-order-refunds-v1-controller.php +++ b/src/RestApi/Version4/Controllers/OrderRefunds.php @@ -4,30 +4,26 @@ * * Handles requests to the /orders//refunds endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 2.6.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WooCommerce\RestApi\Version4\Controllers\Orders as Orders; /** * REST API Order Refunds controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Orders_V1_Controller */ -class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { +class OrderRefunds extends Orders { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -43,79 +39,193 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { */ protected $post_type = 'shop_order_refund'; + /** + * Stores the request. + * + * @var array + */ + protected $request = array(); + /** * Order refunds actions. */ public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_trashable", '__return_false' ); - add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 ); + add_filter( "woocommerce_rest_{$this->post_type}_object_trashable", '__return_false' ); } /** * Register the routes for order refunds. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => true, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_order( $id ); + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + $format_decimal = array( 'amount' ); + $format_date = array( 'date_created' ); + $format_line_items = array( 'line_items' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format line items. + foreach ( $format_line_items as $key ) { + $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'amount' => $data['amount'], + 'reason' => $data['reason'], + 'refunded_by' => $data['refunded_by'], + 'refunded_payment' => $data['refunded_payment'], + 'meta_data' => $data['meta_data'], + 'line_items' => $data['line_items'], + ); + } + + /** + * Prepare a single order output for response. + * + * @since 3.0.0 + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @return WP_Error|WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $this->request = $request; + $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + } + + $data = $this->get_formatted_item_data( $object ); + $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( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } /** * Prepare a single order refund output for response. * - * @param WP_Post $post Post object. + * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. * * @return WP_Error|WP_REST_Response @@ -233,22 +343,21 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { /** * Prepare links for the request. * - * @param WC_Order_Refund $refund Comment object. + * @param WC_Data $object Object data. * @param WP_REST_Request $request Request object. - * @return array Links for the given order refund. + * @return array Links for the given post. */ - protected function prepare_links( $refund, $request ) { - $order_id = $refund->get_parent_id(); - $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $refund->get_id() ) ), + protected function prepare_links( $object, $request ) { + $base = str_replace( '(?P[\d]+)', $object->get_parent_id(), $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), ), ); @@ -256,13 +365,15 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { } /** - * Query args. + * Prepare objects query. * - * @param array $args Request args. - * @param WP_REST_Request $request Request object. + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. * @return array */ - public function query_args( $args, $request ) { + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + $args['post_status'] = array_keys( wc_get_order_statuses() ); $args['post_parent__in'] = array( absint( $request['order_id'] ) ); @@ -292,13 +403,15 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { } // Create the refund. - $refund = wc_create_refund( array( - 'order_id' => $order_data->ID, - 'amount' => $request['amount'], - 'reason' => empty( $request['reason'] ) ? null : $request['reason'], - 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, - 'restock_items' => true, - ) ); + $refund = wc_create_refund( + array( + 'order_id' => $order_data->ID, + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) + ); if ( is_wp_error( $refund ) ) { return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); @@ -329,6 +442,89 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { return $response; } + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( 0 > $request['amount'] ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + } + + // Create the refund. + $refund = wc_create_refund( + array( + 'order_id' => $order->get_id(), + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'line_items' => empty( $request['line_items'] ) ? array() : $request['line_items'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) + ); + + if ( is_wp_error( $refund ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + } + + if ( ! $refund ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + $refund->save_meta_data(); + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $coupon Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + /** * Get the Order's schema, conforming to JSON Schema. * @@ -340,29 +536,72 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'title' => $this->post_type, 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_created' => array( + 'date_created' => array( 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'amount' => array( + 'date_created_gmt' => array( + 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'amount' => array( 'description' => __( 'Refund amount.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'reason' => array( + 'reason' => array( 'description' => __( 'Reason for refund.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'line_items' => array( + 'refunded_by' => array( + 'description' => __( 'User ID of user who created the refund.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'refunded_payment' => array( + 'description' => __( 'If the payment was refunded via the API.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'line_items' => array( 'description' => __( 'Line items data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), @@ -370,25 +609,19 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'name' => array( + 'name' => array( 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'product_id' => array( + 'product_id' => array( 'description' => __( 'Product ID.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), @@ -400,25 +633,19 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'quantity' => array( + 'quantity' => array( 'description' => __( 'Quantity ordered.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'tax_class' => array( + 'tax_class' => array( 'description' => __( 'Tax class of product.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'price' => array( - 'description' => __( 'Product price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( + 'subtotal' => array( 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -430,19 +657,19 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'total' => array( + 'total' => array( 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'total_tax' => array( + 'total_tax' => array( 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'taxes' => array( + 'taxes' => array( 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), @@ -450,13 +677,13 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'items' => array( 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'total' => array( + 'total' => array( 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -471,22 +698,22 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { ), ), ), - 'meta' => array( - 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'items' => array( 'type' => 'object', 'properties' => array( - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), - 'type' => 'string', + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'label' => array( - 'description' => __( 'Meta label.', 'woocommerce' ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -500,9 +727,27 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { ), ), ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), ), ), ), + 'api_refund' => array( + 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'edit' ), + 'default' => true, + ), ), ); @@ -525,6 +770,8 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'validate_callback' => 'rest_validate_request_arg', ); + unset( $params['status'], $params['customer'], $params['product'] ); + return $params; } } From a0061e5a3375c409df914fb9813e1776ce2dcee2 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 13:14:55 +0100 Subject: [PATCH 021/440] ProductAttributeTerms --- .../ProductAttributeTerms.php} | 197 +++++++++--------- 1 file changed, 104 insertions(+), 93 deletions(-) rename src/RestApi/Version4/{class-wc-rest-product-attribute-terms-v1-controller.php => Controllers/ProductAttributeTerms.php} (52%) diff --git a/src/RestApi/Version4/class-wc-rest-product-attribute-terms-v1-controller.php b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php similarity index 52% rename from src/RestApi/Version4/class-wc-rest-product-attribute-terms-v1-controller.php rename to src/RestApi/Version4/Controllers/ProductAttributeTerms.php index 76d43c5cd90..abeb9c8c8d3 100644 --- a/src/RestApi/Version4/class-wc-rest-product-attribute-terms-v1-controller.php +++ b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php @@ -4,30 +4,26 @@ * * Handles requests to the products/attributes//terms endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Terms_Controller; /** * REST API Product Attribute Terms controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Terms_Controller */ -class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Controller { +class ProductAttributeTerms extends WC_REST_Terms_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -40,96 +36,111 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro * Register the routes for terms. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'name' => array( - 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce' ), - 'required' => true, - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - )); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - 'args' => array( - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), - 'type' => 'integer', + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), ), - ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( + 'name' => array( + 'type' => 'string', + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'required' => true, + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); } /** * Prepare a single product attribute term output for response. * - * @param WP_Term $item Term object. - * @param WP_REST_Request $request + * @param WP_Term $item Term object. + * @param WP_REST_Request $request Request params. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { @@ -168,8 +179,8 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro /** * Update term meta fields. * - * @param WP_Term $term - * @param WP_REST_Request $request + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Request params. * @return bool|WP_Error */ protected function update_term_meta_fields( $term, $request ) { From 0730365d7cdcb51391e1b9c010313bf51ef8f281 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 13:21:22 +0100 Subject: [PATCH 022/440] ProductAttributes --- .../ProductAttributes.php} | 218 ++++++++++-------- 1 file changed, 121 insertions(+), 97 deletions(-) rename src/RestApi/Version4/{class-wc-rest-product-attributes-v1-controller.php => Controllers/ProductAttributes.php} (77%) diff --git a/src/RestApi/Version4/class-wc-rest-product-attributes-v1-controller.php b/src/RestApi/Version4/Controllers/ProductAttributes.php similarity index 77% rename from src/RestApi/Version4/class-wc-rest-product-attributes-v1-controller.php rename to src/RestApi/Version4/Controllers/ProductAttributes.php index 211380c3144..c03b84a2fb7 100644 --- a/src/RestApi/Version4/class-wc-rest-product-attributes-v1-controller.php +++ b/src/RestApi/Version4/Controllers/ProductAttributes.php @@ -4,30 +4,26 @@ * * Handles requests to the products/attributes endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Controller; /** * REST API Product Attributes controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller */ -class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { +class ProductAttributes extends WC_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -47,73 +43,88 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { * Register the routes for product attributes. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'name' => array( - 'description' => __( 'Name for the resource.', 'woocommerce' ), - 'type' => 'string', - 'required' => true, - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - )); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => true, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( + 'name' => array( + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'type' => 'string', + 'required' => true, + ), + ) ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); } /** @@ -216,7 +227,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { /** * Get all attributes. * - * @param WP_REST_Request $request + * @param WP_REST_Request $request Request params. * @return array */ public function get_items( $request ) { @@ -225,7 +236,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { foreach ( $attributes as $attribute_obj ) { $attribute = $this->prepare_item_for_response( $attribute_obj, $request ); $attribute = $this->prepare_response_for_collection( $attribute ); - $data[] = $attribute; + $data[] = $attribute; } return rest_ensure_response( $data ); @@ -240,13 +251,15 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { public function create_item( $request ) { global $wpdb; - $id = wc_create_attribute( array( - 'name' => $request['name'], - 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), - 'type' => ! empty( $request['type'] ) ? $request['type'] : 'select', - 'order_by' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', - 'has_archives' => true === $request['has_archives'], - ) ); + $id = wc_create_attribute( + array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => ! empty( $request['type'] ) ? $request['type'] : 'select', + 'order_by' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', + 'has_archives' => true === $request['has_archives'], + ) + ); // Checks for errors. if ( is_wp_error( $id ) ) { @@ -307,13 +320,16 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { global $wpdb; $id = (int) $request['id']; - $edited = wc_update_attribute( $id, array( - 'name' => $request['name'], - 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), - 'type' => $request['type'], - 'order_by' => $request['order_by'], - 'has_archives' => $request['has_archives'], - ) ); + $edited = wc_update_attribute( + $id, + array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => $request['type'], + 'order_by' => $request['order_by'], + 'has_archives' => $request['has_archives'], + ) + ); // Checks for errors. if ( is_wp_error( $edited ) ) { @@ -387,8 +403,8 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { /** * Prepare a single product attribute output for response. * - * @param obj $item Term object. - * @param WP_REST_Request $request + * @param obj $item Term object. + * @param WP_REST_Request $request Request params. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { @@ -541,11 +557,16 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { protected function get_attribute( $id ) { global $wpdb; - $attribute = $wpdb->get_row( $wpdb->prepare( " - SELECT * - FROM {$wpdb->prefix}woocommerce_attribute_taxonomies - WHERE attribute_id = %d - ", $id ) ); + $attribute = $wpdb->get_row( + $wpdb->prepare( + " + SELECT * + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", + $id + ) + ); if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); @@ -558,16 +579,19 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { * Validate attribute slug. * * @deprecated 3.2.0 - * @param string $slug - * @param bool $new_data + * @param string $slug Slug being set. + * @param bool $new_data Is the data new or old. * @return bool|WP_Error */ protected function validate_attribute_slug( $slug, $new_data = true ) { if ( strlen( $slug ) >= 28 ) { + /* Translators: %s slug. */ return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { + /* Translators: %s slug. */ return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { + /* Translators: %s slug. */ return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } From 2ca3c7f0bd5a70c16ac76199c64b608bcfdaebc7 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 13:24:09 +0100 Subject: [PATCH 023/440] ProductCategories --- .../ProductCategories.php} | 94 +++++++++++-------- 1 file changed, 54 insertions(+), 40 deletions(-) rename src/RestApi/Version4/{class-wc-rest-product-categories-v1-controller.php => Controllers/ProductCategories.php} (76%) diff --git a/src/RestApi/Version4/class-wc-rest-product-categories-v1-controller.php b/src/RestApi/Version4/Controllers/ProductCategories.php similarity index 76% rename from src/RestApi/Version4/class-wc-rest-product-categories-v1-controller.php rename to src/RestApi/Version4/Controllers/ProductCategories.php index 3cca0ab7420..743bcd511a6 100644 --- a/src/RestApi/Version4/class-wc-rest-product-categories-v1-controller.php +++ b/src/RestApi/Version4/Controllers/ProductCategories.php @@ -4,30 +4,26 @@ * * Handles requests to the products/categories endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Terms_Controller; /** * REST API Product Categories controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Terms_Controller */ -class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller { +class ProductCategories extends WC_REST_Terms_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -75,12 +71,14 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller $attachment = get_post( $image_id ); $data['image'] = array( - 'id' => (int) $image_id, - 'date_created' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), - 'src' => wp_get_attachment_url( $image_id ), - 'title' => get_the_title( $attachment ), - 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), + 'id' => (int) $image_id, + 'date_created' => wc_rest_prepare_date_response( $attachment->post_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), + 'src' => wp_get_attachment_url( $image_id ), + 'name' => get_the_title( $attachment ), + 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), ); } @@ -110,6 +108,8 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller * @param WP_Term $term Term object. * @param WP_REST_Request $request Request instance. * @return bool|WP_Error + * + * @since 3.5.5 */ protected function update_term_meta_fields( $term, $request ) { $id = (int) $term->term_id; @@ -145,11 +145,13 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller } // Set the image title. - if ( ! empty( $request['image']['title'] ) ) { - wp_update_post( array( - 'ID' => $image_id, - 'post_title' => wc_clean( $request['image']['title'] ), - ) ); + if ( ! empty( $request['image']['name'] ) ) { + wp_update_post( + array( + 'ID' => $image_id, + 'post_title' => wc_clean( $request['image']['name'] ), + ) + ); } } else { delete_term_meta( $id, 'thumbnail_id' ); @@ -166,17 +168,17 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller */ public function get_item_schema() { $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'name' => array( + 'name' => array( 'description' => __( 'Category name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -184,7 +186,7 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller 'sanitize_callback' => 'sanitize_text_field', ), ), - 'slug' => array( + 'slug' => array( 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), @@ -192,7 +194,7 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller 'sanitize_callback' => 'sanitize_title', ), ), - 'parent' => array( + 'parent' => array( 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), @@ -205,59 +207,71 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller 'sanitize_callback' => 'wp_filter_post_kses', ), ), - 'display' => array( + 'display' => array( 'description' => __( 'Category archive display type.', 'woocommerce' ), 'type' => 'string', 'default' => 'default', 'enum' => array( 'default', 'products', 'subcategories', 'both' ), 'context' => array( 'view', 'edit' ), ), - 'image' => array( + 'image' => array( 'description' => __( 'Image data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'date_created' => array( + 'date_created' => array( 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_modified' => array( + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'src' => array( + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), - 'title' => array( + 'name' => array( 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'alt' => array( + 'alt' => array( 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), - 'menu_order' => array( + 'menu_order' => array( 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'count' => array( + 'count' => array( 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), From 9614c6a3b378ef6d11f282bfddd19dea4a065fc6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 13:36:05 +0100 Subject: [PATCH 024/440] ProductReviews --- .../Version4/Controllers/ProductReviews.php | 1169 +++++++++++++++++ ...-wc-rest-product-reviews-v1-controller.php | 578 -------- 2 files changed, 1169 insertions(+), 578 deletions(-) create mode 100644 src/RestApi/Version4/Controllers/ProductReviews.php delete mode 100644 src/RestApi/Version4/class-wc-rest-product-reviews-v1-controller.php diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/RestApi/Version4/Controllers/ProductReviews.php new file mode 100644 index 00000000000..4eab95ee7a1 --- /dev/null +++ b/src/RestApi/Version4/Controllers/ProductReviews.php @@ -0,0 +1,1169 @@ +/reviews. + * + * @package WooCommerce/RestApi + */ + +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Controller; + +/** + * REST API Product Reviews controller class. + */ +class ProductReviews extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v4'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/reviews'; + + /** + * Register the routes for product reviews. + */ + public function register_routes() { + register_rest_route( + $this->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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( + 'product_id' => array( + 'required' => true, + 'description' => __( 'Unique identifier for the product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'review' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Review content.', 'woocommerce' ), + ), + 'reviewer' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + ), + 'reviewer_email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to read webhook deliveries. + * + * @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_product_reviews_permissions( 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a new product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'edit', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'delete', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all reviews. + * + * @param WP_REST_Request $request Full details about the request. + * @return array|WP_Error + */ + public function get_items( $request ) { + // Retrieve the list of registered collection query parameters. + $registered = $this->get_collection_params(); + + /* + * This array defines mappings between public API query parameters whose + * values are accepted as-passed, and their internal WP_Query parameter + * name equivalents (some are the same). Only values which are also + * present in $registered will be set. + */ + $parameter_mappings = array( + 'reviewer' => 'author__in', + 'reviewer_email' => 'author_email', + 'reviewer_exclude' => 'author__not_in', + 'exclude' => 'comment__not_in', + 'include' => 'comment__in', + 'offset' => 'offset', + 'order' => 'order', + 'per_page' => 'number', + 'product' => 'post__in', + 'search' => 'search', + 'status' => 'status', + ); + + $prepared_args = array(); + + /* + * For each known parameter which is both registered and present in the request, + * set the parameter's value on the query $prepared_args. + */ + foreach ( $parameter_mappings as $api_param => $wp_param ) { + if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { + $prepared_args[ $wp_param ] = $request[ $api_param ]; + } + } + + // Ensure certain parameter values default to empty strings. + foreach ( array( 'author_email', 'search' ) as $param ) { + if ( ! isset( $prepared_args[ $param ] ) ) { + $prepared_args[ $param ] = ''; + } + } + + if ( isset( $registered['orderby'] ) ) { + $prepared_args['orderby'] = $this->normalize_query_param( $request['orderby'] ); + } + + if ( isset( $prepared_args['status'] ) ) { + $prepared_args['status'] = 'approved' === $prepared_args['status'] ? 'approve' : $prepared_args['status']; + } + + $prepared_args['no_found_rows'] = false; + $prepared_args['date_query'] = array(); + + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $registered['before'], $request['before'] ) ) { + $prepared_args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $registered['after'], $request['after'] ) ) { + $prepared_args['date_query'][0]['after'] = $request['after']; + } + + if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { + $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); + } + + /** + * Filters arguments, before passing to WP_Comment_Query, when querying reviews via the REST API. + * + * @since 3.5.0 + * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ + * @param array $prepared_args Array of arguments for WP_Comment_Query. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_product_review_query', $prepared_args, $request ); + + // Make sure that returns only reviews. + $prepared_args['type'] = 'review'; + + // Query reviews. + $query = new WP_Comment_Query(); + $query_result = $query->query( $prepared_args ); + $reviews = array(); + + foreach ( $query_result as $review ) { + if ( ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { + continue; + } + + $data = $this->prepare_item_for_response( $review, $request ); + $reviews[] = $this->prepare_response_for_collection( $data ); + } + + $total_reviews = (int) $query->found_comments; + $max_pages = (int) $query->max_num_pages; + + if ( $total_reviews < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $prepared_args['number'], $prepared_args['offset'] ); + + $query = new WP_Comment_Query(); + $prepared_args['count'] = true; + + $total_reviews = $query->query( $prepared_args ); + $max_pages = ceil( $total_reviews / $request['per_page'] ); + } + + $response = rest_ensure_response( $reviews ); + $response->header( 'X-WP-Total', $total_reviews ); + $response->header( 'X-WP-TotalPages', $max_pages ); + + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); + + if ( $request['page'] > 1 ) { + $prev_page = $request['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 > $request['page'] ) { + $next_page = $request['page'] + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Create a single review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $prepared_review ) ) { + return $prepared_review; + } + + $prepared_review['comment_type'] = 'review'; + + /* + * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). + */ + if ( empty( $prepared_review['comment_content'] ) ) { + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). + if ( ! isset( $prepared_review['comment_date_gmt'] ) ) { + $prepared_review['comment_date_gmt'] = current_time( 'mysql', true ); + } + + if ( ! empty( $_SERVER['REMOTE_ADDR'] ) && rest_is_ip_address( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) ) { // WPCS: input var ok, sanitization ok. + $prepared_review['comment_author_IP'] = wc_clean( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // WPCS: input var ok. + } else { + $prepared_review['comment_author_IP'] = '127.0.0.1'; + } + + if ( ! empty( $request['author_user_agent'] ) ) { + $prepared_review['comment_agent'] = $request['author_user_agent']; + } elseif ( $request->get_header( 'user_agent' ) ) { + $prepared_review['comment_agent'] = $request->get_header( 'user_agent' ); + } else { + $prepared_review['comment_agent'] = ''; + } + + $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); + if ( is_wp_error( $check_comment_lengths ) ) { + $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $prepared_review['comment_parent'] = 0; + $prepared_review['comment_author_url'] = ''; + $prepared_review['comment_approved'] = wp_allow_comment( $prepared_review, true ); + + if ( is_wp_error( $prepared_review['comment_approved'] ) ) { + $error_code = $prepared_review['comment_approved']->get_error_code(); + $error_message = $prepared_review['comment_approved']->get_error_message(); + + if ( 'comment_duplicate' === $error_code ) { + return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 409 ) ); + } + + if ( 'comment_flood' === $error_code ) { + return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 400 ) ); + } + + return $prepared_review['comment_approved']; + } + + /** + * Filters a review before it is inserted via the REST API. + * + * Allows modification of the review right before it is inserted via wp_insert_comment(). + * Returning a WP_Error value from the filter will shortcircuit insertion and allow + * skipping further processing. + * + * @since 3.5.0 + * @param array|WP_Error $prepared_review The prepared review data for wp_insert_comment(). + * @param WP_REST_Request $request Request used to insert the review. + */ + $prepared_review = apply_filters( 'woocommerce_rest_pre_insert_product_review', $prepared_review, $request ); + if ( is_wp_error( $prepared_review ) ) { + return $prepared_review; + } + + $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); + + if ( ! $review_id ) { + return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( isset( $request['status'] ) ) { + $this->handle_status_param( $request['status'], $review_id ); + } + + update_comment_meta( $review_id, 'rating', ! empty( $request['rating'] ) ? $request['rating'] : '0' ); + + $review = get_comment( $review_id ); + + /** + * Fires after a comment is created or updated via the REST API. + * + * @param WP_Comment $review Inserted or updated comment object. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating a comment, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_review', $review, $request, true ); + + $fields_update = $this->update_additional_fields_for_object( $review, $request ); + if ( is_wp_error( $fields_update ) ) { + return $fields_update; + } + + $context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view'; + $request->set_param( 'context', $context ); + + $response = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $response ); + + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $review_id ) ) ); + + return $response; + } + + /** + * Get a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $data = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $data ); + + return $response; + } + + /** + * Updates a review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. + */ + public function update_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $id = (int) $review->comment_ID; + + if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { + return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_args = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $prepared_args ) ) { + return $prepared_args; + } + + if ( ! empty( $prepared_args['comment_post_ID'] ) ) { + if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + if ( empty( $prepared_args ) && isset( $request['status'] ) ) { + // Only the comment status is being changed. + $change = $this->handle_status_param( $request['status'], $id ); + + if ( ! $change ) { + return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + } elseif ( ! empty( $prepared_args ) ) { + if ( is_wp_error( $prepared_args ) ) { + return $prepared_args; + } + + if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $prepared_args['comment_ID'] = $id; + + $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); + if ( is_wp_error( $check_comment_lengths ) ) { + $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); + + if ( false === $updated ) { + return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( isset( $request['status'] ) ) { + $this->handle_status_param( $request['status'], $id ); + } + } + + if ( ! empty( $request['rating'] ) ) { + update_comment_meta( $id, 'rating', $request['rating'] ); + } + + $review = get_comment( $id ); + + /** This action is documented in includes/api/class-wc-rest-product-reviews-controller.php */ + do_action( 'woocommerce_rest_insert_product_review', $review, $request, false ); + + $fields_update = $this->update_additional_fields_for_object( $review, $request ); + + if ( is_wp_error( $fields_update ) ) { + return $fields_update; + } + + $request->set_param( 'context', 'edit' ); + + $response = $this->prepare_item_for_response( $review, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Deletes a review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. + */ + public function delete_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + /** + * Filters whether a review can be trashed. + * + * Return false to disable trash support for the post. + * + * @since 3.5.0 + * @param bool $supports_trash Whether the post type support trashing. + * @param WP_Comment $review The review object being considered for trashing support. + */ + $supports_trash = apply_filters( 'woocommerce_rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $review ); + + $request->set_param( 'context', 'edit' ); + + if ( $force ) { + $previous = $this->prepare_item_for_response( $review, $request ); + $result = wp_delete_comment( $review->comment_ID, true ); + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); + } else { + // If this type doesn't support trashing, error out. + if ( ! $supports_trash ) { + /* translators: %s: force=true */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce' ), 'force=true' ), array( 'status' => 501 ) ); + } + + if ( 'trash' === $review->comment_approved ) { + return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + } + + $result = wp_trash_comment( $review->comment_ID ); + $review = get_comment( $review->comment_ID ); + $response = $this->prepare_item_for_response( $review, $request ); + } + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a review is deleted via the REST API. + * + * @param WP_Comment $review The deleted review data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_review', $review, $response, $request ); + + return $response; + } + + /** + * Prepare a single product review output for response. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $review, $request ) { + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $fields = $this->get_fields_for_response( $request ); + $data = array(); + + if ( in_array( 'id', $fields, true ) ) { + $data['id'] = (int) $review->comment_ID; + } + if ( in_array( 'date_created', $fields, true ) ) { + $data['date_created'] = wc_rest_prepare_date_response( $review->comment_date ); + } + if ( in_array( 'date_created_gmt', $fields, true ) ) { + $data['date_created_gmt'] = wc_rest_prepare_date_response( $review->comment_date_gmt ); + } + if ( in_array( 'product_id', $fields, true ) ) { + $data['product_id'] = (int) $review->comment_post_ID; + } + if ( in_array( 'status', $fields, true ) ) { + $data['status'] = $this->prepare_status_response( (string) $review->comment_approved ); + } + if ( in_array( 'reviewer', $fields, true ) ) { + $data['reviewer'] = $review->comment_author; + } + if ( in_array( 'reviewer_email', $fields, true ) ) { + $data['reviewer_email'] = $review->comment_author_email; + } + if ( in_array( 'review', $fields, true ) ) { + $data['review'] = 'view' === $context ? wpautop( $review->comment_content ) : $review->comment_content; + } + if ( in_array( 'rating', $fields, true ) ) { + $data['rating'] = (int) get_comment_meta( $review->comment_ID, 'rating', true ); + } + if ( in_array( 'verified', $fields, true ) ) { + $data['verified'] = wc_review_is_from_verified_owner( $review->comment_ID ); + } + if ( in_array( 'reviewer_avatar_urls', $fields, true ) ) { + $data['reviewer_avatar_urls'] = rest_get_avatar_urls( $review->comment_author_email ); + } + + $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( $review ) ); + + /** + * Filter product reviews object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $review Product review object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + } + + /** + * Prepare a single product review to be inserted into the database. + * + * @param WP_REST_Request $request Request object. + * @return array|WP_Error $prepared_review + */ + protected function prepare_item_for_database( $request ) { + if ( isset( $request['id'] ) ) { + $prepared_review['comment_ID'] = (int) $request['id']; + } + + if ( isset( $request['review'] ) ) { + $prepared_review['comment_content'] = $request['review']; + } + + if ( isset( $request['product_id'] ) ) { + $prepared_review['comment_post_ID'] = (int) $request['product_id']; + } + + if ( isset( $request['reviewer'] ) ) { + $prepared_review['comment_author'] = $request['reviewer']; + } + + if ( isset( $request['reviewer_email'] ) ) { + $prepared_review['comment_author_email'] = $request['reviewer_email']; + } + + if ( ! empty( $request['date_created'] ) ) { + $date_data = rest_get_date_with_gmt( $request['date_created'] ); + + if ( ! empty( $date_data ) ) { + list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; + } + } elseif ( ! empty( $request['date_created_gmt'] ) ) { + $date_data = rest_get_date_with_gmt( $request['date_created_gmt'], true ); + + if ( ! empty( $date_data ) ) { + list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; + } + } + + /** + * Filters a review after it is prepared for the database. + * + * Allows modification of the review right after it is prepared for the database. + * + * @since 3.5.0 + * @param array $prepared_review The prepared review data for `wp_insert_comment`. + * @param WP_REST_Request $request The current request. + */ + return apply_filters( 'woocommerce_rest_preprocess_product_review', $prepared_review, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $review Product review object. + * @return array Links for the given product review. + */ + protected function prepare_links( $review ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $review->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + if ( 0 !== (int) $review->comment_post_ID ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $review->comment_post_ID ) ), + 'embeddable' => true, + ); + } + if ( 0 !== (int) $review->user_id ) { + $links['reviewer'] = array( + 'href' => rest_url( 'wp/v2/users/' . $review->user_id ), + 'embeddable' => true, + ); + } + return $links; + } + + /** + * Get the Product Review's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_review', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Status of the review.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'approved', + 'enum' => array( 'approved', 'hold', 'spam', 'unspam', 'trash', 'untrash' ), + 'context' => array( 'view', 'edit' ), + ), + 'reviewer' => array( + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'reviewer_email' => array( + 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'rating' => array( + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'verified' => array( + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + if ( get_option( 'show_avatars' ) ) { + $avatar_properties = array(); + $avatar_sizes = rest_get_avatar_sizes(); + + foreach ( $avatar_sizes as $size ) { + $avatar_properties[ $size ] = array( + /* translators: %d: avatar image size in pixels */ + 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce' ), $size ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'embed', 'view', 'edit' ), + ); + } + $schema['properties']['reviewer_avatar_urls'] = array( + 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $avatar_properties, + ); + } + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + ); + $params['before'] = array( + 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + ); + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + ); + $params['include'] = array( + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + ); + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( + 'asc', + 'desc', + ), + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date_gmt', + 'enum' => array( + 'date', + 'date_gmt', + 'id', + 'include', + 'product', + ), + ); + $params['reviewer'] = array( + 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['reviewer_exclude'] = array( + 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['reviewer_email'] = array( + 'default' => null, + 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce' ), + 'format' => 'email', + 'type' => 'string', + ); + $params['product'] = array( + 'default' => array(), + 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['status'] = array( + 'default' => 'approved', + 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'enum' => array( + 'all', + 'hold', + 'approved', + 'spam', + 'trash', + ), + ); + + /** + * Filter collection parameters for the reviews controller. + * + * This filter registers the collection parameter, but does not map the + * collection parameter to an internal WP_Comment_Query parameter. Use the + * `wc_rest_review_query` filter to set WP_Comment_Query parameters. + * + * @since 3.5.0 + * @param array $params JSON Schema-formatted collection parameters. + */ + return apply_filters( 'woocommerce_rest_product_review_collection_params', $params ); + } + + /** + * Get the reivew, if the ID is valid. + * + * @since 3.5.0 + * @param int $id Supplied ID. + * @return WP_Comment|WP_Error Comment object if ID is valid, WP_Error otherwise. + */ + protected function get_review( $id ) { + $id = (int) $id; + $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + + if ( 0 >= $id ) { + return $error; + } + + $review = get_comment( $id ); + if ( empty( $review ) ) { + return $error; + } + + if ( ! empty( $review->comment_post_ID ) ) { + $post = get_post( (int) $review->comment_post_ID ); + + if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + return $review; + } + + /** + * Prepends internal property prefix to query parameters to match our response fields. + * + * @since 3.5.0 + * @param string $query_param Query parameter. + * @return string + */ + protected function normalize_query_param( $query_param ) { + $prefix = 'comment_'; + + switch ( $query_param ) { + case 'id': + $normalized = $prefix . 'ID'; + break; + case 'product': + $normalized = $prefix . 'post_ID'; + break; + case 'include': + $normalized = 'comment__in'; + break; + default: + $normalized = $prefix . $query_param; + break; + } + + return $normalized; + } + + /** + * Checks comment_approved to set comment status for single comment output. + * + * @since 3.5.0 + * @param string|int $comment_approved comment status. + * @return string Comment status. + */ + protected function prepare_status_response( $comment_approved ) { + switch ( $comment_approved ) { + case 'hold': + case '0': + $status = 'hold'; + break; + case 'approve': + case '1': + $status = 'approved'; + break; + case 'spam': + case 'trash': + default: + $status = $comment_approved; + break; + } + + return $status; + } + + /** + * Sets the comment_status of a given review object when creating or updating a review. + * + * @since 3.5.0 + * @param string|int $new_status New review status. + * @param int $id Review ID. + * @return bool Whether the status was changed. + */ + protected function handle_status_param( $new_status, $id ) { + $old_status = wp_get_comment_status( $id ); + + if ( $new_status === $old_status ) { + return false; + } + + switch ( $new_status ) { + case 'approved': + case 'approve': + case '1': + $changed = wp_set_comment_status( $id, 'approve' ); + break; + case 'hold': + case '0': + $changed = wp_set_comment_status( $id, 'hold' ); + break; + case 'spam': + $changed = wp_spam_comment( $id ); + break; + case 'unspam': + $changed = wp_unspam_comment( $id ); + break; + case 'trash': + $changed = wp_trash_comment( $id ); + break; + case 'untrash': + $changed = wp_untrash_comment( $id ); + break; + default: + $changed = false; + break; + } + + return $changed; + } +} diff --git a/src/RestApi/Version4/class-wc-rest-product-reviews-v1-controller.php b/src/RestApi/Version4/class-wc-rest-product-reviews-v1-controller.php deleted file mode 100644 index ebfbdba7778..00000000000 --- a/src/RestApi/Version4/class-wc-rest-product-reviews-v1-controller.php +++ /dev/null @@ -1,578 +0,0 @@ -/reviews. - * - * @author WooThemes - * @category API - * @package WooCommerce/RestApi - * @since 3.0.0 - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * REST API Product Reviews Controller Class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller - */ -class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'products/(?P[\d]+)/reviews'; - - /** - * Register the routes for product reviews. - */ - public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'review' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce' ), - ), - 'name' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce' ), - ), - 'email' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce' ), - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read webhook deliveries. - * - * @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_post_permissions( 'product', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $post = get_post( (int) $request['product_id'] ); - - if ( $post && ! wc_rest_check_post_permissions( 'product', 'read', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create a new product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - $post = get_post( (int) $request['product_id'] ); - if ( $post && ! wc_rest_check_post_permissions( 'product', 'create', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to update a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $post = get_post( (int) $request['product_id'] ); - if ( $post && ! wc_rest_check_post_permissions( 'product', 'edit', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to delete a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $post = get_post( (int) $request['product_id'] ); - if ( $post && ! wc_rest_check_post_permissions( 'product', 'delete', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Get all reviews from a product. - * - * @param WP_REST_Request $request - * - * @return array|WP_Error - */ - public function get_items( $request ) { - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $reviews = get_approved_comments( $product_id ); - $data = array(); - foreach ( $reviews as $review_data ) { - $review = $this->prepare_item_for_response( $review_data, $request ); - $review = $this->prepare_response_for_collection( $review ); - $data[] = $review; - } - - return rest_ensure_response( $data ); - } - - /** - * Get a single product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $review = get_comment( $id ); - - if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $delivery = $this->prepare_item_for_response( $review, $request ); - $response = rest_ensure_response( $delivery ); - - return $response; - } - - - /** - * Create a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $prepared_review = $this->prepare_item_for_database( $request ); - - /** - * Filter a product review (comment) before it is inserted via the REST API. - * - * Allows modification of the comment right before it is inserted via `wp_insert_comment`. - * - * @param array $prepared_review The prepared comment data for `wp_insert_comment`. - * @param WP_REST_Request $request Request used to insert the comment. - */ - $prepared_review = apply_filters( 'rest_pre_insert_product_review', $prepared_review, $request ); - - $product_review_id = wp_insert_comment( $prepared_review ); - if ( ! $product_review_id ) { - return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); - } - - update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); - - $product_review = get_comment( $product_review_id ); - $this->update_additional_fields_for_object( $product_review, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Comment $product_review Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $product_review, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $product_review_id ) ) ); - - return $response; - } - - /** - * Update a single product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $product_review_id = (int) $request['id']; - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $review = get_comment( $product_review_id ); - - if ( empty( $product_review_id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $prepared_review = $this->prepare_item_for_database( $request ); - - $updated = wp_update_comment( $prepared_review ); - if ( 0 === $updated ) { - return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); - } - - if ( ! empty( $request['rating'] ) ) { - update_comment_meta( $product_review_id, 'rating', $request['rating'] ); - } - - $product_review = get_comment( $product_review_id ); - $this->update_additional_fields_for_object( $product_review, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Comment $comment Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $product_review, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Delete a product review. - * - * @param WP_REST_Request $request Full details about the request - * - * @return bool|WP_Error|WP_REST_Response - */ - public function delete_item( $request ) { - $product_review_id = absint( is_array( $request['id'] ) ? $request['id']['id'] : $request['id'] ); - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - $product_review = get_comment( $product_review_id ); - if ( empty( $product_review_id ) || empty( $product_review->comment_ID ) || empty( $product_review->comment_post_ID ) ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - /** - * Filter whether a product review is trashable. - * - * Return false to disable trash support for the product review. - * - * @param boolean $supports_trash Whether the object supports trashing. - * @param WP_Post $product_review The object being considered for trashing support. - */ - $supports_trash = apply_filters( 'rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $product_review ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $product_review, $request ); - - if ( $force ) { - $result = wp_delete_comment( $product_review_id, true ); - } else { - if ( ! $supports_trash ) { - return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); - } - - if ( 'trash' === $product_review->comment_approved ) { - return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); - } - - $result = wp_trash_comment( $product_review->comment_ID ); - } - - if ( ! $result ) { - return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a product review is deleted via the REST API. - * - * @param object $product_review The deleted item. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'rest_delete_product_review', $product_review, $response, $request ); - - return $response; - } - - /** - * Prepare a single product review output for response. - * - * @param WP_Comment $review Product review object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $review, $request ) { - $data = array( - 'id' => (int) $review->comment_ID, - 'date_created' => wc_rest_prepare_date_response( $review->comment_date_gmt ), - 'review' => $review->comment_content, - 'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ), - 'name' => $review->comment_author, - 'email' => $review->comment_author_email, - 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), - ); - - $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( $review, $request ) ); - - /** - * Filter product reviews object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_Comment $review Product review object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); - } - - /** - * Prepare a single product review to be inserted into the database. - * - * @param WP_REST_Request $request Request object. - * @return array|WP_Error $prepared_review - */ - protected function prepare_item_for_database( $request ) { - $prepared_review = array( 'comment_approved' => 1, 'comment_type' => 'review' ); - - if ( isset( $request['id'] ) ) { - $prepared_review['comment_ID'] = (int) $request['id']; - } - - if ( isset( $request['review'] ) ) { - $prepared_review['comment_content'] = $request['review']; - } - - if ( isset( $request['product_id'] ) ) { - $prepared_review['comment_post_ID'] = (int) $request['product_id']; - } - - if ( isset( $request['name'] ) ) { - $prepared_review['comment_author'] = $request['name']; - } - - if ( isset( $request['email'] ) ) { - $prepared_review['comment_author_email'] = $request['email']; - } - - if ( isset( $request['date_created'] ) ) { - $prepared_review['comment_date'] = $request['date_created']; - } - - if ( isset( $request['date_created_gmt'] ) ) { - $prepared_review['comment_date_gmt'] = $request['date_created_gmt']; - } - - return apply_filters( 'rest_preprocess_product_review', $prepared_review, $request ); - } - - /** - * Prepare links for the request. - * - * @param WP_Comment $review Product review object. - * @param WP_REST_Request $request Request object. - * @return array Links for the given product review. - */ - protected function prepare_links( $review, $request ) { - $product_id = (int) $request['product_id']; - $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $review->comment_ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Product Review's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_review', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Reviewer name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', '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() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} From 9f3c7d1ca87259eaab536fc0107735d3963849fd Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 13:37:25 +0100 Subject: [PATCH 025/440] ProductShippingClasses --- .../ProductShippingClasses.php} | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) rename src/RestApi/Version4/{class-wc-rest-product-shipping-classes-v1-controller.php => Controllers/ProductShippingClasses.php} (90%) diff --git a/src/RestApi/Version4/class-wc-rest-product-shipping-classes-v1-controller.php b/src/RestApi/Version4/Controllers/ProductShippingClasses.php similarity index 90% rename from src/RestApi/Version4/class-wc-rest-product-shipping-classes-v1-controller.php rename to src/RestApi/Version4/Controllers/ProductShippingClasses.php index 89b59f1b9b6..47e150a5272 100644 --- a/src/RestApi/Version4/class-wc-rest-product-shipping-classes-v1-controller.php +++ b/src/RestApi/Version4/Controllers/ProductShippingClasses.php @@ -4,30 +4,26 @@ * * Handles requests to the products/shipping_classes endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Terms_Controller; /** * REST API Product Shipping Classes controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Terms_Controller */ -class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Controller { +class ProductShippingClasses extends WC_REST_Terms_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -46,8 +42,8 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr /** * Prepare a single product shipping class output for response. * - * @param obj $item Term object. - * @param WP_REST_Request $request + * @param obj $item Term object. + * @param WP_REST_Request $request Request params. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { From 5ea0d8cb4e17c1539992865ae1d084dbe2a1dd42 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 13:38:41 +0100 Subject: [PATCH 026/440] ProductTags --- .../ProductTags.php} | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) rename src/RestApi/Version4/{class-wc-rest-product-tags-v1-controller.php => Controllers/ProductTags.php} (90%) diff --git a/src/RestApi/Version4/class-wc-rest-product-tags-v1-controller.php b/src/RestApi/Version4/Controllers/ProductTags.php similarity index 90% rename from src/RestApi/Version4/class-wc-rest-product-tags-v1-controller.php rename to src/RestApi/Version4/Controllers/ProductTags.php index 76161e94e13..77d6118dfea 100644 --- a/src/RestApi/Version4/class-wc-rest-product-tags-v1-controller.php +++ b/src/RestApi/Version4/Controllers/ProductTags.php @@ -4,30 +4,26 @@ * * Handles requests to the products/tags endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Terms_Controller; /** * REST API Product Tags controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Terms_Controller */ -class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { +class ProductTags extends WC_REST_Terms_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -46,8 +42,8 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { /** * Prepare a single product tag output for response. * - * @param obj $item Term object. - * @param WP_REST_Request $request + * @param obj $item Term object. + * @param WP_REST_Request $request Request params. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { From b1d756b18137e5b269a3399aa7d8a21b2e04ab0e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:04:07 +0100 Subject: [PATCH 027/440] Track changes --- src/RestApi/Version4/changelog.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/RestApi/Version4/changelog.md diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md new file mode 100644 index 00000000000..afd213f053e --- /dev/null +++ b/src/RestApi/Version4/changelog.md @@ -0,0 +1,18 @@ +# REST API v4 Changelog + +## Changes + +- All endpoints - Rewritten with namespaces as standalone classes. +- Coupons - Added `search` parameter. +- Orders - Added order number to schema. +- Product Reviews - Updated response links. +- Products - Added `low_in_stock` and `search` parameter. + +## New endpoints + +- Added `reports/products` endpoint. + +## Removed endpoints + +- Removed `reports/top_sellers` endpoint. +- Removed `reports/sales` endpoint. From fc69c323e2bf801a1a8c31c2d13fd6ac3ce36bec Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:04:13 +0100 Subject: [PATCH 028/440] Remove old report endpoints --- ...ass-wc-rest-report-sales-v1-controller.php | 397 ------------------ ...-rest-report-top-sellers-v1-controller.php | 174 -------- 2 files changed, 571 deletions(-) delete mode 100644 src/RestApi/Version4/class-wc-rest-report-sales-v1-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-report-top-sellers-v1-controller.php diff --git a/src/RestApi/Version4/class-wc-rest-report-sales-v1-controller.php b/src/RestApi/Version4/class-wc-rest-report-sales-v1-controller.php deleted file mode 100644 index ebd52c67565..00000000000 --- a/src/RestApi/Version4/class-wc-rest-report-sales-v1-controller.php +++ /dev/null @@ -1,397 +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' ), - ) ); - } - - /** - * Check whether a given request has permission to read report. - * - * @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( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get sales reports. - * - * @param WP_REST_Request $request - * @return array|WP_Error - */ - public function get_items( $request ) { - $data = array(); - $item = $this->prepare_item_for_response( null, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - - return rest_ensure_response( $data ); - } - - /** - * Prepare a report sales object for serialization. - * - * @param null $_ - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $_, $request ) { - // Set date filtering. - $filter = array( - 'period' => $request['period'], - 'date_min' => $request['date_min'], - 'date_max' => $request['date_max'], - ); - $this->setup_report( $filter ); - - // New customers. - $users_query = new WP_User_Query( - array( - 'fields' => array( 'user_registered' ), - 'role' => 'customer', - ) - ); - - $customers = $users_query->get_results(); - - foreach ( $customers as $key => $customer ) { - if ( strtotime( $customer->user_registered ) < $this->report->start_date || strtotime( $customer->user_registered ) > $this->report->end_date ) { - unset( $customers[ $key ] ); - } - } - - $total_customers = count( $customers ); - $report_data = $this->report->get_report_data(); - $period_totals = array(); - - // Setup period totals by ensuring each period in the interval has data. - for ( $i = 0; $i <= $this->report->chart_interval; $i++ ) { - - switch ( $this->report->chart_groupby ) { - case 'day' : - $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $this->report->start_date ) ); - break; - default : - $time = date( 'Y-m', strtotime( "+{$i} MONTH", $this->report->start_date ) ); - break; - } - - // Set the customer signups for each period. - $customer_count = 0; - foreach ( $customers as $customer ) { - if ( date( ( 'day' == $this->report->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) { - $customer_count++; - } - } - - $period_totals[ $time ] = array( - 'sales' => wc_format_decimal( 0.00, 2 ), - 'orders' => 0, - 'items' => 0, - 'tax' => wc_format_decimal( 0.00, 2 ), - 'shipping' => wc_format_decimal( 0.00, 2 ), - 'discount' => wc_format_decimal( 0.00, 2 ), - 'customers' => $customer_count, - ); - } - - // add total sales, total order count, total tax and total shipping for each period - foreach ( $report_data->orders as $order ) { - $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); - - if ( ! isset( $period_totals[ $time ] ) ) { - continue; - } - - $period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 ); - $period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 ); - $period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 ); - } - - foreach ( $report_data->order_counts as $order ) { - $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); - - if ( ! isset( $period_totals[ $time ] ) ) { - continue; - } - - $period_totals[ $time ]['orders'] = (int) $order->count; - } - - // Add total order items for each period. - foreach ( $report_data->order_items as $order_item ) { - $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) ); - - if ( ! isset( $period_totals[ $time ] ) ) { - continue; - } - - $period_totals[ $time ]['items'] = (int) $order_item->order_item_count; - } - - // Add total discount for each period. - foreach ( $report_data->coupons as $discount ) { - $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) ); - - if ( ! isset( $period_totals[ $time ] ) ) { - continue; - } - - $period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 ); - } - - $sales_data = array( - 'total_sales' => $report_data->total_sales, - 'net_sales' => $report_data->net_sales, - 'average_sales' => $report_data->average_sales, - 'total_orders' => $report_data->total_orders, - 'total_items' => $report_data->total_items, - 'total_tax' => wc_format_decimal( $report_data->total_tax + $report_data->total_shipping_tax, 2 ), - 'total_shipping' => $report_data->total_shipping, - 'total_refunds' => $report_data->total_refunds, - 'total_discount' => $report_data->total_coupons, - 'totals_grouped_by' => $this->report->chart_groupby, - 'totals' => $period_totals, - 'total_customers' => $total_customers, - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $sales_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( array( - 'about' => array( - 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), - ), - ) ); - - /** - * Filter a report sales returned from the API. - * - * Allows modification of the report sales data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $data The original report object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_sales', $response, (object) $sales_data, $request ); - } - - /** - * Setup the report object and parse any date filtering. - * - * @param array $filter date filtering - */ - protected function setup_report( $filter ) { - include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); - include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' ); - - $this->report = new WC_Report_Sales_By_Date(); - - if ( empty( $filter['period'] ) ) { - // Custom date range. - $filter['period'] = 'custom'; - - if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) { - - // Overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges. - $_GET['start_date'] = $filter['date_min']; - $_GET['end_date'] = isset( $filter['date_max'] ) ? $filter['date_max'] : null; - - } else { - - // Default custom range to today. - $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); - } - } else { - $filter['period'] = empty( $filter['period'] ) ? 'week' : $filter['period']; - - // Change "week" period to "7day". - if ( 'week' === $filter['period'] ) { - $filter['period'] = '7day'; - } - } - - $this->report->calculate_current_range( $filter['period'] ); - } - - /** - * 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' => 'sales_report', - 'type' => 'object', - 'properties' => array( - 'total_sales' => array( - 'description' => __( 'Gross sales in the period.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'net_sales' => array( - 'description' => __( 'Net sales in the period.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'average_sales' => array( - 'description' => __( 'Average net daily sales.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_orders' => array( - 'description' => __( 'Total of orders placed.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_items' => array( - 'description' => __( 'Total of items purchased.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Total charged for taxes.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_shipping' => array( - 'description' => __( 'Total charged for shipping.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_refunds' => array( - 'description' => __( 'Total of refunded orders.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_discount' => array( - 'description' => __( 'Total of coupons used.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'totals_grouped_by' => array( - 'description' => __( 'Group type.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'totals' => array( - 'description' => __( 'Totals.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'array', - ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - 'period' => array( - 'description' => __( 'Report period.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( 'week', 'month', 'last_month', 'year' ), - 'validate_callback' => 'rest_validate_request_arg', - 'sanitize_callback' => 'sanitize_text_field', - ), - 'date_min' => array( - /* translators: %s: date format */ - 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), - 'type' => 'string', - 'format' => 'date', - 'validate_callback' => 'wc_rest_validate_reports_request_arg', - 'sanitize_callback' => 'sanitize_text_field', - ), - 'date_max' => array( - /* translators: %s: date format */ - 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), - 'type' => 'string', - 'format' => 'date', - 'validate_callback' => 'wc_rest_validate_reports_request_arg', - 'sanitize_callback' => 'sanitize_text_field', - ), - ); - } -} diff --git a/src/RestApi/Version4/class-wc-rest-report-top-sellers-v1-controller.php b/src/RestApi/Version4/class-wc-rest-report-top-sellers-v1-controller.php deleted file mode 100644 index 8d581540858..00000000000 --- a/src/RestApi/Version4/class-wc-rest-report-top-sellers-v1-controller.php +++ /dev/null @@ -1,174 +0,0 @@ - $request['period'], - 'date_min' => $request['date_min'], - 'date_max' => $request['date_max'], - ); - $this->setup_report( $filter ); - - $report_data = $this->report->get_order_report_data( array( - 'data' => array( - '_product_id' => array( - 'type' => 'order_item_meta', - 'order_item_type' => 'line_item', - 'function' => '', - 'name' => 'product_id', - ), - '_qty' => array( - 'type' => 'order_item_meta', - 'order_item_type' => 'line_item', - 'function' => 'SUM', - 'name' => 'order_item_qty', - ), - ), - 'order_by' => 'order_item_qty DESC', - 'group_by' => 'product_id', - 'limit' => isset( $filter['limit'] ) ? absint( $filter['limit'] ) : 12, - 'query_type' => 'get_results', - 'filter_range' => true, - ) ); - - $top_sellers = array(); - - foreach ( $report_data as $item ) { - $product = wc_get_product( $item->product_id ); - - if ( $product ) { - $top_sellers[] = array( - 'name' => $product->get_name(), - 'product_id' => (int) $item->product_id, - 'quantity' => wc_stock_amount( $item->order_item_qty ), - ); - } - } - - $data = array(); - foreach ( $top_sellers as $top_seller ) { - $item = $this->prepare_item_for_response( (object) $top_seller, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - return rest_ensure_response( $data ); - } - - /** - * Prepare a report sales object for serialization. - * - * @param stdClass $top_seller - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $top_seller, $request ) { - $data = array( - 'name' => $top_seller->name, - 'product_id' => $top_seller->product_id, - 'quantity' => $top_seller->quantity, - ); - - $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( array( - 'about' => array( - 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), - ), - 'product' => array( - 'href' => rest_url( sprintf( '/%s/products/%s', $this->namespace, $top_seller->product_id ) ), - ), - ) ); - - /** - * Filter a report top sellers returned from the API. - * - * Allows modification of the report top sellers data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $top_seller The original report object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_top_sellers', $response, $top_seller, $request ); - } - - /** - * 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' => 'top_sellers_report', - 'type' => 'object', - 'properties' => array( - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'quantity' => array( - 'description' => __( 'Total number of purchases.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} From 0d7105bdc4fdca253d309208dec23c6aac508ca9 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:12:42 +0100 Subject: [PATCH 029/440] TaxClasses --- .../TaxClasses.php} | 117 ++++++++++-------- 1 file changed, 63 insertions(+), 54 deletions(-) rename src/RestApi/Version4/{class-wc-rest-tax-classes-v1-controller.php => Controllers/TaxClasses.php} (79%) diff --git a/src/RestApi/Version4/class-wc-rest-tax-classes-v1-controller.php b/src/RestApi/Version4/Controllers/TaxClasses.php similarity index 79% rename from src/RestApi/Version4/class-wc-rest-tax-classes-v1-controller.php rename to src/RestApi/Version4/Controllers/TaxClasses.php index 6e5b25d8cd6..7b00cd8eb89 100644 --- a/src/RestApi/Version4/class-wc-rest-tax-classes-v1-controller.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -4,30 +4,26 @@ * * Handles requests to the /taxes/classes endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Terms_Controller; /** - * REST API Tax Classes controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller + * REST API Tax Class controller class. */ -class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { +class TaxClasses extends WC_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -40,43 +36,51 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { * Register the routes for tax classes. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', array( - 'args' => array( - 'slug' => array( - 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), - 'type' => 'string', + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), ), - ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'args' => array( + 'slug' => array( + 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), + 'type' => 'string', ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); } /** @@ -126,7 +130,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { /** * Get all tax classes. * - * @param WP_REST_Request $request + * @param WP_REST_Request $request Request params. * @return array */ public function get_items( $request ) { @@ -248,14 +252,19 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); // Delete tax rate locations locations from the selected class. - $wpdb->query( $wpdb->prepare( " - DELETE locations.* - FROM {$wpdb->prefix}woocommerce_tax_rate_locations AS locations - INNER JOIN - {$wpdb->prefix}woocommerce_tax_rates AS rates - ON rates.tax_rate_id = locations.tax_rate_id - WHERE rates.tax_rate_class = '%s' - ", $tax_class['slug'] ) ); + $wpdb->query( + $wpdb->prepare( + " + DELETE locations.* + FROM {$wpdb->prefix}woocommerce_tax_rate_locations AS locations + INNER JOIN + {$wpdb->prefix}woocommerce_tax_rates AS rates + ON rates.tax_rate_id = locations.tax_rate_id + WHERE rates.tax_rate_class = %s + ", + $tax_class['slug'] + ) + ); // Delete tax rates in the selected class. $wpdb->delete( $wpdb->prefix . 'woocommerce_tax_rates', array( 'tax_rate_class' => $tax_class['slug'] ), array( '%s' ) ); @@ -278,7 +287,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { /** * Prepare a single tax class output for response. * - * @param array $tax_class Tax class data. + * @param array $tax_class Tax class data. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ From ed3daf867615b12328e0c4b085dbdd7329e35ec6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:12:47 +0100 Subject: [PATCH 030/440] Reports --- src/RestApi/Version4/Controllers/Reports.php | 318 ++++++++++++++++++ src/RestApi/Version4/changelog.md | 1 + .../class-wc-rest-reports-v1-controller.php | 184 ---------- 3 files changed, 319 insertions(+), 184 deletions(-) create mode 100644 src/RestApi/Version4/Controllers/Reports.php delete mode 100644 src/RestApi/Version4/class-wc-rest-reports-v1-controller.php diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php new file mode 100644 index 00000000000..6105a7625e6 --- /dev/null +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -0,0 +1,318 @@ +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' ), + ) + ); + } + + /** + * Check whether a given request has permission to read reports. + * + * @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( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + + /** + * Get all reports. + * + * @param WP_REST_Request $request Request data. + * @return array|WP_Error + */ + public function get_items( $request ) { + $data = array(); + $reports = array( + array( + 'slug' => 'performance-indicators', + 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'revenue/stats', + 'description' => __( 'Stats about revenue.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'orders/stats', + 'description' => __( 'Stats about orders.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'products', + 'description' => __( 'Products detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'products/stats', + 'description' => __( 'Stats about products.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'categories', + 'description' => __( 'Product categories detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'categories/stats', + 'description' => __( 'Stats about product categories.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'coupons', + 'description' => __( 'Coupons detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'coupons/stats', + 'description' => __( 'Stats about coupons.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'taxes', + 'description' => __( 'Taxes detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'taxes/stats', + 'description' => __( 'Stats about taxes.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'downloads', + 'description' => __( 'Product downloads detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'downloads/files', + 'description' => __( 'Product download files detailed reports.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'downloads/stats', + 'description' => __( 'Stats about product downloads.', 'woocommerce-admin' ), + ), + array( + 'slug' => 'customers', + 'description' => __( 'Customers detailed reports.', 'woocommerce-admin' ), + ), + ); + + /** + * Filter the list of allowed reports, so that data can be loaded from third party extensions in addition to WooCommerce core. + * Array items should be in format of array( 'slug' => 'downloads/stats', 'description' => '', + * 'url' => '', and 'path' => '/wc-ext/v1/...'. + * + * @param array $endpoints The list of allowed reports.. + */ + $reports = apply_filters( 'woocommerce_admin_reports', $reports ); + + foreach ( $reports as $report ) { + if ( empty( $report['slug'] ) ) { + continue; + } + + if ( empty( $report['path'] ) ) { + $report['path'] = '/' . $this->namespace . '/reports/' . $report['slug']; + } + + // Allows a different admin page to be loaded here, + // or allows an empty url if no report exists for a set of performance indicators. + if ( ! isset( $report['url'] ) ) { + if ( '/stats' === substr( $report['slug'], -6 ) ) { + $url_slug = substr( $report['slug'], 0, -6 ); + } else { + $url_slug = $report['slug']; + } + + $report['url'] = '/analytics/' . $url_slug; + } + + $item = $this->prepare_item_for_response( (object) $report, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Get the order number for an order. If no filter is present for `woocommerce_order_number`, we can just return the ID. + * Returns the parent order number if the order is actually a refund. + * + * @param int $order_id Order ID. + * @return string + */ + public function get_order_number( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( 'shop_order_refund' === $order->get_type() ) { + $order = wc_get_order( $order->get_parent_id() ); + } + + if ( ! has_filter( 'woocommerce_order_number' ) ) { + return $order->get_id(); + } + + return $order->get_order_number(); + } + + /** + * 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 = array( + 'slug' => $report->slug, + 'description' => $report->description, + 'path' => $report->path, + ); + + $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( + array( + 'self' => array( + 'href' => rest_url( $report->path ), + ), + 'report' => array( + 'href' => $report->url, + ), + 'collection' => array( + 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), + ), + ) + ); + + /** + * 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', $response, $report, $request ); + } + + /** + * 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', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human-readable description of the resource.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'path' => array( + 'description' => __( 'API path.', 'woocommerce-admin' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + + /** + * Get order statuses without prefixes. + * + * @return array + */ + public function get_order_statuses() { + $order_statuses = array(); + + foreach ( array_keys( wc_get_order_statuses() ) as $status ) { + $order_statuses[] = str_replace( 'wc-', '', $status ); + } + + return $order_statuses; + } + + /** + * Check whether a given request has permission to read reports. + * + * @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( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } +} diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md index afd213f053e..f3cebffafc4 100644 --- a/src/RestApi/Version4/changelog.md +++ b/src/RestApi/Version4/changelog.md @@ -7,6 +7,7 @@ - Orders - Added order number to schema. - Product Reviews - Updated response links. - Products - Added `low_in_stock` and `search` parameter. +- Reports - Updated with updated list of available reports. ## New endpoints diff --git a/src/RestApi/Version4/class-wc-rest-reports-v1-controller.php b/src/RestApi/Version4/class-wc-rest-reports-v1-controller.php deleted file mode 100644 index 4b40f00875f..00000000000 --- a/src/RestApi/Version4/class-wc-rest-reports-v1-controller.php +++ /dev/null @@ -1,184 +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' ), - ) ); - } - - /** - * Check whether a given request has permission to read reports. - * - * @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( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get reports list. - * - * @since 3.5.0 - * @return array - */ - protected function get_reports() { - return array( - array( - 'slug' => 'sales', - 'description' => __( 'List of sales reports.', 'woocommerce' ), - ), - array( - 'slug' => 'top_sellers', - 'description' => __( 'List of top sellers products.', 'woocommerce' ), - ), - ); - } - - /** - * Get all reports. - * - * @param WP_REST_Request $request - * @return array|WP_Error - */ - public function get_items( $request ) { - $data = array(); - $reports = $this->get_reports(); - - foreach ( $reports as $report ) { - $item = $this->prepare_item_for_response( (object) $report, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - return rest_ensure_response( $data ); - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'description' => $report->description, - ); - - $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( array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $report->slug ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - ) ); - - /** - * 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', $response, $report, $request ); - } - - /** - * 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', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} From ebc4c95960c1fa611213827667146da44f570bb9 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:17:37 +0100 Subject: [PATCH 031/440] Taxes --- .../Version4/Controllers/TaxClasses.php | 2 +- .../Taxes.php} | 216 +++++++++++------- src/RestApi/Version4/changelog.md | 1 + 3 files changed, 132 insertions(+), 87 deletions(-) rename src/RestApi/Version4/{class-wc-rest-taxes-v1-controller.php => Controllers/Taxes.php} (79%) diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/RestApi/Version4/Controllers/TaxClasses.php index 7b00cd8eb89..8587cdaf472 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -11,7 +11,7 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Terms_Controller; +use \WC_REST_Controller; /** * REST API Tax Class controller class. diff --git a/src/RestApi/Version4/class-wc-rest-taxes-v1-controller.php b/src/RestApi/Version4/Controllers/Taxes.php similarity index 79% rename from src/RestApi/Version4/class-wc-rest-taxes-v1-controller.php rename to src/RestApi/Version4/Controllers/Taxes.php index 278e87bd999..c5f5af74f43 100644 --- a/src/RestApi/Version4/class-wc-rest-taxes-v1-controller.php +++ b/src/RestApi/Version4/Controllers/Taxes.php @@ -4,30 +4,26 @@ * * Handles requests to the /taxes endpoint. * - * @author WooThemes - * @category API * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Controller; /** * REST API Taxes controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller */ -class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { +class Taxes extends WC_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -40,67 +36,79 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { * Register the routes for taxes. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); } /** @@ -192,7 +200,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { } /** - * Get all taxes. + * Get all taxes and allow filtering by tax code. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|WP_REST_Response @@ -200,7 +208,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { public function get_items( $request ) { global $wpdb; - $prepared_args = array(); + $prepared_args = array(); $prepared_args['order'] = $request['order']; $prepared_args['number'] = $request['per_page']; if ( ! empty( $request['offset'] ) ) { @@ -208,12 +216,14 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { } else { $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; } - $orderby_possibles = array( + $orderby_possibles = array( 'id' => 'tax_rate_id', 'order' => 'tax_rate_order', ); $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; $prepared_args['class'] = $request['class']; + $prepared_args['code'] = $request['code']; + $prepared_args['include'] = $request['include']; /** * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. @@ -231,10 +241,25 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { // Filter by tax class. if ( ! empty( $prepared_args['class'] ) ) { - $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; + $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; $query .= " AND tax_rate_class = '$class'"; } + // Filter by tax code. + $tax_code_search = $prepared_args['code']; + if ( $tax_code_search ) { + $tax_code_search = $wpdb->esc_like( $tax_code_search ); + $tax_code_search = ' \'%' . $tax_code_search . '%\''; + $query .= ' AND CONCAT_WS( "-", NULLIF(tax_rate_country, ""), NULLIF(tax_rate_state, ""), NULLIF(tax_rate_name, ""), NULLIF(tax_rate_priority, "") ) LIKE ' . $tax_code_search; + } + + // Filter by included tax rate IDs. + $included_taxes = $prepared_args['include']; + if ( ! empty( $included_taxes ) ) { + $included_taxes = implode( ',', $prepared_args['include'] ); + $query .= " AND tax_rate_id IN ({$included_taxes})"; + } + // Order tax rates. $order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) ); @@ -242,11 +267,11 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { $pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] ); // Query taxes. - $results = $wpdb->get_results( $query . $order_by . $pagination ); + $results = $wpdb->get_results( $query . $order_by . $pagination ); // @codingStandardsIgnoreLine. $taxes = array(); foreach ( $results as $tax ) { - $data = $this->prepare_item_for_response( $tax, $request ); + $data = $this->prepare_item_for_response( $tax, $request ); $taxes[] = $this->prepare_response_for_collection( $data ); } @@ -254,10 +279,10 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { // Store pagination values for headers then unset for count query. $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); // Query only for ids. - $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); + $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); // @codingStandardsIgnoreLine. // Calculate totals. $total_taxes = (int) $wpdb->num_rows; @@ -287,7 +312,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { * Take tax data from the request and return the updated or newly created rate. * * @param WP_REST_Request $request Full details about the request. - * @param stdClass|null $current Existing tax object. + * @param stdClass|null $current Existing tax object. * @return object */ protected function create_or_update_tax( $request, $current = null ) { @@ -321,16 +346,16 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { // Add to data array. switch ( $key ) { - case 'tax_rate_priority' : - case 'tax_rate_compound' : - case 'tax_rate_shipping' : - case 'tax_rate_order' : + case 'tax_rate_priority': + case 'tax_rate_compound': + case 'tax_rate_shipping': + case 'tax_rate_order': $data[ $field ] = absint( $request[ $key ] ); break; - case 'tax_rate_class' : + case 'tax_rate_class': $data[ $field ] = 'standard' !== $request['tax_rate_class'] ? $request['tax_rate_class'] : ''; break; - default : + default: $data[ $field ] = wc_clean( $request[ $key ] ); break; } @@ -487,7 +512,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { /** * Prepare a single tax output for response. * - * @param stdClass $tax Tax object. + * @param stdClass $tax Tax object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ @@ -511,11 +536,16 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { ); // Get locales from a tax rate. - $locales = $wpdb->get_results( $wpdb->prepare( " - SELECT location_code, location_type - FROM {$wpdb->prefix}woocommerce_tax_rate_locations - WHERE tax_rate_id = %d - ", $id ) ); + $locales = $wpdb->get_results( + $wpdb->prepare( + " + SELECT location_code, location_type + FROM {$wpdb->prefix}woocommerce_tax_rate_locations + WHERE tax_rate_id = %d + ", + $id + ) + ); if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) { foreach ( $locales as $locale ) { @@ -703,6 +733,20 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); + $params['code'] = array( + 'description' => __( 'Search by similar tax code.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['include'] = array( + 'description' => __( 'Limit result set to items that have the specified rate ID(s) assigned.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'validate_callback' => 'rest_validate_request_arg', + ); return $params; } diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md index f3cebffafc4..9da7e0296a6 100644 --- a/src/RestApi/Version4/changelog.md +++ b/src/RestApi/Version4/changelog.md @@ -8,6 +8,7 @@ - Product Reviews - Updated response links. - Products - Added `low_in_stock` and `search` parameter. - Reports - Updated with updated list of available reports. +- Taxes - Added `code` and `include` params. ## New endpoints From 9934ec8420522748092faab26c7f40e3c9126dc9 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:20:45 +0100 Subject: [PATCH 032/440] Webhooks --- .../Webhooks.php} | 86 ++--- ...-rest-webhook-deliveries-v1-controller.php | 314 ------------------ 2 files changed, 49 insertions(+), 351 deletions(-) rename src/RestApi/Version4/{class-wc-rest-webhooks-v1-controller.php => Controllers/Webhooks.php} (92%) delete mode 100644 src/RestApi/Version4/class-wc-rest-webhook-deliveries-v1-controller.php diff --git a/src/RestApi/Version4/class-wc-rest-webhooks-v1-controller.php b/src/RestApi/Version4/Controllers/Webhooks.php similarity index 92% rename from src/RestApi/Version4/class-wc-rest-webhooks-v1-controller.php rename to src/RestApi/Version4/Controllers/Webhooks.php index 97b1640ac56..69f882c76a2 100644 --- a/src/RestApi/Version4/class-wc-rest-webhooks-v1-controller.php +++ b/src/RestApi/Version4/Controllers/Webhooks.php @@ -5,27 +5,25 @@ * Handles requests to the /webhooks endpoint. * * @package WooCommerce/RestApi - * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Controller; /** * REST API Webhooks controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller */ -class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { +class Webhooks extends WC_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -214,7 +212,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { * @return string */ protected function get_default_api_version() { - return 'wp_api_v1'; + return 'wp_api_v4'; } /** @@ -538,9 +536,9 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { /** * Prepare a single webhook output for response. * - * @param int $id Webhook ID or object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @param int $id Webhook ID. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response */ public function prepare_item_for_response( $id, $request ) { $webhook = wc_get_webhook( $id ); @@ -549,17 +547,19 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } - $data = array( - 'id' => $webhook->get_id(), - 'name' => $webhook->get_name(), - 'status' => $webhook->get_status(), - 'topic' => $webhook->get_topic(), - 'resource' => $webhook->get_resource(), - 'event' => $webhook->get_event(), - 'hooks' => $webhook->get_hooks(), - 'delivery_url' => $webhook->get_delivery_url(), - 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), + $data = array( + 'id' => $webhook->get_id(), + 'name' => $webhook->get_name(), + 'status' => $webhook->get_status(), + 'topic' => $webhook->get_topic(), + 'resource' => $webhook->get_resource(), + 'event' => $webhook->get_event(), + 'hooks' => $webhook->get_hooks(), + 'delivery_url' => $webhook->get_delivery_url(), + 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $webhook->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; @@ -569,7 +569,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { // Wrap the data in a response object. $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $webhook->get_id() ) ); + $response->add_links( $this->prepare_links( $webhook->get_id(), $request ) ); /** * Filter webhook object returned from the REST API. @@ -611,74 +611,86 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'title' => 'webhook', 'type' => 'object', 'properties' => array( - 'id' => array( + 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'name' => array( + 'name' => array( 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'status' => array( + 'status' => array( 'description' => __( 'Webhook status.', 'woocommerce' ), 'type' => 'string', 'default' => 'active', 'enum' => array_keys( wc_get_webhook_statuses() ), 'context' => array( 'view', 'edit' ), ), - 'topic' => array( + 'topic' => array( 'description' => __( 'Webhook topic.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'resource' => array( + 'resource' => array( 'description' => __( 'Webhook resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'event' => array( + 'event' => array( 'description' => __( 'Webhook event.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'hooks' => array( + 'hooks' => array( 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'items' => array( - 'type' => 'string', + 'type' => 'string', ), ), - 'delivery_url' => array( + 'delivery_url' => array( 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'secret' => array( + 'secret' => array( 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), 'type' => 'string', 'context' => array( 'edit' ), ), - 'date_created' => array( + 'date_created' => array( 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'date_modified' => array( + 'date_created_gmt' => array( + 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), ), ); diff --git a/src/RestApi/Version4/class-wc-rest-webhook-deliveries-v1-controller.php b/src/RestApi/Version4/class-wc-rest-webhook-deliveries-v1-controller.php deleted file mode 100644 index a3b2cd81981..00000000000 --- a/src/RestApi/Version4/class-wc-rest-webhook-deliveries-v1-controller.php +++ /dev/null @@ -1,314 +0,0 @@ -/deliveries endpoint. - * - * @author WooThemes - * @category API - * @package WooCommerce/RestApi - * @since 3.0.0 - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * REST API Webhook Deliveries controller class. - * - * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. - * @package WooCommerce/RestApi - * @extends WC_REST_Controller - */ -class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'webhooks/(?P[\d]+)/deliveries'; - - /** - * Register the routes for webhook deliveries. - */ - public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'webhook_id' => array( - 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), - 'type' => 'integer', - ), - ), - 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( - 'webhook_id' => array( - 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read taxes. - * - * @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( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a tax. - * - * @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( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all webhook deliveries. - * - * @param WP_REST_Request $request - * - * @return array|WP_Error - */ - public function get_items( $request ) { - $webhook = wc_get_webhook( (int) $request['webhook_id'] ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $logs = array(); - $data = array(); - foreach ( $logs as $log ) { - $delivery = $this->prepare_item_for_response( (object) $log, $request ); - $delivery = $this->prepare_response_for_collection( $delivery ); - $data[] = $delivery; - } - - return rest_ensure_response( $data ); - } - - /** - * Get a single webhook delivery. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $webhook = wc_get_webhook( (int) $request['webhook_id'] ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $log = array(); - - if ( empty( $id ) || empty( $log ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $delivery = $this->prepare_item_for_response( (object) $log, $request ); - $response = rest_ensure_response( $delivery ); - - return $response; - } - - /** - * Prepare a single webhook delivery output for response. - * - * @param stdClass $log Delivery log object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $log, $request ) { - $data = (array) $log; - $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( $log ) ); - - /** - * Filter webhook delivery object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $log Delivery log object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request ); - } - - /** - * Prepare links for the request. - * - * @param stdClass $log Delivery log object. - * @return array Links for the given webhook delivery. - */ - protected function prepare_links( $log ) { - $webhook_id = (int) $log->request_headers['X-WC-Webhook-ID']; - $base = str_replace( '(?P[\d]+)', $webhook_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $log->id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/webhooks/%d', $this->namespace, $webhook_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Webhook's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'webhook_delivery', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'duration' => array( - 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'summary' => array( - 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'request_url' => array( - 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'request_headers' => array( - 'description' => __( 'Request headers.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'request_body' => array( - 'description' => __( 'Request body.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_code' => array( - 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_message' => array( - 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_headers' => array( - 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'response_body' => array( - 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - '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() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} From 35dfc10dc739cfa433babf3d9d3fe52319c9a5da Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:29:39 +0100 Subject: [PATCH 033/440] Moving remaining classes to refactor --- ...min-rest-reports-categories-controller.php | 0 ...class-wc-admin-rest-reports-controller.php | 0 ...-admin-rest-reports-coupons-controller.php | 0 ...-rest-reports-coupons-stats-controller.php | 0 ...dmin-rest-reports-customers-controller.php | 0 ...est-reports-customers-stats-controller.php | 0 ...dmin-rest-reports-downloads-controller.php | 0 ...est-reports-downloads-files-controller.php | 0 ...est-reports-downloads-stats-controller.php | 0 ...c-admin-rest-reports-import-controller.php | 0 ...c-admin-rest-reports-orders-controller.php | 0 ...n-rest-reports-orders-stats-controller.php | 0 ...orts-performance-indicators-controller.php | 0 ...admin-rest-reports-products-controller.php | 0 ...rest-reports-products-stats-controller.php | 0 ...-rest-reports-revenue-stats-controller.php | 0 ...wc-admin-rest-reports-stock-controller.php | 0 ...in-rest-reports-stock-stats-controller.php | 0 ...wc-admin-rest-reports-taxes-controller.php | 0 ...in-rest-reports-taxes-stats-controller.php | 0 ...min-rest-reports-variations-controller.php | 0 .../class-wc-admin-rest-data-controller.php | 0 ...c-admin-rest-data-countries-controller.php | 0 ...dmin-rest-data-download-ips-controller.php | 0 ...-wc-admin-rest-leaderboards-controller.php | 0 ...dmin-rest-onboarding-levels-controller.php | 0 ...min-rest-onboarding-plugins-controller.php | 0 ...min-rest-onboarding-profile-controller.php | 0 ...min-rest-product-variations-controller.php | 0 ...-admin-rest-setting-options-controller.php | 0 .../Version4/class-wc-rest-controller.php | 467 +++++++ .../class-wc-rest-crud-controller.php | 627 +++++++++ ...ass-wc-rest-data-continents-controller.php | 357 +++++ .../class-wc-rest-data-controller.php | 184 +++ ...lass-wc-rest-data-countries-controller.php | 240 ++++ ...ass-wc-rest-data-currencies-controller.php | 221 +++ ...lass-wc-rest-network-orders-controller.php | 27 + ...s-wc-rest-network-orders-v2-controller.php | 174 +++ ...ss-wc-rest-payment-gateways-controller.php | 226 ++++ ...wc-rest-payment-gateways-v2-controller.php | 466 +++++++ .../class-wc-rest-posts-controller.php | 723 ++++++++++ ...-wc-rest-product-variations-controller.php | 860 ++++++++++++ ...-rest-product-variations-v2-controller.php | 1002 ++++++++++++++ ...-rest-report-coupons-totals-controller.php | 143 ++ ...est-report-customers-totals-controller.php | 154 +++ ...c-rest-report-orders-totals-controller.php | 127 ++ ...rest-report-products-totals-controller.php | 133 ++ ...-rest-report-reviews-totals-controller.php | 132 ++ ...ass-wc-rest-setting-options-controller.php | 250 ++++ ...-wc-rest-setting-options-v2-controller.php | 581 ++++++++ .../class-wc-rest-settings-controller.php | 112 ++ .../class-wc-rest-settings-v2-controller.php | 232 ++++ ...ss-wc-rest-shipping-methods-controller.php | 27 + ...wc-rest-shipping-methods-v2-controller.php | 231 ++++ ...est-shipping-zone-locations-controller.php | 27 + ...-shipping-zone-locations-v2-controller.php | 190 +++ ...-rest-shipping-zone-methods-controller.php | 27 + ...st-shipping-zone-methods-v2-controller.php | 541 ++++++++ ...wc-rest-shipping-zones-controller-base.php | 125 ++ ...lass-wc-rest-shipping-zones-controller.php | 27 + ...s-wc-rest-shipping-zones-v2-controller.php | 304 +++++ ...class-wc-rest-system-status-controller.php | 27 + ...wc-rest-system-status-tools-controller.php | 27 + ...rest-system-status-tools-v2-controller.php | 563 ++++++++ ...ss-wc-rest-system-status-v2-controller.php | 1180 +++++++++++++++++ .../class-wc-rest-terms-controller.php | 806 +++++++++++ ...s-wc-admin-rest-admin-notes-controller.php | 484 ------- ...class-wc-admin-rest-coupons-controller.php | 93 -- ...ass-wc-admin-rest-customers-controller.php | 50 - .../class-wc-admin-rest-orders-controller.php | 75 -- ...min-rest-product-categories-controller.php | 26 - ...-admin-rest-product-reviews-controller.php | 55 - ...lass-wc-admin-rest-products-controller.php | 189 --- .../class-wc-admin-rest-taxes-controller.php | 159 --- 74 files changed, 11540 insertions(+), 1131 deletions(-) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-categories-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-coupons-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-coupons-stats-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-customers-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-customers-stats-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-downloads-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-downloads-files-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-downloads-stats-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-import-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-orders-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-orders-stats-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-performance-indicators-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-products-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-products-stats-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-revenue-stats-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-stock-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-stock-stats-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-taxes-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-taxes-stats-controller.php (100%) rename src/RestApi/{Version4_temp => Version4/Controllers/Reports}/class-wc-admin-rest-reports-variations-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-data-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-data-countries-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-data-download-ips-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-leaderboards-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-onboarding-levels-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-onboarding-plugins-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-onboarding-profile-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-product-variations-controller.php (100%) rename src/RestApi/{Version4_temp => Version4}/class-wc-admin-rest-setting-options-controller.php (100%) create mode 100644 src/RestApi/Version4/class-wc-rest-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-crud-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-data-continents-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-data-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-data-countries-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-data-currencies-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-network-orders-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-network-orders-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-payment-gateways-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-payment-gateways-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-posts-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-product-variations-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-product-variations-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-report-coupons-totals-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-report-customers-totals-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-report-orders-totals-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-report-products-totals-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-report-reviews-totals-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-setting-options-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-setting-options-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-settings-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-settings-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-methods-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-methods-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zone-locations-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zone-locations-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zone-methods-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zone-methods-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zones-controller-base.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zones-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zones-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-system-status-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-system-status-tools-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-system-status-tools-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-system-status-v2-controller.php create mode 100644 src/RestApi/Version4/class-wc-rest-terms-controller.php delete mode 100644 src/RestApi/Version4_temp/class-wc-admin-rest-admin-notes-controller.php delete mode 100644 src/RestApi/Version4_temp/class-wc-admin-rest-coupons-controller.php delete mode 100644 src/RestApi/Version4_temp/class-wc-admin-rest-customers-controller.php delete mode 100644 src/RestApi/Version4_temp/class-wc-admin-rest-orders-controller.php delete mode 100644 src/RestApi/Version4_temp/class-wc-admin-rest-product-categories-controller.php delete mode 100644 src/RestApi/Version4_temp/class-wc-admin-rest-product-reviews-controller.php delete mode 100644 src/RestApi/Version4_temp/class-wc-admin-rest-products-controller.php delete mode 100644 src/RestApi/Version4_temp/class-wc-admin-rest-taxes-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-categories-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-categories-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-coupons-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-coupons-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-coupons-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-coupons-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-customers-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-customers-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-customers-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-customers-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-files-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-files-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-files-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-files-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-downloads-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-import-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-import-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-orders-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-orders-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-orders-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-orders-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-performance-indicators-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-performance-indicators-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-products-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-products-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-products-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-products-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-revenue-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-revenue-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-stock-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-stock-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-stock-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-stock-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-taxes-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-taxes-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-taxes-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-taxes-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-reports-variations-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-reports-variations-controller.php rename to src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-data-controller.php b/src/RestApi/Version4/class-wc-admin-rest-data-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-data-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-data-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-data-countries-controller.php b/src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-data-countries-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-data-download-ips-controller.php b/src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-data-download-ips-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-leaderboards-controller.php b/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-leaderboards-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-levels-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-levels-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-plugins-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-plugins-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-profile-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-onboarding-profile-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-product-variations-controller.php b/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-product-variations-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-setting-options-controller.php b/src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php similarity index 100% rename from src/RestApi/Version4_temp/class-wc-admin-rest-setting-options-controller.php rename to src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php diff --git a/src/RestApi/Version4/class-wc-rest-controller.php b/src/RestApi/Version4/class-wc-rest-controller.php new file mode 100644 index 00000000000..e0ff5c4732c --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-controller.php @@ -0,0 +1,467 @@ + + * + * NOTE THAT ONLY CODE RELEVANT FOR MOST ENDPOINTS SHOULD BE INCLUDED INTO THIS CLASS. + * If necessary extend this class and create new abstract classes like `WC_REST_CRUD_Controller` or `WC_REST_Terms_Controller`. + * + * @class WC_REST_Controller + * @package WooCommerce/RestApi + * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * Abstract Rest Controller Class + * + * @package WooCommerce/RestApi + * @extends WP_REST_Controller + * @version 2.6.0 + */ +abstract class WC_REST_Controller extends WP_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = ''; + + /** + * Add the schema from additional fields to an schema array. + * + * The type of object is inferred from the passed schema. + * + * @param array $schema Schema array. + * + * @return array + */ + protected function add_additional_fields_schema( $schema ) { + if ( empty( $schema['title'] ) ) { + return $schema; + } + + /** + * Can't use $this->get_object_type otherwise we cause an inf loop. + */ + $object_type = $schema['title']; + + $additional_fields = $this->get_additional_fields( $object_type ); + + foreach ( $additional_fields as $field_name => $field_options ) { + if ( ! $field_options['schema'] ) { + continue; + } + + $schema['properties'][ $field_name ] = $field_options['schema']; + } + + $schema['properties'] = apply_filters( 'woocommerce_rest_' . $object_type . '_schema', $schema['properties'] ); + + return $schema; + } + + /** + * Get normalized rest base. + * + * @return string + */ + protected function get_normalized_rest_base() { + return preg_replace( '/\(.*\)\//i', '', $this->rest_base ); + } + + /** + * Check batch limit. + * + * @param array $items Request items. + * @return bool|WP_Error + */ + protected function check_batch_limit( $items ) { + $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); + $total = 0; + + if ( ! empty( $items['create'] ) ) { + $total += count( $items['create'] ); + } + + if ( ! empty( $items['update'] ) ) { + $total += count( $items['update'] ); + } + + if ( ! empty( $items['delete'] ) ) { + $total += count( $items['delete'] ); + } + + if ( $total > $limit ) { + /* translators: %s: items limit */ + return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); + } + + return true; + } + + /** + * Bulk create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + /** + * REST Server + * + * @var WP_REST_Server $wp_rest_server + */ + global $wp_rest_server; + + // Get the request params. + $items = array_filter( $request->get_params() ); + $response = array(); + + // Check batch limit. + $limit = $this->check_batch_limit( $items ); + if ( is_wp_error( $limit ) ) { + return $limit; + } + + if ( ! empty( $items['create'] ) ) { + foreach ( $items['create'] as $item ) { + $_item = new WP_REST_Request( 'POST' ); + + // Default parameters. + $defaults = array(); + $schema = $this->get_public_item_schema(); + foreach ( $schema['properties'] as $arg => $options ) { + if ( isset( $options['default'] ) ) { + $defaults[ $arg ] = $options['default']; + } + } + $_item->set_default_params( $defaults ); + + // Set request parameters. + $_item->set_body_params( $item ); + $_response = $this->create_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['create'][] = array( + 'id' => 0, + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['create'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + if ( ! empty( $items['update'] ) ) { + foreach ( $items['update'] as $item ) { + $_item = new WP_REST_Request( 'PUT' ); + $_item->set_body_params( $item ); + $_response = $this->update_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['update'][] = array( + 'id' => $item['id'], + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['update'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + if ( ! empty( $items['delete'] ) ) { + foreach ( $items['delete'] as $id ) { + $id = (int) $id; + + if ( 0 === $id ) { + continue; + } + + $_item = new WP_REST_Request( 'DELETE' ); + $_item->set_query_params( + array( + 'id' => $id, + 'force' => true, + ) + ); + $_response = $this->delete_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['delete'][] = array( + 'id' => $id, + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['delete'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + return $response; + } + + /** + * Validate a text value for a text based setting. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string + */ + public function validate_setting_text_field( $value, $setting ) { + $value = is_null( $value ) ? '' : $value; + return wp_kses_post( trim( stripslashes( $value ) ) ); + } + + /** + * Validate select based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_select_field( $value, $setting ) { + if ( array_key_exists( $value, $setting['options'] ) ) { + return $value; + } else { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + /** + * Validate multiselect based settings. + * + * @since 3.0.0 + * @param array $values Values. + * @param array $setting Setting. + * @return array|WP_Error + */ + public function validate_setting_multiselect_field( $values, $setting ) { + if ( empty( $values ) ) { + return array(); + } + + if ( ! is_array( $values ) ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $final_values = array(); + foreach ( $values as $value ) { + if ( array_key_exists( $value, $setting['options'] ) ) { + $final_values[] = $value; + } + } + + return $final_values; + } + + /** + * Validate image_width based settings. + * + * @since 3.0.0 + * @param array $values Values. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_image_width_field( $values, $setting ) { + if ( ! is_array( $values ) ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $current = $setting['value']; + if ( isset( $values['width'] ) ) { + $current['width'] = intval( $values['width'] ); + } + if ( isset( $values['height'] ) ) { + $current['height'] = intval( $values['height'] ); + } + if ( isset( $values['crop'] ) ) { + $current['crop'] = (bool) $values['crop']; + } + return $current; + } + + /** + * Validate radio based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_radio_field( $value, $setting ) { + return $this->validate_setting_select_field( $value, $setting ); + } + + /** + * Validate checkbox based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_checkbox_field( $value, $setting ) { + if ( in_array( $value, array( 'yes', 'no' ) ) ) { + return $value; + } elseif ( empty( $value ) ) { + $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; + return $value; + } else { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + /** + * Validate textarea based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string + */ + public function validate_setting_textarea_field( $value, $setting ) { + $value = is_null( $value ) ? '' : $value; + return wp_kses( + trim( stripslashes( $value ) ), + array_merge( + array( + 'iframe' => array( + 'src' => true, + 'style' => true, + 'id' => true, + 'class' => true, + ), + ), + wp_kses_allowed_html( 'post' ) + ) + ); + } + + /** + * Add meta query. + * + * @since 3.0.0 + * @param array $args Query args. + * @param array $meta_query Meta query. + * @return array + */ + protected function add_meta_query( $args, $meta_query ) { + if ( empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); + } + + $args['meta_query'][] = $meta_query; + + return $args['meta_query']; + } + + /** + * Get the batch schema, conforming to JSON Schema. + * + * @return array + */ + public function get_public_batch_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'batch', + 'type' => 'object', + 'properties' => array( + 'create' => array( + 'description' => __( 'List of created resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + ), + ), + 'update' => array( + 'description' => __( 'List of updated resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + ), + ), + 'delete' => array( + 'description' => __( 'List of delete resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + ), + ), + ); + + return $schema; + } + + /** + * Gets an array of fields to be included on the response. + * Included fields are based on item schema and `_fields=` request argument. + * Introduced to support WordPress 4.9.6 changes. + * + * @since 3.5.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Fields to be included in the response. + */ + public function get_fields_for_response( $request ) { + $schema = $this->get_item_schema(); + $fields = isset( $schema['properties'] ) ? array_keys( $schema['properties'] ) : array(); + + $additional_fields = $this->get_additional_fields(); + foreach ( $additional_fields as $field_name => $field_options ) { + // For back-compat, include any field with an empty schema + // because it won't be present in $this->get_item_schema(). + if ( is_null( $field_options['schema'] ) ) { + $fields[] = $field_name; + } + } + + if ( ! isset( $request['_fields'] ) ) { + return $fields; + } + $requested_fields = is_array( $request['_fields'] ) ? $request['_fields'] : preg_split( '/[\s,]+/', $request['_fields'] ); + if ( 0 === count( $requested_fields ) ) { + return $fields; + } + // Trim off outside whitespace from the comma delimited list. + $requested_fields = array_map( 'trim', $requested_fields ); + // Always persist 'id', because it can be needed for add_additional_fields_to_object(). + if ( in_array( 'id', $fields, true ) ) { + $requested_fields[] = 'id'; + } + return array_intersect( $fields, $requested_fields ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-crud-controller.php b/src/RestApi/Version4/class-wc-rest-crud-controller.php new file mode 100644 index 00000000000..6953ee2cb52 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-crud-controller.php @@ -0,0 +1,627 @@ + 405 ) ); + } + + /** + * Check if a given request has access to read an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get object permalink. + * + * @param object $object Object. + * @return string + */ + protected function get_permalink( $object ) { + return ''; + } + + /** + * Prepares the object for the REST response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. + */ + protected function prepare_object_for_response( $object, $request ) { + // translators: %s: Class method name. + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + */ + protected function prepare_object_for_database( $request, $creating = false ) { + // translators: %s: Class method name. + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_object_for_response( $object, $request ); + $response = rest_ensure_response( $data ); + + if ( $this->public ) { + $response->link_header( 'alternate', $this->get_permalink( $object ), array( 'type' => 'text/html' ) ); + } + + return $response; + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + $object->save(); + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $object = $this->save_object( $request, true ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + try { + $this->update_additional_fields_for_object( $object, $request ); + } catch ( WC_Data_Exception $e ) { + $object->delete(); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + $object->delete(); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + /** + * Fires after a single object is created or updated via the REST API. + * + * @param WC_Data $object Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating object, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ) ); + + return $response; + } + + /** + * Update a single post. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $object = $this->save_object( $request, false ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + try { + $this->update_additional_fields_for_object( $object, $request ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + /** + * Fires after a single object is created or updated via the REST API. + * + * @param WC_Data $object Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating object, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + return rest_ensure_response( $response ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = array(); + $args['offset'] = $request['offset']; + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['paged'] = $request['page']; + $args['post__in'] = $request['include']; + $args['post__not_in'] = $request['exclude']; + $args['posts_per_page'] = $request['per_page']; + $args['name'] = $request['slug']; + $args['post_parent__in'] = $request['parent']; + $args['post_parent__not_in'] = $request['parent_exclude']; + $args['s'] = $request['search']; + + if ( 'date' === $args['orderby'] ) { + $args['orderby'] = 'date ID'; + } + + $args['date_query'] = array(); + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $request['before'] ) ) { + $args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $request['after'] ) ) { + $args['date_query'][0]['after'] = $request['after']; + } + + // Force the post_type argument, since it's not a user input variable. + $args['post_type'] = $this->post_type; + + /** + * 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_{$this->post_type}_object_query", $args, $request ); + + return $this->prepare_items_query( $args, $request ); + } + + /** + * Get objects. + * + * @since 3.0.0 + * @param array $query_args Query args. + * @return array + */ + protected function get_objects( $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( array( $this, 'get_object' ), $result ), + 'total' => (int) $total_posts, + 'pages' => (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ), + ); + } + + /** + * Get a collection of posts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $query_args = $this->prepare_objects_query( $request ); + $query_results = $this->get_objects( $query_args ); + + $objects = array(); + foreach ( $query_results['objects'] as $object ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { + continue; + } + + $data = $this->prepare_object_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 = $this->rest_base; + $attrib_prefix = '(?P<'; + if ( strpos( $base, $attrib_prefix ) !== false ) { + $attrib_names = array(); + preg_match( '/\(\?P<[^>]+>.*\)/', $base, $attrib_names, PREG_OFFSET_CAPTURE ); + foreach ( $attrib_names as $attrib_name_match ) { + $beginning_offset = strlen( $attrib_prefix ); + $attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] ); + $attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset ); + if ( isset( $request[ $attrib_name ] ) ) { + $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); + } + } + } + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $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; + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $object->delete( true ); + $result = 0 === $object->get_id(); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + $object->delete(); + $result = 'trash' === $object->get_status(); + } + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single object is deleted or trashed via the REST API. + * + * @param WC_Data $object The deleted or trashed object. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = array(); + $params['context'] = $this->get_context_param(); + $params['context']['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['search'] = array( + 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + '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['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' => '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', + 'id', + 'include', + 'title', + 'slug', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + if ( $this->hierarchical ) { + $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(), + ); + } + + /** + * Filter collection parameters for the posts controller. + * + * The dynamic part of the filter `$this->post_type` refers to the post + * type slug for the controller. + * + * This filter registers the collection parameter, but does not map the + * collection parameter to an internal WP_Query parameter. Use the + * `rest_{$this->post_type}_query` filter to set WP_Query parameters. + * + * @param array $query_params JSON Schema-formatted collection parameters. + * @param WP_Post_Type $post_type Post type object. + */ + return apply_filters( "rest_{$this->post_type}_collection_params", $params, $this->post_type ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-data-continents-controller.php b/src/RestApi/Version4/class-wc-rest-data-continents-controller.php new file mode 100644 index 00000000000..ccf64086b3f --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-data-continents-controller.php @@ -0,0 +1,357 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => array( + 'continent' => array( + 'description' => __( '2 character continent code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Return the list of countries and states for a given continent. + * + * @since 3.5.0 + * @param string $continent_code Continent code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_continent( $continent_code = false, $request ) { + $continents = WC()->countries->get_continents(); + $countries = WC()->countries->get_countries(); + $states = WC()->countries->get_states(); + $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php'; + $data = array(); + + if ( ! array_key_exists( $continent_code, $continents ) ) { + return false; + } + + $continent_list = $continents[ $continent_code ]; + + $continent = array( + 'code' => $continent_code, + 'name' => $continent_list['name'], + ); + + $local_countries = array(); + foreach ( $continent_list['countries'] as $country_code ) { + if ( isset( $countries[ $country_code ] ) ) { + $country = array( + 'code' => $country_code, + 'name' => $countries[ $country_code ], + ); + + // If we have detailed locale information include that in the response. + if ( array_key_exists( $country_code, $locale_info ) ) { + // Defensive programming against unexpected changes in locale-info.php. + $country_data = wp_parse_args( + $locale_info[ $country_code ], array( + 'currency_code' => 'USD', + 'currency_pos' => 'left', + 'decimal_sep' => '.', + 'dimension_unit' => 'in', + 'num_decimals' => 2, + 'thousand_sep' => ',', + 'weight_unit' => 'lbs', + ) + ); + + $country = array_merge( $country, $country_data ); + } + + $local_states = array(); + if ( isset( $states[ $country_code ] ) ) { + foreach ( $states[ $country_code ] as $state_code => $state_name ) { + $local_states[] = array( + 'code' => $state_code, + 'name' => $state_name, + ); + } + } + $country['states'] = $local_states; + + // Allow only desired keys (e.g. filter out tax rates). + $allowed = array( + 'code', + 'currency_code', + 'currency_pos', + 'decimal_sep', + 'dimension_unit', + 'name', + 'num_decimals', + 'states', + 'thousand_sep', + 'weight_unit', + ); + $country = array_intersect_key( $country, array_flip( $allowed ) ); + + $local_countries[] = $country; + } + } + + $continent['countries'] = $local_countries; + return $continent; + } + + /** + * Return the list of states for all continents. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $continents = WC()->countries->get_continents(); + $data = array(); + + foreach ( array_keys( $continents ) as $continent_code ) { + $continent = $this->get_continent( $continent_code, $request ); + $response = $this->prepare_item_for_response( $continent, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return the list of locations for a given continent. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_continent( strtoupper( $request['location'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Prepare the data object for response. + * + * @since 3.5.0 + * @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 ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter the location list returned from the API. + * + * Allows modification of the loction data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param array $item The original list of continent(s), countries, and states. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_continent', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given continent. + */ + protected function prepare_links( $item ) { + $continent_code = strtolower( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $continent_code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + return $links; + } + + /** + * Get the location schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_continents', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( '2 character continent code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of continent.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'countries' => array( + 'type' => 'array', + 'description' => __( 'List of countries on this continent.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_code' => array( + 'type' => 'string', + 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_pos' => array( + 'type' => 'string', + 'description' => __( 'Currency symbol position for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'decimal_sep' => array( + 'type' => 'string', + 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'dimension_unit' => array( + 'type' => 'string', + 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'num_decimals' => array( + 'type' => 'integer', + 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'states' => array( + 'type' => 'array', + 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'State code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of state.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + 'thousand_sep' => array( + 'type' => 'string', + 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'weight_unit' => array( + 'type' => 'string', + 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-data-controller.php b/src/RestApi/Version4/class-wc-rest-data-controller.php new file mode 100644 index 00000000000..71c6dd9029a --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-data-controller.php @@ -0,0 +1,184 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to read site data. + * + * @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( 'settings', '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 site settings. + * + * @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( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Return the list of data resources. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $data = array(); + $resources = array( + array( + 'slug' => 'continents', + 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce' ), + ), + array( + 'slug' => 'countries', + 'description' => __( 'List of supported states in a given country.', 'woocommerce' ), + ), + array( + 'slug' => 'currencies', + 'description' => __( 'List of supported currencies.', 'woocommerce' ), + ), + ); + + foreach ( $resources as $resource ) { + $item = $this->prepare_item_for_response( (object) $resource, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a data resource object for serialization. + * + * @param stdClass $resource Resource data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $resource, $request ) { + $data = array( + 'slug' => $resource->slug, + 'description' => $resource->description, + ); + + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $resource ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given country. + */ + protected function prepare_links( $item ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->slug ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the data index schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_index', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'Data resource ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Data resource description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-data-countries-controller.php b/src/RestApi/Version4/class-wc-rest-data-countries-controller.php new file mode 100644 index 00000000000..ff659b67e09 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-data-countries-controller.php @@ -0,0 +1,240 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => array( + 'location' => array( + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a list of countries and states. + * + * @param string $country_code Country code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_country( $country_code = false, $request ) { + $countries = WC()->countries->get_countries(); + $states = WC()->countries->get_states(); + $data = array(); + + if ( ! array_key_exists( $country_code, $countries ) ) { + return false; + } + + $country = array( + 'code' => $country_code, + 'name' => $countries[ $country_code ], + ); + + $local_states = array(); + if ( isset( $states[ $country_code ] ) ) { + foreach ( $states[ $country_code ] as $state_code => $state_name ) { + $local_states[] = array( + 'code' => $state_code, + 'name' => $state_name, + ); + } + } + $country['states'] = $local_states; + return $country; + } + + /** + * Return the list of states for all countries. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $countries = WC()->countries->get_countries(); + $data = array(); + + foreach ( array_keys( $countries ) as $country_code ) { + $country = $this->get_country( $country_code, $request ); + $response = $this->prepare_item_for_response( $country, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return the list of states for a given country. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_country( strtoupper( $request['location'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Prepare the data object for response. + * + * @since 3.5.0 + * @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 ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter the states list for a country returned from the API. + * + * Allows modification of the loction data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param array $data The original country's states list. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_country', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given country. + */ + protected function prepare_links( $item ) { + $country_code = strtolower( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $country_code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + + /** + * Get the location schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_countries', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'states' => array( + 'type' => 'array', + 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'State code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of state.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-data-currencies-controller.php b/src/RestApi/Version4/class-wc-rest-data-currencies-controller.php new file mode 100644 index 00000000000..b5439695d0d --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-data-currencies-controller.php @@ -0,0 +1,221 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/current', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_current_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]{3})', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'location' => array( + 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get currency information. + * + * @param string $code Currency code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_currency( $code = false, $request ) { + $currencies = get_woocommerce_currencies(); + $data = array(); + + if ( ! array_key_exists( $code, $currencies ) ) { + return false; + } + + $currency = array( + 'code' => $code, + 'name' => $currencies[ $code ], + 'symbol' => get_woocommerce_currency_symbol( $code ), + ); + + return $currency; + } + + /** + * Return the list of currencies. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $currencies = get_woocommerce_currencies(); + foreach ( array_keys( $currencies ) as $code ) { + $currency = $this->get_currency( $code, $request ); + $response = $this->prepare_item_for_response( $currency, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return information for a specific currency. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Return information for the current site currency. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_current_item( $request ) { + $currency = get_option( 'woocommerce_currency' ); + return $this->prepare_item_for_response( $this->get_currency( $currency, $request ), $request ); + } + + /** + * 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 ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter currency returned from the API. + * + * @param WP_REST_Response $response The response object. + * @param array $item Currency data. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_currency', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given currency. + */ + protected function prepare_links( $item ) { + $code = strtoupper( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + + /** + * Get the currency schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_currencies', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of currency.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'symbol' => array( + 'type' => 'string', + 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-network-orders-controller.php b/src/RestApi/Version4/class-wc-rest-network-orders-controller.php new file mode 100644 index 00000000000..963a7cbec36 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-network-orders-controller.php @@ -0,0 +1,27 @@ +namespace, + '/' . $this->rest_base . '/network', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'network_orders' ), + 'permission_callback' => array( $this, 'network_orders_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + } + + /** + * Retrieves the item's schema for display / public consumption purposes. + * + * @return array Public item schema data. + */ + public function get_public_item_schema() { + $schema = parent::get_public_item_schema(); + + $schema['properties']['blog'] = array( + 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['edit_url'] = array( + 'description' => __( 'URL to edit the order', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['customer'][] = array( + 'description' => __( 'Name of the customer for the order', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['status_name'][] = array( + 'description' => __( 'Order Status', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['formatted_total'][] = array( + 'description' => __( 'Order total formatted for locale', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + + return $schema; + } + + /** + * Does a permissions check for the proper requested blog + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool $permission + */ + public function network_orders_permissions_check( $request ) { + $blog_id = $request->get_param( 'blog_id' ); + $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); + + switch_to_blog( $blog_id ); + + $permission = $this->get_items_permissions_check( $request ); + + restore_current_blog(); + + return $permission; + } + + /** + * Get a collection of orders from the requested blog id + * + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_REST_Response + */ + public function network_orders( $request ) { + $blog_id = $request->get_param( 'blog_id' ); + $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); + $active_plugins = get_blog_option( $blog_id, 'active_plugins', array() ); + $network_active_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + + $plugins = array_merge( $active_plugins, $network_active_plugins ); + $wc_active = false; + foreach ( $plugins as $plugin ) { + if ( substr_compare( $plugin, '/woocommerce.php', strlen( $plugin ) - strlen( '/woocommerce.php' ), strlen( '/woocommerce.php' ) ) === 0 ) { + $wc_active = true; + } + } + + // If WooCommerce not active for site, return an empty response. + if ( ! $wc_active ) { + $response = rest_ensure_response( array() ); + return $response; + } + + switch_to_blog( $blog_id ); + add_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); + $items = $this->get_items( $request ); + remove_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); + + foreach ( $items->data as &$current_order ) { + $order = wc_get_order( $current_order['id'] ); + + $current_order['blog'] = get_blog_details( get_current_blog_id() ); + $current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' ); + /* translators: 1: first name 2: last name */ + $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); + $current_order['status_name'] = wc_get_order_status_name( $order->get_status() ); + $current_order['formatted_total'] = $order->get_formatted_order_total(); + } + + restore_current_blog(); + + return $items; + } + + /** + * Filters the post statuses to on hold and processing for the network order query. + * + * @param array $args Query args. + * + * @return array + */ + public function network_orders_filter_args( $args ) { + $args['post_status'] = array( + 'wc-on-hold', + 'wc-processing', + ); + + return $args; + } +} diff --git a/src/RestApi/Version4/class-wc-rest-payment-gateways-controller.php b/src/RestApi/Version4/class-wc-rest-payment-gateways-controller.php new file mode 100644 index 00000000000..dc71790b6f7 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-payment-gateways-controller.php @@ -0,0 +1,226 @@ + $gateway->id, + 'title' => $gateway->title, + 'description' => $gateway->description, + 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', + 'enabled' => ( 'yes' === $gateway->enabled ), + 'method_title' => $gateway->get_method_title(), + 'method_description' => $gateway->get_method_description(), + 'method_supports' => $gateway->supports, + 'settings' => $this->get_settings( $gateway ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $gateway, $request ) ); + + /** + * Filter payment gateway objects returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); + } + + /** + * Return settings associated with this payment gateway. + * + * @param WC_Payment_Gateway $gateway Gateway instance. + * + * @return array + */ + public function get_settings( $gateway ) { + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type. + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + + // Ignore 'enabled' and 'description' which get included elsewhere. + if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { + continue; + } + + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Get the payment gateway schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'payment_gateway', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + ), + 'enabled' => array( + 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_title' => array( + 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_supports' => array( + 'description' => __( 'Supported features for this payment gateway.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'settings' => array( + 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-payment-gateways-v2-controller.php b/src/RestApi/Version4/class-wc-rest-payment-gateways-v2-controller.php new file mode 100644 index 00000000000..96eece65ae4 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-payment-gateways-v2-controller.php @@ -0,0 +1,466 @@ + + */ + public function register_routes() { + register_rest_route( + $this->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[\w-]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view payment gateways. + * + * @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( 'payment_gateways', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to read a payment gateway. + * + * @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( 'payment_gateways', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check whether a given request has permission to edit payment gateways. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get payment gateways. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $payment_gateways = WC()->payment_gateways->payment_gateways(); + $response = array(); + foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { + $payment_gateway->id = $payment_gateway_id; + $gateway = $this->prepare_item_for_response( $payment_gateway, $request ); + $gateway = $this->prepare_response_for_collection( $gateway ); + $response[] = $gateway; + } + return rest_ensure_response( $response ); + } + + /** + * Get a single payment gateway. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $gateway = $this->get_gateway( $request ); + + if ( is_null( $gateway ) ) { + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $gateway = $this->prepare_item_for_response( $gateway, $request ); + return rest_ensure_response( $gateway ); + } + + /** + * Update A Single Payment Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_item( $request ) { + $gateway = $this->get_gateway( $request ); + + if ( is_null( $gateway ) ) { + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Get settings. + $gateway->init_form_fields(); + $settings = $gateway->settings; + + // Update settings. + if ( isset( $request['settings'] ) ) { + $errors_found = false; + foreach ( $gateway->form_fields as $key => $field ) { + if ( isset( $request['settings'][ $key ] ) ) { + if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); + } else { + $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); + } + if ( is_wp_error( $value ) ) { + $errors_found = true; + break; + } + $settings[ $key ] = $value; + } + } + + if ( $errors_found ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update if this method is enabled or not. + if ( isset( $request['enabled'] ) ) { + $settings['enabled'] = wc_bool_to_string( $request['enabled'] ); + $gateway->enabled = $settings['enabled']; + } + + // Update title. + if ( isset( $request['title'] ) ) { + $settings['title'] = $request['title']; + $gateway->title = $settings['title']; + } + + // Update description. + if ( isset( $request['description'] ) ) { + $settings['description'] = $request['description']; + $gateway->description = $settings['description']; + } + + // Update options. + $gateway->settings = $settings; + update_option( $gateway->get_option_key(), apply_filters( 'woocommerce_gateway_' . $gateway->id . '_settings_values', $settings, $gateway ) ); + + // Update order. + if ( isset( $request['order'] ) ) { + $order = (array) get_option( 'woocommerce_gateway_order' ); + $order[ $gateway->id ] = $request['order']; + update_option( 'woocommerce_gateway_order', $order ); + $gateway->order = absint( $request['order'] ); + } + + $gateway = $this->prepare_item_for_response( $gateway, $request ); + return rest_ensure_response( $gateway ); + } + + /** + * Get a gateway based on the current request object. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|null + */ + public function get_gateway( $request ) { + $gateway = null; + $payment_gateways = WC()->payment_gateways->payment_gateways(); + foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { + if ( $request['id'] !== $payment_gateway_id ) { + continue; + } + $payment_gateway->id = $payment_gateway_id; + $gateway = $payment_gateway; + } + return $gateway; + } + + /** + * Prepare a payment gateway for response. + * + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $gateway, $request ) { + $order = (array) get_option( 'woocommerce_gateway_order' ); + $item = array( + 'id' => $gateway->id, + 'title' => $gateway->title, + 'description' => $gateway->description, + 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', + 'enabled' => ( 'yes' === $gateway->enabled ), + 'method_title' => $gateway->get_method_title(), + 'method_description' => $gateway->get_method_description(), + 'settings' => $this->get_settings( $gateway ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $gateway, $request ) ); + + /** + * Filter payment gateway objects returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); + } + + /** + * Return settings associated with this payment gateway. + * + * @param WC_Payment_Gateway $gateway Gateway data. + * + * @return array + */ + public function get_settings( $gateway ) { + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type. + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + // Ignore 'title' settings/fields -- they are UI only. + if ( 'title' === $field['type'] ) { + continue; + } + // Ignore 'enabled' and 'description' which get included elsewhere. + if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { + continue; + } + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Prepare links for the request. + * + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $gateway, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $gateway->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the payment gateway schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'payment_gateway', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + ), + 'enabled' => array( + 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_title' => array( + 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'settings' => array( + 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + +} diff --git a/src/RestApi/Version4/class-wc-rest-posts-controller.php b/src/RestApi/Version4/class-wc-rest-posts-controller.php new file mode 100644 index 00000000000..d5966551502 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-posts-controller.php @@ -0,0 +1,723 @@ +post_type, 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $post = get_post( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $data ); + + if ( $this->public ) { + $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) ); + } + + return $response; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + $post->post_type = $this->post_type; + $post_id = wp_insert_post( $post, true ); + + if ( is_wp_error( $post_id ) ) { + + if ( in_array( $post_id->get_error_code(), array( 'db_insert_error' ) ) ) { + $post_id->add_data( array( 'status' => 500 ) ); + } else { + $post_id->add_data( array( 'status' => 400 ) ); + } + return $post_id; + } + $post->ID = $post_id; + $post = get_post( $post_id ); + + $this->update_additional_fields_for_object( $post, $request ); + + // Add meta fields. + $meta_fields = $this->add_post_meta_fields( $post, $request ); + if ( is_wp_error( $meta_fields ) ) { + // Remove post. + $this->delete_post( $post ); + + return $meta_fields; + } + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post_id ) ) ); + + return $response; + } + + /** + * Add post meta fields. + * + * @param WP_Post $post Post Object. + * @param WP_REST_Request $request WP_REST_Request Object. + * @return bool|WP_Error + */ + protected function add_post_meta_fields( $post, $request ) { + return true; + } + + /** + * Delete post. + * + * @param WP_Post $post Post object. + */ + protected function delete_post( $post ) { + wp_delete_post( $post->ID, true ); + } + + /** + * Update a single post. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $post = get_post( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + // Convert the post object to an array, otherwise wp_update_post will expect non-escaped input. + $post_id = wp_update_post( (array) $post, true ); + if ( is_wp_error( $post_id ) ) { + if ( in_array( $post_id->get_error_code(), array( 'db_update_error' ) ) ) { + $post_id->add_data( array( 'status' => 500 ) ); + } else { + $post_id->add_data( array( 'status' => 400 ) ); + } + return $post_id; + } + + $post = get_post( $post_id ); + $this->update_additional_fields_for_object( $post, $request ); + + // Update meta fields. + $meta_fields = $this->update_post_meta_fields( $post, $request ); + if ( is_wp_error( $meta_fields ) ) { + return $meta_fields; + } + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + } + + /** + * Get a collection of posts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $args = array(); + $args['offset'] = $request['offset']; + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['paged'] = $request['page']; + $args['post__in'] = $request['include']; + $args['post__not_in'] = $request['exclude']; + $args['posts_per_page'] = $request['per_page']; + $args['name'] = $request['slug']; + $args['post_parent__in'] = $request['parent']; + $args['post_parent__not_in'] = $request['parent_exclude']; + $args['s'] = $request['search']; + + $args['date_query'] = array(); + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $request['before'] ) ) { + $args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $request['after'] ) ) { + $args['date_query'][0]['after'] = $request['after']; + } + + if ( 'wc/v1' === $this->namespace ) { + if ( is_array( $request['filter'] ) ) { + $args = array_merge( $args, $request['filter'] ); + unset( $args['filter'] ); + } + } + + // Force the post_type argument, since it's not a user input variable. + $args['post_type'] = $this->post_type; + + /** + * 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_{$this->post_type}_query", $args, $request ); + $query_args = $this->prepare_items_query( $args, $request ); + + $posts_query = new WP_Query(); + $query_result = $posts_query->query( $query_args ); + + $posts = array(); + foreach ( $query_result as $post ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { + continue; + } + + $data = $this->prepare_item_for_response( $post, $request ); + $posts[] = $this->prepare_response_for_collection( $data ); + } + + $page = (int) $query_args['paged']; + $total_posts = $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; + } + + $max_pages = ceil( $total_posts / (int) $query_args['posts_per_page'] ); + + $response = rest_ensure_response( $posts ); + $response->header( 'X-WP-Total', (int) $total_posts ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $request_params = $request->get_query_params(); + if ( ! empty( $request_params['filter'] ) ) { + // Normalize the pagination params. + unset( $request_params['filter']['posts_per_page'] ); + unset( $request_params['filter']['paged'] ); + } + $base = add_query_arg( $request_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; + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = (bool) $request['force']; + $post = get_post( $id ); + + if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0; + + /** + * Filter whether an item is trashable. + * + * Return false to disable trash support for the item. + * + * @param boolean $supports_trash Whether the item type support trashing. + * @param WP_Post $post The Post object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $result = wp_delete_post( $id, true ); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( 'trash' === $post->post_status ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + // (Note that internally this falls through to `wp_delete_post` if + // the trash is disabled.) + $result = wp_trash_post( $id ); + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param object $post The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $post, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Determine the allowed query_vars for a get_items() response and + * prepare for WP_Query. + * + * @param array $prepared_args Prepared arguments. + * @param WP_REST_Request $request Request object. + * @return array $query_args + */ + protected function prepare_items_query( $prepared_args = array(), $request = null ) { + + $valid_vars = array_flip( $this->get_allowed_query_vars() ); + $query_args = array(); + foreach ( $valid_vars as $var => $index ) { + if ( isset( $prepared_args[ $var ] ) ) { + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $var, refers to the query_var key. + * + * @param mixed $prepared_args[ $var ] The query_var value. + */ + $query_args[ $var ] = apply_filters( "woocommerce_rest_query_var-{$var}", $prepared_args[ $var ] ); + } + } + + $query_args['ignore_sticky_posts'] = true; + + if ( 'include' === $query_args['orderby'] ) { + $query_args['orderby'] = 'post__in'; + } elseif ( 'id' === $query_args['orderby'] ) { + $query_args['orderby'] = 'ID'; // ID must be capitalized. + } elseif ( 'slug' === $query_args['orderby'] ) { + $query_args['orderby'] = 'name'; + } + + return $query_args; + } + + /** + * Get all the WP Query vars that are allowed for the API request. + * + * @return array + */ + protected function get_allowed_query_vars() { + global $wp; + + /** + * Filter the publicly allowed query vars. + * + * Allows adjusting of the default query vars that are made public. + * + * @param array Array of allowed WP_Query query vars. + */ + $valid_vars = apply_filters( 'query_vars', $wp->public_query_vars ); + + $post_type_obj = get_post_type_object( $this->post_type ); + if ( current_user_can( $post_type_obj->cap->edit_posts ) ) { + /** + * Filter the allowed 'private' query vars for authorized users. + * + * If the user has the `edit_posts` capability, we also allow use of + * private query parameters, which are only undesirable on the + * frontend, but are safe for use in query strings. + * + * To disable anyway, use + * `add_filter( 'woocommerce_rest_private_query_vars', '__return_empty_array' );` + * + * @param array $private_query_vars Array of allowed query vars for authorized users. + * } + */ + $private = apply_filters( 'woocommerce_rest_private_query_vars', $wp->private_query_vars ); + $valid_vars = array_merge( $valid_vars, $private ); + } + // Define our own in addition to WP's normal vars. + $rest_valid = array( + 'date_query', + 'ignore_sticky_posts', + 'offset', + 'post__in', + 'post__not_in', + 'post_parent', + 'post_parent__in', + 'post_parent__not_in', + 'posts_per_page', + 'meta_query', + 'tax_query', + 'meta_key', + 'meta_value', + 'meta_compare', + 'meta_value_num', + ); + $valid_vars = array_merge( $valid_vars, $rest_valid ); + + /** + * Filter allowed query vars for the REST API. + * + * This filter allows you to add or remove query vars from the final allowed + * list for all requests, including unauthenticated ones. To alter the + * vars for editors only. + * + * @param array { + * Array of allowed WP_Query query vars. + * + * @param string $allowed_query_var The query var to allow. + * } + */ + $valid_vars = apply_filters( 'woocommerce_rest_query_vars', $valid_vars ); + + return $valid_vars; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $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['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' => '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', + 'id', + 'include', + 'title', + 'slug', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $post_type_obj = get_post_type_object( $this->post_type ); + + if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) { + $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(), + ); + } + + if ( 'wc/v1' === $this->namespace ) { + $params['filter'] = array( + 'type' => 'object', + 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce' ), + ); + } + + return $params; + } + + /** + * Update post meta fields. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return bool|WP_Error + */ + protected function update_post_meta_fields( $post, $request ) { + return true; + } +} diff --git a/src/RestApi/Version4/class-wc-rest-product-variations-controller.php b/src/RestApi/Version4/class-wc-rest-product-variations-controller.php new file mode 100644 index 00000000000..5b69656b0ab --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-product-variations-controller.php @@ -0,0 +1,860 @@ +/variations endpoints. + * + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API variations controller class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Product_Variations_V2_Controller + */ +class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; + + /** + * Prepare a single variation output for response. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = array( + 'id' => $object->get_id(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), + 'description' => wc_format_content( $object->get_description() ), + 'permalink' => $object->get_permalink(), + 'sku' => $object->get_sku(), + 'price' => $object->get_price(), + 'regular_price' => $object->get_regular_price(), + 'sale_price' => $object->get_sale_price(), + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), + 'on_sale' => $object->is_on_sale(), + 'status' => $object->get_status(), + 'purchasable' => $object->is_purchasable(), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => $this->get_downloads( $object ), + 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, + 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, + 'tax_status' => $object->get_tax_status(), + 'tax_class' => $object->get_tax_class(), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity(), + 'stock_status' => $object->get_stock_status(), + 'backorders' => $object->get_backorders(), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'weight' => $object->get_weight(), + 'dimensions' => array( + 'length' => $object->get_length(), + 'width' => $object->get_width(), + 'height' => $object->get_height(), + ), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id(), + 'image' => $this->get_image( $object ), + 'attributes' => $this->get_attributes( $object ), + 'menu_order' => $object->get_menu_order(), + 'meta_data' => $object->get_meta_data(), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare a single variation for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + if ( isset( $request['id'] ) ) { + $variation = wc_get_product( absint( $request['id'] ) ); + } else { + $variation = new WC_Product_Variation(); + } + + $variation->set_parent_id( absint( $request['product_id'] ) ); + + // Status. + if ( isset( $request['status'] ) ) { + $variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // SKU. + if ( isset( $request['sku'] ) ) { + $variation->set_sku( wc_clean( $request['sku'] ) ); + } + + // Thumbnail. + if ( isset( $request['image'] ) ) { + if ( is_array( $request['image'] ) ) { + $variation = $this->set_variation_image( $variation, $request['image'] ); + } else { + $variation->set_image_id( '' ); + } + } + + // Virtual variation. + if ( isset( $request['virtual'] ) ) { + $variation->set_virtual( $request['virtual'] ); + } + + // Downloadable variation. + if ( isset( $request['downloadable'] ) ) { + $variation->set_downloadable( $request['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $variation->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $variation->set_download_expiry( $request['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $request ); + + // Stock handling. + if ( isset( $request['manage_stock'] ) ) { + $variation->set_manage_stock( $request['manage_stock'] ); + } + + if ( isset( $request['stock_status'] ) ) { + $variation->set_stock_status( $request['stock_status'] ); + } + + if ( isset( $request['backorders'] ) ) { + $variation->set_backorders( $request['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $request['stock_quantity'] ) ) { + $variation->set_stock_quantity( $request['stock_quantity'] ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $variation->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $variation->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + + // Tax class. + if ( isset( $request['tax_class'] ) ) { + $variation->set_tax_class( $request['tax_class'] ); + } + + // Description. + if ( isset( $request['description'] ) ) { + $variation->set_description( wp_kses_post( $request['description'] ) ); + } + + // Update taxonomies. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + $parent = wc_get_product( $variation->get_parent_id() ); + + if ( ! $parent ) { + return new WP_Error( + // Translators: %d parent ID. + "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $variation->get_parent_id() ), array( + 'status' => 404, + ) + ); + } + + $parent_attributes = $parent->get_attributes(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + // Menu order. + if ( $request['menu_order'] ) { + $variation->set_menu_order( $request['menu_order'] ); + } + + // Meta data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $variation Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); + } + + /** + * Get the image for a product variation. + * + * @param WC_Product_Variation $variation Variation data. + * @return array + */ + protected function get_image( $variation ) { + if ( ! $variation->get_image_id() ) { + return; + } + + $attachment_id = $variation->get_image_id(); + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + return; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + return; + } + + if ( ! isset( $image ) ) { + return array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + } + + /** + * Set variation image. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product_Variation $variation Variation instance. + * @param array $image Image data. + * @return WC_Product_Variation + */ + protected function set_variation_image( $variation, $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $variation->get_id(), array( $image ) ) ) { + throw new WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $variation->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: attachment ID */ + throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $variation->set_image_id( $attachment_id ); + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + + return $variation; + } + + /** + * Get the Variation's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Variation description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Variation status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_keys( get_post_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); + + // Set post_status. + $args['post_status'] = $request['status']; + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product based on stock_status. + if ( ! empty( $request['stock_status'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_stock_status', + 'value' => $request['stock_status'], + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + $args['post_parent'] = $request['product_id']; + + return $args; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + unset( + $params['in_stock'], + $params['type'], + $params['featured'], + $params['category'], + $params['tag'], + $params['shipping_class'], + $params['attribute'], + $params['attribute_term'] + ); + + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/src/RestApi/Version4/class-wc-rest-product-variations-v2-controller.php b/src/RestApi/Version4/class-wc-rest-product-variations-v2-controller.php new file mode 100644 index 00000000000..d1fdb90e72f --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-product-variations-v2-controller.php @@ -0,0 +1,1002 @@ +/variations endpoints. + * + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API variations controller class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Products_V2_Controller + */ +class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/(?P[\d]+)/variations'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'product_variation'; + + /** + * Initialize product actions (parent). + */ + public function __construct() { + add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'add_product_id' ), 9, 2 ); + parent::__construct(); + } + + /** + * Register the routes for products. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_product( $id ); + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + // Check if variation belongs to the correct parent product. + if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Prepare a single variation output for response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = array( + 'id' => $object->get_id(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), + 'description' => wc_format_content( $object->get_description() ), + 'permalink' => $object->get_permalink(), + 'sku' => $object->get_sku(), + 'price' => $object->get_price(), + 'regular_price' => $object->get_regular_price(), + 'sale_price' => $object->get_sale_price(), + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), + 'on_sale' => $object->is_on_sale(), + 'visible' => $object->is_visible(), + 'purchasable' => $object->is_purchasable(), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => $this->get_downloads( $object ), + 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, + 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, + 'tax_status' => $object->get_tax_status(), + 'tax_class' => $object->get_tax_class(), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity(), + 'in_stock' => $object->is_in_stock(), + 'backorders' => $object->get_backorders(), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'weight' => $object->get_weight(), + 'dimensions' => array( + 'length' => $object->get_length(), + 'width' => $object->get_width(), + 'height' => $object->get_height(), + ), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id(), + 'image' => current( $this->get_images( $object ) ), + 'attributes' => $this->get_attributes( $object ), + 'menu_order' => $object->get_menu_order(), + 'meta_data' => $object->get_meta_data(), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + $args['post_parent'] = $request['product_id']; + + return $args; + } + + /** + * Prepare a single variation for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + if ( isset( $request['id'] ) ) { + $variation = wc_get_product( absint( $request['id'] ) ); + } else { + $variation = new WC_Product_Variation(); + } + + // Update parent ID just once. + if ( 0 === $variation->get_parent_id() ) { + $variation->set_parent_id( absint( $request['product_id'] ) ); + } + + // Status. + if ( isset( $request['visible'] ) ) { + $variation->set_status( false === $request['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $request['sku'] ) ) { + $variation->set_sku( wc_clean( $request['sku'] ) ); + } + + // Thumbnail. + if ( isset( $request['image'] ) ) { + if ( is_array( $request['image'] ) && ! empty( $request['image'] ) ) { + $image = $request['image']; + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->set_product_images( $variation, array( $image ) ); + } else { + $variation->set_image_id( '' ); + } + } + + // Virtual variation. + if ( isset( $request['virtual'] ) ) { + $variation->set_virtual( $request['virtual'] ); + } + + // Downloadable variation. + if ( isset( $request['downloadable'] ) ) { + $variation->set_downloadable( $request['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $variation->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $variation->set_download_expiry( $request['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $request ); + + // Stock handling. + if ( isset( $request['manage_stock'] ) ) { + if ( 'parent' === $request['manage_stock'] ) { + $variation->set_manage_stock( false ); // This just indicates the variation does not manage stock, but the parent does. + } else { + $variation->set_manage_stock( wc_string_to_bool( $request['manage_stock'] ) ); + } + } + + if ( isset( $request['in_stock'] ) ) { + $variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' ); + } + + if ( isset( $request['backorders'] ) ) { + $variation->set_backorders( $request['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $request['stock_quantity'] ) ) { + $variation->set_stock_quantity( $request['stock_quantity'] ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $variation->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $variation->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + + // Tax class. + if ( isset( $request['tax_class'] ) ) { + $variation->set_tax_class( $request['tax_class'] ); + } + + // Description. + if ( isset( $request['description'] ) ) { + $variation->set_description( wp_kses_post( $request['description'] ) ); + } + + // Update taxonomies. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + $parent = wc_get_product( $variation->get_parent_id() ); + $parent_attributes = $parent->get_attributes(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $raw_attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $raw_attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $raw_attribute_name ) { + continue; + } + + $attribute_name = sanitize_title( $raw_attribute_name ); + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $raw_attribute_name ); // @codingStandardsIgnoreLine + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + // Menu order. + if ( $request['menu_order'] ) { + $variation->set_menu_order( $request['menu_order'] ); + } + + // Meta data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $variation Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); + } + + /** + * Clear caches here so in sync with any new variations. + * + * @param WC_Data $object Object data. + */ + public function clear_transients( $object ) { + wc_delete_product_transients( $object->get_parent_id() ); + wp_cache_delete( 'product-' . $object->get_parent_id(), 'products' ); + } + + /** + * Delete a variation. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( + "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( + 'status' => 404, + ) + ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( + /* translators: %s: post type */ + "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( + 'status' => rest_authorization_required_code(), + ) + ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $object->delete( true ); + $result = 0 === $object->get_id(); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( + 'status' => 501, + ) + ); + } + + // Otherwise, only trash if we haven't already. + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( + 'status' => 410, + ) + ); + } + + $object->delete(); + $result = 'trash' === $object->get_status(); + } + } + + if ( ! $result ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( + 'status' => 500, + ) + ); + } + + // Delete parent product transients. + if ( 0 !== $object->get_parent_id() ) { + wc_delete_product_transients( $object->get_parent_id() ); + } + + /** + * Fires after a single object is deleted or trashed via the REST API. + * + * @param WC_Data $object The deleted or trashed object. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); + + return $response; + } + + /** + * Bulk create, update and delete items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + $items = array_filter( $request->get_params() ); + $params = $request->get_url_params(); + $product_id = $params['product_id']; + $body_params = array(); + + foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { + if ( ! empty( $items[ $batch_type ] ) ) { + $injected_items = array(); + foreach ( $items[ $batch_type ] as $item ) { + $injected_items[] = is_array( $item ) ? array_merge( + array( + 'product_id' => $product_id, + ), $item + ) : $item; + } + $body_params[ $batch_type ] = $injected_items; + } + } + + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( $body_params ); + + return parent::batch_items( $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $product_id = (int) $request['product_id']; + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), + ), + ); + return $links; + } + + /** + * Get the Variation's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Variation description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'visible' => array( + 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'mixed', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-report-coupons-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-coupons-totals-controller.php new file mode 100644 index 00000000000..d999b349703 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-report-coupons-totals-controller.php @@ -0,0 +1,143 @@ + $name ) { + $results = $wpdb->get_results( + $wpdb->prepare( " + SELECT count(meta_id) AS total + FROM $wpdb->postmeta + WHERE meta_key = 'discount_type' + AND meta_value = %s + ", $slug ) + ); + + $total = isset( $results[0] ) ? (int) $results[0]->total : 0; + + $data[] = array( + 'slug' => $slug, + 'name' => $name, + 'total' => $total, + ); + } + + set_transient( 'rest_api_coupons_type_count', $data, YEAR_IN_SECONDS ); + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_count', $response, $report, $request ); + } + + /** + * 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_coupon_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Coupon type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of coupons.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-report-customers-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-customers-totals-controller.php new file mode 100644 index 00000000000..c32b170e2db --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-report-customers-totals-controller.php @@ -0,0 +1,154 @@ + $total ) { + if ( in_array( $role, array( 'administrator', 'shop_manager' ), true ) ) { + continue; + } + + $total_customers += (int) $total; + } + + $customers_query = new WP_User_Query( + array( + 'role__not_in' => array( 'administrator', 'shop_manager' ), + 'number' => 0, + 'fields' => 'ID', + 'count_total' => true, + 'meta_query' => array( // WPCS: slow query ok. + array( + 'key' => 'paying_customer', + 'value' => 1, + 'compare' => '=', + ), + ), + ) + ); + + $total_paying = (int) $customers_query->get_total(); + + $data = array( + array( + 'slug' => 'paying', + 'name' => __( 'Paying customer', 'woocommerce' ), + 'total' => $total_paying, + ), + array( + 'slug' => 'non_paying', + 'name' => __( 'Non-paying customer', 'woocommerce' ), + 'total' => $total_customers - $total_paying, + ), + ); + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_count', $response, $report, $request ); + } + + /** + * 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_customer_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Customer type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of customers.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-report-orders-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-orders-totals-controller.php new file mode 100644 index 00000000000..3fdc4619351 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-report-orders-totals-controller.php @@ -0,0 +1,127 @@ + $name ) { + if ( ! isset( $totals->$slug ) ) { + continue; + } + + $data[] = array( + 'slug' => str_replace( 'wc-', '', $slug ), + 'name' => $name, + 'total' => (int) $totals->$slug, + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_count', $response, $report, $request ); + } + + /** + * 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_order_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Order status name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of orders.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-report-products-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-products-totals-controller.php new file mode 100644 index 00000000000..adb42b0d276 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-report-products-totals-controller.php @@ -0,0 +1,133 @@ + 'product_type', + 'hide_empty' => false, + ) + ); + $data = array(); + + foreach ( $terms as $product_type ) { + if ( ! isset( $types[ $product_type->name ] ) ) { + continue; + } + + $data[] = array( + 'slug' => $product_type->name, + 'name' => $types[ $product_type->name ], + 'total' => (int) $product_type->count, + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_count', $response, $report, $request ); + } + + /** + * 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_product_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-report-reviews-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-reviews-totals-controller.php new file mode 100644 index 00000000000..ef7ce098baa --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-report-reviews-totals-controller.php @@ -0,0 +1,132 @@ + true, + 'post_type' => 'product', + 'meta_key' => 'rating', // WPCS: slow query ok. + 'meta_value' => '', // WPCS: slow query ok. + ); + + for ( $i = 1; $i <= 5; $i++ ) { + $query_data['meta_value'] = $i; + + $data[] = array( + 'slug' => 'rated_' . $i . '_out_of_5', + /* translators: %s: average rating */ + 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $i ), + 'total' => (int) get_comments( $query_data ), + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $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_reviews_count', $response, $report, $request ); + } + + /** + * 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_review_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Review type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of reviews.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-setting-options-controller.php b/src/RestApi/Version4/class-wc-rest-setting-options-controller.php new file mode 100644 index 00000000000..41ae7ae86f7 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-setting-options-controller.php @@ -0,0 +1,250 @@ + 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + + if ( empty( $settings ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_settings = array(); + foreach ( $settings as $setting ) { + $option_key = $setting['option_key']; + $setting = $this->filter_setting( $setting ); + $default = isset( $setting['default'] ) ? $setting['default'] : ''; + // Get the option value. + if ( is_array( $option_key ) ) { + $option = get_option( $option_key[0] ); + $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; + } else { + $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); + $setting['value'] = $admin_setting_value; + } + + if ( 'multi_select_countries' === $setting['type'] ) { + $setting['options'] = WC()->countries->get_countries(); + $setting['type'] = 'multiselect'; + } elseif ( 'single_select_country' === $setting['type'] ) { + $setting['type'] = 'select'; + $setting['options'] = $this->get_countries_and_states(); + } elseif ( 'single_select_page' === $setting['type'] ) { + $pages = get_pages( + array( + 'sort_column' => 'menu_order', + 'sort_order' => 'ASC', + 'hierarchical' => 0, + ) + ); + $options = array(); + foreach ( $pages as $page ) { + $options[ $page->ID ] = ! empty( $page->post_title ) ? $page->post_title : '#' . $page->ID; + } + $setting['type'] = 'select'; + $setting['options'] = $options; + } + + $filtered_settings[] = $setting; + } + + return $filtered_settings; + } + + /** + * Returns a list of countries and states for use in the base location setting. + * + * @since 3.0.7 + * @return array Array of states and countries. + */ + private function get_countries_and_states() { + $countries = WC()->countries->get_countries(); + if ( ! $countries ) { + return array(); + } + $output = array(); + foreach ( $countries as $key => $value ) { + $states = WC()->countries->get_states( $key ); + + if ( $states ) { + foreach ( $states as $state_key => $state_value ) { + $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; + } + } else { + $output[ $key ] = $value; + } + } + return $output; + } + + /** + * Get the settings schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'group_id' => array( + 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'options' => array( + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-setting-options-v2-controller.php b/src/RestApi/Version4/class-wc-rest-setting-options-v2-controller.php new file mode 100644 index 00000000000..7136459b925 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-setting-options-v2-controller.php @@ -0,0 +1,581 @@ +[\w-]+)'; + + /** + * Register routes. + * + * @since 3.0.0 + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Return a single setting. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $setting = $this->get_setting( $request['group_id'], $request['id'] ); + + if ( is_wp_error( $setting ) ) { + return $setting; + } + + $response = $this->prepare_item_for_response( $setting, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Return all settings in a group. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $settings = $this->get_group_settings( $request['group_id'] ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + + $data = array(); + + foreach ( $settings as $setting_obj ) { + $setting = $this->prepare_item_for_response( $setting_obj, $request ); + $setting = $this->prepare_response_for_collection( $setting ); + if ( $this->is_setting_type_valid( $setting['type'] ) ) { + $data[] = $setting; + } + } + + return rest_ensure_response( $data ); + } + + /** + * Get all settings in a group. + * + * @since 3.0.0 + * @param string $group_id Group ID. + * @return array|WP_Error + */ + public function get_group_settings( $group_id ) { + if ( empty( $group_id ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); + + if ( empty( $settings ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_settings = array(); + foreach ( $settings as $setting ) { + $option_key = $setting['option_key']; + $setting = $this->filter_setting( $setting ); + $default = isset( $setting['default'] ) ? $setting['default'] : ''; + // Get the option value. + if ( is_array( $option_key ) ) { + $option = get_option( $option_key[0] ); + $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; + } else { + $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); + $setting['value'] = $admin_setting_value; + } + + if ( 'multi_select_countries' === $setting['type'] ) { + $setting['options'] = WC()->countries->get_countries(); + $setting['type'] = 'multiselect'; + } elseif ( 'single_select_country' === $setting['type'] ) { + $setting['type'] = 'select'; + $setting['options'] = $this->get_countries_and_states(); + } + + $filtered_settings[] = $setting; + } + + return $filtered_settings; + } + + /** + * Returns a list of countries and states for use in the base location setting. + * + * @since 3.0.7 + * @return array Array of states and countries. + */ + private function get_countries_and_states() { + $countries = WC()->countries->get_countries(); + if ( ! $countries ) { + return array(); + } + + $output = array(); + + foreach ( $countries as $key => $value ) { + $states = WC()->countries->get_states( $key ); + if ( $states ) { + foreach ( $states as $state_key => $state_value ) { + $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; + } + } else { + $output[ $key ] = $value; + } + } + + return $output; + } + + /** + * Get setting data. + * + * @since 3.0.0 + * @param string $group_id Group ID. + * @param string $setting_id Setting ID. + * @return stdClass|WP_Error + */ + public function get_setting( $group_id, $setting_id ) { + if ( empty( $setting_id ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $settings = $this->get_group_settings( $group_id ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); + + if ( empty( $array_key ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $setting = $settings[ $array_key[0] ]; + + if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return $setting; + } + + /** + * Bulk create, update and delete items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + // Get the request params. + $items = array_filter( $request->get_params() ); + + /* + * Since our batch settings update is group-specific and matches based on the route, + * we inject the URL parameters (containing group) into the batch items + */ + if ( ! empty( $items['update'] ) ) { + $to_update = array(); + foreach ( $items['update'] as $item ) { + $to_update[] = array_merge( $request->get_url_params(), $item ); + } + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( array( 'update' => $to_update ) ); + } + + return parent::batch_items( $request ); + } + + /** + * Update a single setting in a group. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $setting = $this->get_setting( $request['group_id'], $request['id'] ); + + if ( is_wp_error( $setting ) ) { + return $setting; + } + + if ( is_callable( array( $this, 'validate_setting_' . $setting['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $setting['type'] . '_field'}( $request['value'], $setting ); + } else { + $value = $this->validate_setting_text_field( $request['value'], $setting ); + } + + if ( is_wp_error( $value ) ) { + return $value; + } + + if ( is_array( $setting['option_key'] ) ) { + $setting['value'] = $value; + $option_key = $setting['option_key']; + $prev = get_option( $option_key[0] ); + $prev[ $option_key[1] ] = $request['value']; + update_option( $option_key[0], $prev ); + } else { + $update_data = array(); + $update_data[ $setting['option_key'] ] = $value; + $setting['value'] = $value; + WC_Admin_Settings::save_fields( array( $setting ), $update_data ); + } + + $response = $this->prepare_item_for_response( $setting, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Prepare a single setting object for response. + * + * @since 3.0.0 + * @param object $item Setting object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + unset( $item['option_key'] ); + $data = $this->filter_setting( $item ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, empty( $request['context'] ) ? 'view' : $request['context'] ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $data['id'], $request['group_id'] ) ); + return $response; + } + + /** + * Prepare links for the request. + * + * @since 3.0.0 + * @param string $setting_id Setting ID. + * @param string $group_id Group ID. + * @return array Links for the given setting. + */ + protected function prepare_links( $setting_id, $group_id ) { + $base = str_replace( '(?P[\w-]+)', $group_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $base, $setting_id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + ); + + return $links; + } + + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Makes sure the current user has access to WRITE the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + 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; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * + * @since 3.0.0 + * @param array $setting Settings. + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + if ( 'image_width' === $setting['type'] ) { + $setting = $this->cast_image_width( $setting ); + } + + return $setting; + } + + /** + * For image_width, Crop can return "0" instead of false -- so we want + * to make sure we return these consistently the same we accept them. + * + * @todo remove in 4.0 + * @since 3.0.0 + * @param array $setting Settings. + * @return array + */ + public function cast_image_width( $setting ) { + foreach ( array( 'default', 'value' ) as $key ) { + if ( isset( $setting[ $key ] ) ) { + $setting[ $key ]['width'] = intval( $setting[ $key ]['width'] ); + $setting[ $key ]['height'] = intval( $setting[ $key ]['height'] ); + $setting[ $key ]['crop'] = (bool) $setting[ $key ]['crop']; + } + } + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * + * @since 3.0.0 + * @param string $key Key to check. + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( + $key, array( + 'id', + 'label', + 'description', + 'default', + 'tip', + 'placeholder', + 'type', + 'options', + 'value', + 'option_key', + ) + ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * + * @since 3.0.0 + * @param string $type Type. + * @return bool + */ + public function is_setting_type_valid( $type ) { + return in_array( + $type, array( + 'text', // Validates with validate_setting_text_field. + 'email', // Validates with validate_setting_text_field. + 'number', // Validates with validate_setting_text_field. + 'color', // Validates with validate_setting_text_field. + 'password', // Validates with validate_setting_text_field. + 'textarea', // Validates with validate_setting_textarea_field. + 'select', // Validates with validate_setting_select_field. + 'multiselect', // Validates with validate_setting_multiselect_field. + 'radio', // Validates with validate_setting_radio_field (-> validate_setting_select_field). + 'checkbox', // Validates with validate_setting_checkbox_field. + 'image_width', // Validates with validate_setting_image_width_field. + 'thumbnail_cropping', // Validates with validate_setting_text_field. + ) + ); + } + + /** + * Get the settings schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox', 'thumbnail_cropping' ), + 'readonly' => true, + ), + 'options' => array( + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-settings-controller.php b/src/RestApi/Version4/class-wc-rest-settings-controller.php new file mode 100644 index 00000000000..869f725144f --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-settings-controller.php @@ -0,0 +1,112 @@ +namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_batch_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 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; + } + + /** + * Update a setting. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $options_controller = new WC_REST_Setting_Options_Controller(); + $response = $options_controller->update_item( $request ); + + return $response; + } + + /** + * Get the groups schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting_group', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-settings-v2-controller.php b/src/RestApi/Version4/class-wc-rest-settings-v2-controller.php new file mode 100644 index 00000000000..3b1dd0be705 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-settings-v2-controller.php @@ -0,0 +1,232 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get all settings groups items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $defaults = $this->group_defaults(); + $filtered_groups = array(); + foreach ( $groups as $group ) { + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $group['sub_groups'] = $sub_groups; + + $group = wp_parse_args( $group, $defaults ); + if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { + $group_obj = $this->filter_group( $group ); + $group_data = $this->prepare_item_for_response( $group_obj, $request ); + $group_data = $this->prepare_response_for_collection( $group_data ); + + $filtered_groups[] = $group_data; + } + } + + $response = rest_ensure_response( $filtered_groups ); + return $response; + } + + /** + * Prepare links for the request. + * + * @param string $group_id Group ID. + * @return array Links for the given group. + */ + protected function prepare_links( $group_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'options' => array( + 'href' => rest_url( trailingslashit( $base ) . $group_id ), + ), + ); + + return $links; + } + + /** + * Prepare a report sales object for serialization. + * + * @since 3.0.0 + * @param array $item Group object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item['id'] ) ); + + return $response; + } + + /** + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * + * @since 3.0.0 + * @param array $group Group. + * @return array + */ + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) + ); + } + + /** + * Callback for allowed keys for each group response. + * + * @since 3.0.0 + * @param string $key Key to check. + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * + * @since 3.0.0 + * @return array + */ + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + 'sub_groups' => array(), + ); + } + + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get the groups schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting_group', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-methods-controller.php b/src/RestApi/Version4/class-wc-rest-shipping-methods-controller.php new file mode 100644 index 00000000000..ca3c36d607c --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-shipping-methods-controller.php @@ -0,0 +1,27 @@ + + */ + public function register_routes() { + register_rest_route( + $this->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[\w-]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view shipping methods. + * + * @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( 'shipping_methods', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to read a shipping method. + * + * @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( 'shipping_methods', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get shipping methods. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $wc_shipping = WC_Shipping::instance(); + $response = array(); + foreach ( $wc_shipping->get_shipping_methods() as $id => $shipping_method ) { + $method = $this->prepare_item_for_response( $shipping_method, $request ); + $method = $this->prepare_response_for_collection( $method ); + $response[] = $method; + } + return rest_ensure_response( $response ); + } + + /** + * Get a single Shipping Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $wc_shipping = WC_Shipping::instance(); + $methods = $wc_shipping->get_shipping_methods(); + if ( empty( $methods[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $methods[ $request['id'] ]; + $response = $this->prepare_item_for_response( $method, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Prepare a shipping method for response. + * + * @param WC_Shipping_Method $method Shipping method object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $method, $request ) { + $data = array( + 'id' => $method->id, + 'title' => $method->method_title, + 'description' => $method->method_description, + ); + + $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( $method, $request ) ); + + /** + * Filter shipping methods object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Shipping_Method $method Shipping method object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_shipping_method', $response, $method, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Shipping_Method $method Shipping method object. + * @param WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $method, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $method->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the shipping method schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_method', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zone-locations-controller.php b/src/RestApi/Version4/class-wc-rest-shipping-zone-locations-controller.php new file mode 100644 index 00000000000..6211eccd561 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-shipping-zone-locations-controller.php @@ -0,0 +1,27 @@ +/locations endpoint. + * + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Locations class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Shipping_Zone_Locations_V2_Controller + */ +class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zone_Locations_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zone-locations-v2-controller.php b/src/RestApi/Version4/class-wc-rest-shipping-zone-locations-v2-controller.php new file mode 100644 index 00000000000..4fd40bc9060 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-shipping-zone-locations-v2-controller.php @@ -0,0 +1,190 @@ +/locations endpoint. + * + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Locations class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Shipping_Zones_Controller_Base + */ +class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { + + /** + * Register the routes for Shipping Zone Locations. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/locations', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get all Shipping Zone Locations. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $zone = $this->get_zone( (int) $request['id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $locations = $zone->get_zone_locations(); + $data = array(); + + foreach ( $locations as $location_obj ) { + $location = $this->prepare_item_for_response( $location_obj, $request ); + $location = $this->prepare_response_for_collection( $location ); + $data[] = $location; + } + + return rest_ensure_response( $data ); + } + + /** + * Update all Shipping Zone Locations. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_items( $request ) { + $zone = $this->get_zone( (int) $request['id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + if ( 0 === $zone->get_id() ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + } + + $raw_locations = $request->get_json_params(); + $locations = array(); + + foreach ( (array) $raw_locations as $raw_location ) { + if ( empty( $raw_location['code'] ) ) { + continue; + } + + $type = ! empty( $raw_location['type'] ) ? sanitize_text_field( $raw_location['type'] ) : 'country'; + + if ( ! in_array( $type, array( 'postcode', 'state', 'country', 'continent' ), true ) ) { + continue; + } + + $locations[] = array( + 'code' => sanitize_text_field( $raw_location['code'] ), + 'type' => sanitize_text_field( $type ), + ); + } + + $zone->set_locations( $locations ); + $zone->save(); + + return $this->get_items( $request ); + } + + /** + * Prepare the Shipping Zone Location for the REST response. + * + * @param array $item Shipping Zone Location. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $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( (int) $request['id'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @return array Links for the given Shipping Zone Location. + */ + protected function prepare_links( $zone_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + $links = array( + 'collection' => array( + 'href' => rest_url( $base . '/locations' ), + ), + 'describes' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zone Locations schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_location', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'description' => __( 'Shipping zone location code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'type' => array( + 'description' => __( 'Shipping zone location type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'country', + 'enum' => array( + 'postcode', + 'state', + 'country', + 'continent', + ), + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-controller.php b/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-controller.php new file mode 100644 index 00000000000..3ed5cf4e08b --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-controller.php @@ -0,0 +1,27 @@ +/methods endpoint. + * + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Methods class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Shipping_Zone_Methods_V2_Controller + */ +class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zone_Methods_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-v2-controller.php b/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-v2-controller.php new file mode 100644 index 00000000000..3cd52028ea6 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-v2-controller.php @@ -0,0 +1,541 @@ +/methods endpoint. + * + * @package WooCommerce/RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Methods class. + * + * @package WooCommerce/RestApi + * @extends WC_REST_Shipping_Zones_Controller_Base + */ +class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { + + /** + * Register the routes for Shipping Zone Methods. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods', array( + 'args' => array( + 'zone_id' => array( + 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'method_id' => array( + 'required' => true, + 'readonly' => false, + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', array( + 'args' => array( + 'zone_id' => array( + 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'type' => 'integer', + ), + 'instance_id' => array( + 'description' => __( 'Unique ID for the instance.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_items_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a single Shipping Zone Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $method, $request ); + + return rest_ensure_response( $data ); + } + + /** + * Get all Shipping Zone Methods. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $methods = $zone->get_shipping_methods(); + $data = array(); + + foreach ( $methods as $method_obj ) { + $method = $this->prepare_item_for_response( $method_obj, $request ); + $data[] = $method; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a new shipping zone method instance. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $method_id = $request['method_id']; + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = $zone->add_shipping_method( $method_id ); + $methods = $zone->get_shipping_methods(); + $method = false; + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $data = $this->prepare_item_for_response( $method, $request ); + return rest_ensure_response( $data ); + } + + /** + * Delete a shipping method instance. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $force = $request['force']; + + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $request->set_param( 'context', 'view' ); + $response = $this->prepare_item_for_response( $method, $request ); + + // Actually delete. + if ( $force ) { + $zone->delete_shipping_method( $instance_id ); + } else { + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + /** + * Fires after a product review is deleted via the REST API. + * + * @param object $method + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'rest_delete_product_review', $method, $response, $request ); + + return $response; + } + + /** + * Update A Single Shipping Zone Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $data = $this->prepare_item_for_response( $method, $request ); + return rest_ensure_response( $data ); + } + + /** + * Updates settings, order, and enabled status on create. + * + * @param int $instance_id Instance ID. + * @param WC_Shipping_Method $method Shipping method data. + * @param WP_REST_Request $request Request data. + * + * @return WC_Shipping_Method + */ + public function update_fields( $instance_id, $method, $request ) { + global $wpdb; + + // Update settings if present. + if ( isset( $request['settings'] ) ) { + $method->init_instance_settings(); + $instance_settings = $method->instance_settings; + $errors_found = false; + foreach ( $method->get_instance_form_fields() as $key => $field ) { + if ( isset( $request['settings'][ $key ] ) ) { + if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); + } else { + $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); + } + if ( is_wp_error( $value ) ) { + $errors_found = true; + break; + } + $instance_settings[ $key ] = $value; + } + } + + if ( $errors_found ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); + } + + // Update order. + if ( isset( $request['order'] ) ) { + $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'method_order' => absint( $request['order'] ) ), array( 'instance_id' => absint( $instance_id ) ) ); + $method->method_order = absint( $request['order'] ); + } + + // Update if this method is enabled or not. + if ( isset( $request['enabled'] ) ) { + if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'is_enabled' => $request['enabled'] ), array( 'instance_id' => absint( $instance_id ) ) ) ) { + do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method->id, $request['zone_id'], $request['enabled'] ); + $method->enabled = ( true === $request['enabled'] ? 'yes' : 'no' ); + } + } + + return $method; + } + + /** + * Prepare the Shipping Zone Method for the REST response. + * + * @param array $item Shipping Zone Method. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $method = array( + 'id' => $item->instance_id, + 'instance_id' => $item->instance_id, + 'title' => $item->instance_settings['title'], + 'order' => $item->method_order, + 'enabled' => ( 'yes' === $item->enabled ), + 'method_id' => $item->id, + 'method_title' => $item->method_title, + 'method_description' => $item->method_description, + 'settings' => $this->get_settings( $item ), + ); + + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $method, $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( $request['zone_id'], $item->instance_id ) ); + + $response = $this->prepare_response_for_collection( $response ); + + return $response; + } + + /** + * Return settings associated with this shipping zone method instance. + * + * @param WC_Shipping_Method $item Shipping method data. + * + * @return array + */ + public function get_settings( $item ) { + $item->init_instance_settings(); + $settings = array(); + foreach ( $item->get_instance_form_fields() as $id => $field ) { + $data = array( + 'id' => $id, + 'label' => $field['title'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => $item->instance_settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @param int $instance_id Given Shipping Zone Method Instance ID. + * @return array Links for the given Shipping Zone Method. + */ + protected function prepare_links( $zone_id, $instance_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + $links = array( + 'self' => array( + 'href' => rest_url( $base . '/methods/' . $instance_id ), + ), + 'collection' => array( + 'href' => rest_url( $base . '/methods' ), + ), + 'describes' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zone Methods schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_method', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'instance_id' => array( + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Shipping method customer facing title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order' => array( + 'description' => __( 'Shipping method sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'enabled' => array( + 'description' => __( 'Shipping method enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_title' => array( + 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'settings' => array( + 'description' => __( 'Shipping method settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zones-controller-base.php b/src/RestApi/Version4/class-wc-rest-shipping-zones-controller-base.php new file mode 100644 index 00000000000..7b8cc282f3b --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-shipping-zones-controller-base.php @@ -0,0 +1,125 @@ + 404 ) ); + } + + return $zone; + } + + /** + * Check whether a given request has permission to read Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check whether a given request has permission to edit Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check whether a given request has permission to delete Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + +} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zones-controller.php b/src/RestApi/Version4/class-wc-rest-shipping-zones-controller.php new file mode 100644 index 00000000000..778861bff5c --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-shipping-zones-controller.php @@ -0,0 +1,27 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Shipping zone name.', 'woocommerce' ), + ), + ) + ), + ), + '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_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_items_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a single Shipping Zone. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $data = $zone->get_data(); + $data = $this->prepare_item_for_response( $data, $request ); + $data = $this->prepare_response_for_collection( $data ); + + return rest_ensure_response( $data ); + } + + /** + * Get all Shipping Zones. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response + */ + public function get_items( $request ) { + $rest_of_the_world = WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); + + $zones = WC_Shipping_Zones::get_zones(); + array_unshift( $zones, $rest_of_the_world->get_data() ); + $data = array(); + + foreach ( $zones as $zone_obj ) { + $zone = $this->prepare_item_for_response( $zone_obj, $request ); + $zone = $this->prepare_response_for_collection( $zone ); + $data[] = $zone; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $zone = new WC_Shipping_Zone( null ); + + if ( ! is_null( $request->get_param( 'name' ) ) ) { + $zone->set_zone_name( $request->get_param( 'name' ) ); + } + + if ( ! is_null( $request->get_param( 'order' ) ) ) { + $zone->set_zone_order( $request->get_param( 'order' ) ); + } + + $zone->save(); + + if ( $zone->get_id() !== 0 ) { + $request->set_param( 'id', $zone->get_id() ); + $response = $this->get_item( $request ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); + return $response; + } else { + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); + } + } + + /** + * Update a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + if ( 0 === $zone->get_id() ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + } + + $zone_changed = false; + + if ( ! is_null( $request->get_param( 'name' ) ) ) { + $zone->set_zone_name( $request->get_param( 'name' ) ); + $zone_changed = true; + } + + if ( ! is_null( $request->get_param( 'order' ) ) ) { + $zone->set_zone_order( $request->get_param( 'order' ) ); + $zone_changed = true; + } + + if ( $zone_changed ) { + $zone->save(); + } + + return $this->get_item( $request ); + } + + /** + * Delete a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function delete_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $force = $request['force']; + + $response = $this->get_item( $request ); + + if ( $force ) { + $zone->delete(); + } else { + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + return $response; + } + + /** + * Prepare the Shipping Zone for the REST response. + * + * @param array $item Shipping Zone. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $data = array( + 'id' => (int) $item['id'], + 'name' => $item['zone_name'], + 'order' => (int) $item['zone_order'], + ); + + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $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( $data['id'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @return array Links for the given Shipping Zone. + */ + protected function prepare_links( $zone_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $zone_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + 'describedby' => array( + 'href' => rest_url( trailingslashit( $base ) . $zone_id . '/locations' ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zones schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Shipping zone name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'order' => array( + 'description' => __( 'Shipping zone order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-system-status-controller.php b/src/RestApi/Version4/class-wc-rest-system-status-controller.php new file mode 100644 index 00000000000..71a1ce085e4 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-system-status-controller.php @@ -0,0 +1,27 @@ +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[\w-]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + 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_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view system status tools. + * + * @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; + } + + /** + * Check whether a given request has permission to view a specific system status tool. + * + * @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 view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check whether a given request has permission to execute a specific system status tool. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * A list of available tools for use in the system status section. + * 'button' becomes 'action' in the API. + * + * @return array + */ + public function get_tools() { + $tools = array( + 'clear_transients' => array( + 'name' => __( 'WooCommerce transients', 'woocommerce' ), + 'button' => __( 'Clear transients', 'woocommerce' ), + 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ), + ), + 'clear_expired_transients' => array( + 'name' => __( 'Expired transients', 'woocommerce' ), + 'button' => __( 'Clear transients', 'woocommerce' ), + 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce' ), + ), + 'delete_orphaned_variations' => array( + 'name' => __( 'Orphaned variations', 'woocommerce' ), + 'button' => __( 'Delete orphaned variations', 'woocommerce' ), + 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce' ), + ), + 'clear_expired_download_permissions' => array( + 'name' => __( 'Used-up download permissions', 'woocommerce' ), + 'button' => __( 'Clean up download permissions', 'woocommerce' ), + 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ), + ), + 'regenerate_product_lookup_tables' => array( + 'name' => __( 'Product lookup tables', 'woocommerce' ), + 'button' => __( 'Regenerate', 'woocommerce' ), + 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce' ), + ), + 'recount_terms' => array( + 'name' => __( 'Term counts', 'woocommerce' ), + 'button' => __( 'Recount terms', 'woocommerce' ), + 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ), + ), + 'reset_roles' => array( + 'name' => __( 'Capabilities', 'woocommerce' ), + 'button' => __( 'Reset capabilities', 'woocommerce' ), + 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ), + ), + 'clear_sessions' => array( + 'name' => __( 'Clear customer sessions', 'woocommerce' ), + 'button' => __( 'Clear', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce' ) + ), + ), + 'install_pages' => array( + 'name' => __( 'Create default WooCommerce pages', 'woocommerce' ), + 'button' => __( 'Create pages', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce' ) + ), + ), + 'delete_taxes' => array( + 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce' ), + 'button' => __( 'Delete tax rates', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce' ) + ), + ), + 'regenerate_thumbnails' => array( + 'name' => __( 'Regenerate shop thumbnails', 'woocommerce' ), + 'button' => __( 'Regenerate', 'woocommerce' ), + 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce' ), + ), + 'db_update_routine' => array( + 'name' => __( 'Update database', 'woocommerce' ), + 'button' => __( 'Update database', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce' ) + ), + ), + ); + + // Jetpack does the image resizing heavy lifting so you don't have to. + if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) { + unset( $tools['regenerate_thumbnails'] ); + } + + return apply_filters( 'woocommerce_debug_tools', $tools ); + } + + /** + * Get a list of system status tools. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $tools = array(); + foreach ( $this->get_tools() as $id => $tool ) { + $tools[] = $this->prepare_response_for_collection( + $this->prepare_item_for_response( + array( + 'id' => $id, + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ), + $request + ) + ); + } + + $response = rest_ensure_response( $tools ); + return $response; + } + + /** + * Return a single tool. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $tools = $this->get_tools(); + if ( empty( $tools[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + $tool = $tools[ $request['id'] ]; + return rest_ensure_response( + $this->prepare_item_for_response( + array( + 'id' => $request['id'], + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ), + $request + ) + ); + } + + /** + * Update (execute) a tool. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $tools = $this->get_tools(); + if ( empty( $tools[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tool = $tools[ $request['id'] ]; + $tool = array( + 'id' => $request['id'], + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ); + + $execute_return = $this->execute_tool( $request['id'] ); + $tool = array_merge( $tool, $execute_return ); + + /** + * Fires after a WooCommerce REST system status tool has been executed. + * + * @param array $tool Details about the tool that has been executed. + * @param WP_REST_Request $request The current WP_REST_Request object. + */ + do_action( 'woocommerce_rest_insert_system_status_tool', $tool, $request ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tool, $request ); + return rest_ensure_response( $response ); + } + + /** + * Prepare a tool item for serialization. + * + * @param array $item Object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item['id'] ) ); + + return $response; + } + + /** + * Get the system status tools schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'system_status_tool', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the tool.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'name' => array( + 'description' => __( 'Tool name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'action' => array( + 'description' => __( 'What running the tool will do.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'Tool description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'success' => array( + 'description' => __( 'Did the tool run successfully?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'edit' ), + ), + 'message' => array( + 'description' => __( 'Tool return message.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Prepare links for the request. + * + * @param string $id ID. + * @return array + */ + protected function prepare_links( $id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'item' => array( + 'href' => rest_url( trailingslashit( $base ) . $id ), + 'embeddable' => true, + ), + ); + + return $links; + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + + /** + * Actually executes a tool. + * + * @param string $tool Tool. + * @return array + */ + public function execute_tool( $tool ) { + global $wpdb; + $ran = true; + switch ( $tool ) { + case 'clear_transients': + wc_delete_product_transients(); + wc_delete_shop_order_transients(); + delete_transient( 'wc_count_comments' ); + + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( $attribute_taxonomies ) { + foreach ( $attribute_taxonomies as $attribute ) { + delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name ); + } + } + + WC_Cache_Helper::get_transient_version( 'shipping', true ); + $message = __( 'Product transients cleared', 'woocommerce' ); + break; + + case 'clear_expired_transients': + /* translators: %d: amount of expired transients */ + $message = sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() ); + break; + + case 'delete_orphaned_variations': + // Delete orphans. + $result = absint( + $wpdb->query( + "DELETE products + FROM {$wpdb->posts} products + LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent + WHERE wp.ID IS NULL AND products.post_type = 'product_variation';" + ) + ); + /* translators: %d: amount of orphaned variations */ + $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result ); + break; + + case 'clear_expired_download_permissions': + // Delete expired download permissions and ones with 0 downloads remaining. + $result = absint( + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )", + date( 'Y-m-d', current_time( 'timestamp' ) ) + ) + ) + ); + /* translators: %d: amount of permissions */ + $message = sprintf( __( '%d permissions deleted', 'woocommerce' ), $result ); + break; + + case 'regenerate_product_lookup_tables': + if ( ! wc_update_product_lookup_tables_is_running() ) { + wc_update_product_lookup_tables(); + } + $message = __( 'Lookup tables are regenerating', 'woocommerce' ); + break; + case 'reset_roles': + // Remove then re-add caps and roles. + WC_Install::remove_roles(); + WC_Install::create_roles(); + $message = __( 'Roles successfully reset', 'woocommerce' ); + break; + + case 'recount_terms': + $product_cats = get_terms( + 'product_cat', + array( + 'hide_empty' => false, + 'fields' => 'id=>parent', + ) + ); + _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false ); + $product_tags = get_terms( + 'product_tag', + array( + 'hide_empty' => false, + 'fields' => 'id=>parent', + ) + ); + _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); + $message = __( 'Terms successfully recounted', 'woocommerce' ); + break; + + case 'clear_sessions': + $wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" ); + $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. + wp_cache_flush(); + /* translators: %d: amount of sessions */ + $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) ); + break; + + case 'install_pages': + WC_Install::create_pages(); + $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); + break; + + case 'delete_taxes': + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); + WC_Cache_Helper::incr_cache_prefix( 'taxes' ); + $message = __( 'Tax rates successfully deleted', 'woocommerce' ); + break; + + case 'regenerate_thumbnails': + WC_Regenerate_Images::queue_image_regeneration(); + $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); + break; + + case 'db_update_routine': + $blog_id = get_current_blog_id(); + // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). + // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. + do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); + $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' ); + break; + + default: + $tools = $this->get_tools(); + if ( isset( $tools[ $tool ]['callback'] ) ) { + $callback = $tools[ $tool ]['callback']; + $return = call_user_func( $callback ); + if ( is_string( $return ) ) { + $message = $return; + } elseif ( false === $return ) { + $callback_string = is_array( $callback ) ? get_class( $callback[0] ) . '::' . $callback[1] : $callback; + $ran = false; + /* translators: %s: callback string */ + $message = sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback_string ); + } else { + $message = __( 'Tool ran.', 'woocommerce' ); + } + } else { + $ran = false; + $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ); + } + break; + } + + return array( + 'success' => $ran, + 'message' => $message, + ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-system-status-v2-controller.php b/src/RestApi/Version4/class-wc-rest-system-status-v2-controller.php new file mode 100644 index 00000000000..d141e656009 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-system-status-v2-controller.php @@ -0,0 +1,1180 @@ +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' ), + ) + ); + } + + /** + * Check whether a given request has permission to view system status. + * + * @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; + } + + /** + * Get a system status info, by section. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $schema = $this->get_item_schema(); + $mappings = $this->get_item_mappings(); + $response = array(); + + foreach ( $mappings as $section => $values ) { + foreach ( $values as $key => $value ) { + if ( isset( $schema['properties'][ $section ]['properties'][ $key ]['type'] ) ) { + settype( $values[ $key ], $schema['properties'][ $section ]['properties'][ $key ]['type'] ); + } + } + settype( $values, $schema['properties'][ $section ]['type'] ); + $response[ $section ] = $values; + } + + $response = $this->prepare_item_for_response( $response, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Get the system status schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'system_status', + 'type' => 'object', + 'properties' => array( + 'environment' => array( + 'description' => __( 'Environment.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'home_url' => array( + 'description' => __( 'Home URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'site_url' => array( + 'description' => __( 'Site URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wc_version' => array( + 'description' => __( 'WooCommerce version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'log_directory' => array( + 'description' => __( 'Log directory.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'log_directory_writable' => array( + 'description' => __( 'Is log directory writable?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_version' => array( + 'description' => __( 'WordPress version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_multisite' => array( + 'description' => __( 'Is WordPress multisite?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_memory_limit' => array( + 'description' => __( 'WordPress memory limit.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_debug_mode' => array( + 'description' => __( 'Is WordPress debug mode active?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_cron' => array( + 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'language' => array( + 'description' => __( 'WordPress language.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'server_info' => array( + 'description' => __( 'Server info.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_version' => array( + 'description' => __( 'PHP version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_post_max_size' => array( + 'description' => __( 'PHP post max size.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_max_execution_time' => array( + 'description' => __( 'PHP max execution time.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_max_input_vars' => array( + 'description' => __( 'PHP max input vars.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'curl_version' => array( + 'description' => __( 'cURL version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'suhosin_installed' => array( + 'description' => __( 'Is SUHOSIN installed?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'max_upload_size' => array( + 'description' => __( 'Max upload size.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mysql_version' => array( + 'description' => __( 'MySQL version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mysql_version_string' => array( + 'description' => __( 'MySQL version string.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'default_timezone' => array( + 'description' => __( 'Default timezone.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'fsockopen_or_curl_enabled' => array( + 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'soapclient_enabled' => array( + 'description' => __( 'Is SoapClient class enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'domdocument_enabled' => array( + 'description' => __( 'Is DomDocument class enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'gzip_enabled' => array( + 'description' => __( 'Is GZip enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mbstring_enabled' => array( + 'description' => __( 'Is mbstring enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_post_successful' => array( + 'description' => __( 'Remote POST successful?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_post_response' => array( + 'description' => __( 'Remote POST response.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_get_successful' => array( + 'description' => __( 'Remote GET successful?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_get_response' => array( + 'description' => __( 'Remote GET response.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'database' => array( + 'description' => __( 'Database.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'wc_database_version' => array( + 'description' => __( 'WC database version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'database_prefix' => array( + 'description' => __( 'Database prefix.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'maxmind_geoip_database' => array( + 'description' => __( 'MaxMind GeoIP database.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'database_tables' => array( + 'description' => __( 'Database tables.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ), + 'active_plugins' => array( + 'description' => __( 'Active plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'inactive_plugins' => array( + 'description' => __( 'Inactive plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'dropins_mu_plugins' => array( + 'description' => __( 'Dropins & MU plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'theme' => array( + 'description' => __( 'Theme.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'name' => array( + 'description' => __( 'Theme name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'version' => array( + 'description' => __( 'Theme version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'version_latest' => array( + 'description' => __( 'Latest version of theme.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'author_url' => array( + 'description' => __( 'Theme author URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'is_child_theme' => array( + 'description' => __( 'Is this theme a child theme?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_woocommerce_support' => array( + 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_woocommerce_file' => array( + 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_outdated_templates' => array( + 'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'overrides' => array( + 'description' => __( 'Template overrides.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'parent_name' => array( + 'description' => __( 'Parent theme name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_version' => array( + 'description' => __( 'Parent theme version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_author_url' => array( + 'description' => __( 'Parent theme author URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'settings' => array( + 'description' => __( 'Settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'api_enabled' => array( + 'description' => __( 'REST API enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'force_ssl' => array( + 'description' => __( 'SSL forced?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency' => array( + 'description' => __( 'Currency.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_symbol' => array( + 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_position' => array( + 'description' => __( 'Currency position.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'thousand_separator' => array( + 'description' => __( 'Thousand separator.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'decimal_separator' => array( + 'description' => __( 'Decimal separator.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'number_of_decimals' => array( + 'description' => __( 'Number of decimals.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'geolocation_enabled' => array( + 'description' => __( 'Geolocation enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'taxonomies' => array( + 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'product_visibility_terms' => array( + 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ), + 'security' => array( + 'description' => __( 'Security.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'secure_connection' => array( + 'description' => __( 'Is the connection to your store secure?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'hide_errors' => array( + 'description' => __( 'Hide errors from visitors?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'pages' => array( + 'description' => __( 'WooCommerce pages.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Return an array of sections and the data associated with each. + * + * @return array + */ + public function get_item_mappings() { + return array( + 'environment' => $this->get_environment_info(), + 'database' => $this->get_database_info(), + 'active_plugins' => $this->get_active_plugins(), + 'inactive_plugins' => $this->get_inactive_plugins(), + 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(), + 'theme' => $this->get_theme_info(), + 'settings' => $this->get_settings(), + 'security' => $this->get_security_info(), + 'pages' => $this->get_pages(), + ); + } + + /** + * Get array of environment information. Includes thing like software + * versions, and various server settings. + * + * @return array + */ + public function get_environment_info() { + global $wpdb; + + // Figure out cURL version, if installed. + $curl_version = ''; + if ( function_exists( 'curl_version' ) ) { + $curl_version = curl_version(); + $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; + } elseif ( extension_loaded( 'curl' ) ) { + $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); + } + + // WP memory limit. + $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); + if ( function_exists( 'memory_get_usage' ) ) { + $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); + } + + // Test POST requests. + $post_response_code = get_transient( 'woocommerce_test_remote_post' ); + + if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { + $response = wp_safe_remote_post( + 'https://www.paypal.com/cgi-bin/webscr', + array( + 'timeout' => 10, + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', + 'body' => array( + 'cmd' => '_notify-validate', + ), + ) + ); + if ( ! is_wp_error( $response ) ) { + $post_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); + } + + $post_response_successful = ! is_wp_error( $post_response_code ) && $post_response_code >= 200 && $post_response_code < 300; + + // Test GET requests. + $get_response_code = get_transient( 'woocommerce_test_remote_get' ); + + if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { + $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); + if ( ! is_wp_error( $response ) ) { + $get_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); + } + + $get_response_successful = ! is_wp_error( $get_response_code ) && $get_response_code >= 200 && $get_response_code < 300; + + $database_version = wc_get_server_database_version(); + + // Return all environment info. Described by JSON Schema. + return array( + 'home_url' => get_option( 'home' ), + 'site_url' => get_option( 'siteurl' ), + 'version' => WC()->version, + 'log_directory' => WC_LOG_DIR, + 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), + 'wp_version' => get_bloginfo( 'version' ), + 'wp_multisite' => is_multisite(), + 'wp_memory_limit' => $wp_memory_limit, + 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), + 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ), + 'language' => get_locale(), + 'external_object_cache' => wp_using_ext_object_cache(), + 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '', + 'php_version' => phpversion(), + 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), + 'php_max_execution_time' => ini_get( 'max_execution_time' ), + 'php_max_input_vars' => ini_get( 'max_input_vars' ), + 'curl_version' => $curl_version, + 'suhosin_installed' => extension_loaded( 'suhosin' ), + 'max_upload_size' => wp_max_upload_size(), + 'mysql_version' => $database_version['number'], + 'mysql_version_string' => $database_version['string'], + 'default_timezone' => date_default_timezone_get(), + 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ), + 'soapclient_enabled' => class_exists( 'SoapClient' ), + 'domdocument_enabled' => class_exists( 'DOMDocument' ), + 'gzip_enabled' => is_callable( 'gzopen' ), + 'mbstring_enabled' => extension_loaded( 'mbstring' ), + 'remote_post_successful' => $post_response_successful, + 'remote_post_response' => is_wp_error( $post_response_code ) ? $post_response_code->get_error_message() : $post_response_code, + 'remote_get_successful' => $get_response_successful, + 'remote_get_response' => is_wp_error( $get_response_code ) ? $get_response_code->get_error_message() : $get_response_code, + ); + } + + /** + * Add prefix to table. + * + * @param string $table Table name. + * @return stromg + */ + protected function add_db_table_prefix( $table ) { + global $wpdb; + return $wpdb->prefix . $table; + } + + /** + * Get array of database information. Version, prefix, and table existence. + * + * @return array + */ + public function get_database_info() { + global $wpdb; + + $database_table_information = $wpdb->get_results( + $wpdb->prepare( + "SELECT + table_name AS 'name', + engine, + round( ( data_length / 1024 / 1024 ), 2 ) 'data', + round( ( index_length / 1024 / 1024 ), 2 ) 'index' + FROM information_schema.TABLES + WHERE table_schema = %s + ORDER BY name ASC;", + DB_NAME + ) + ); + + // WC Core tables to check existence of. + $core_tables = apply_filters( + 'woocommerce_database_tables', + array( + 'woocommerce_sessions', + 'woocommerce_api_keys', + 'woocommerce_attribute_taxonomies', + 'woocommerce_downloadable_product_permissions', + 'woocommerce_order_items', + 'woocommerce_order_itemmeta', + 'woocommerce_tax_rates', + 'woocommerce_tax_rate_locations', + 'woocommerce_shipping_zones', + 'woocommerce_shipping_zone_locations', + 'woocommerce_shipping_zone_methods', + 'woocommerce_payment_tokens', + 'woocommerce_payment_tokenmeta', + 'woocommerce_log', + ) + ); + + /** + * Adding the prefix to the tables array, for backwards compatibility. + * + * If we changed the tables above to include the prefix, then any filters against that table could break. + */ + $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); + + /** + * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. + * + * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. + */ + $tables = array( + 'woocommerce' => array_fill_keys( $core_tables, false ), + 'other' => array(), + ); + + $database_size = array( + 'data' => 0, + 'index' => 0, + ); + + $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); + $global_tables = $wpdb->tables( 'global', true ); + foreach ( $database_table_information as $table ) { + // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. + if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { + continue; + } + $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce' : 'other'; + + $tables[ $table_type ][ $table->name ] = array( + 'data' => $table->data, + 'index' => $table->index, + 'engine' => $table->engine, + ); + + $database_size['data'] += $table->data; + $database_size['index'] += $table->index; + } + + // Return all database info. Described by JSON Schema. + return array( + 'wc_database_version' => get_option( 'woocommerce_db_version' ), + 'database_prefix' => $wpdb->prefix, + 'maxmind_geoip_database' => WC_Geolocation::get_local_database_path(), + 'database_tables' => $tables, + 'database_size' => $database_size, + ); + } + + /** + * Get array of counts of objects. Orders, products, etc. + * + * @return array + */ + public function get_post_type_counts() { + global $wpdb; + + $post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" ); + + return is_array( $post_type_counts ) ? $post_type_counts : array(); + } + + /** + * Get a list of plugins active on the site. + * + * @return array + */ + public function get_active_plugins() { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + if ( ! function_exists( 'get_plugin_data' ) ) { + return array(); + } + + $active_plugins = (array) get_option( 'active_plugins', array() ); + if ( is_multisite() ) { + $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); + } + + $active_plugins_data = array(); + + foreach ( $active_plugins as $plugin ) { + $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + $active_plugins_data[] = $this->format_plugin_data( $plugin, $data ); + } + + return $active_plugins_data; + } + + /** + * Get a list of inplugins active on the site. + * + * @return array + */ + public function get_inactive_plugins() { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + if ( ! function_exists( 'get_plugins' ) ) { + return array(); + } + + $plugins = get_plugins(); + $active_plugins = (array) get_option( 'active_plugins', array() ); + + if ( is_multisite() ) { + $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); + } + + $plugins_data = array(); + + foreach ( $plugins as $plugin => $data ) { + if ( in_array( $plugin, $active_plugins, true ) ) { + continue; + } + $plugins_data[] = $this->format_plugin_data( $plugin, $data ); + } + + return $plugins_data; + } + + /** + * Format plugin data, including data on updates, into a standard format. + * + * @since 3.6.0 + * @param string $plugin Plugin directory/file. + * @param array $data Plugin data from WP. + * @return array Formatted data. + */ + protected function format_plugin_data( $plugin, $data ) { + require_once ABSPATH . 'wp-admin/includes/update.php'; + + if ( ! function_exists( 'get_plugin_updates' ) ) { + return array(); + } + + // Use WP API to lookup latest updates for plugins. WC_Helper injects updates for premium plugins. + if ( empty( $this->available_updates ) ) { + $this->available_updates = get_plugin_updates(); + } + + $version_latest = $data['Version']; + + // Find latest version. + if ( isset( $this->available_updates[ $plugin ]->update->new_version ) ) { + $version_latest = $this->available_updates[ $plugin ]->update->new_version; + } + + return array( + 'plugin' => $plugin, + 'name' => $data['Name'], + 'version' => $data['Version'], + 'version_latest' => $version_latest, + 'url' => $data['PluginURI'], + 'author_name' => $data['AuthorName'], + 'author_url' => esc_url_raw( $data['AuthorURI'] ), + 'network_activated' => $data['Network'], + ); + } + + /** + * Get a list of Dropins and MU plugins. + * + * @since 3.6.0 + * @return array + */ + public function get_dropins_mu_plugins() { + $dropins = get_dropins(); + $plugins = array( + 'dropins' => array(), + 'mu_plugins' => array(), + ); + foreach ( $dropins as $key => $dropin ) { + $plugins['dropins'][] = array( + 'plugin' => $key, + 'name' => $dropin['Name'], + ); + } + + $mu_plugins = get_mu_plugins(); + foreach ( $mu_plugins as $plugin => $mu_plugin ) { + $plugins['mu_plugins'][] = array( + 'plugin' => $plugin, + 'name' => $mu_plugin['Name'], + 'version' => $mu_plugin['Version'], + 'url' => $mu_plugin['PluginURI'], + 'author_name' => $mu_plugin['AuthorName'], + 'author_url' => esc_url_raw( $mu_plugin['AuthorURI'] ), + ); + } + return $plugins; + } + + /** + * Get info on the current active theme, info on parent theme (if presnet) + * and a list of template overrides. + * + * @return array + */ + public function get_theme_info() { + $active_theme = wp_get_theme(); + + // Get parent theme info if this theme is a child theme, otherwise + // pass empty info in the response. + if ( is_child_theme() ) { + $parent_theme = wp_get_theme( $active_theme->template ); + $parent_theme_info = array( + 'parent_name' => $parent_theme->name, + 'parent_version' => $parent_theme->version, + 'parent_version_latest' => WC_Admin_Status::get_latest_theme_version( $parent_theme ), + 'parent_author_url' => $parent_theme->{'Author URI'}, + ); + } else { + $parent_theme_info = array( + 'parent_name' => '', + 'parent_version' => '', + 'parent_version_latest' => '', + 'parent_author_url' => '', + ); + } + + /** + * Scan the theme directory for all WC templates to see if our theme + * overrides any of them. + */ + $override_files = array(); + $outdated_templates = false; + $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); + foreach ( $scan_files as $file ) { + $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' ); + + if ( file_exists( $located ) ) { + $theme_file = $located; + } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . $file; + } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; + } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { + $theme_file = get_template_directory() . '/' . $file; + } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; + } else { + $theme_file = false; + } + + if ( ! empty( $theme_file ) ) { + $core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); + $theme_version = WC_Admin_Status::get_file_version( $theme_file ); + if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { + if ( ! $outdated_templates ) { + $outdated_templates = true; + } + } + $override_files[] = array( + 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), + 'version' => $theme_version, + 'core_version' => $core_version, + ); + } + } + + $active_theme_info = array( + 'name' => $active_theme->name, + 'version' => $active_theme->version, + 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ), + 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), + 'is_child_theme' => is_child_theme(), + 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), + 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), + 'has_outdated_templates' => $outdated_templates, + 'overrides' => $override_files, + ); + + return array_merge( $active_theme_info, $parent_theme_info ); + } + + /** + * Get some setting values for the site that are useful for debugging + * purposes. For full settings access, use the settings api. + * + * @return array + */ + public function get_settings() { + // Get a list of terms used for product/order taxonomies. + $term_response = array(); + $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + // Get a list of terms used for product visibility. + $product_visibility_terms = array(); + $terms = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $product_visibility_terms[ $term->slug ] = strtolower( $term->name ); + } + + // Check if WooCommerce.com account is connected. + $woo_com_connected = 'no'; + $helper_options = get_option( 'woocommerce_helper_data', array() ); + if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) { + $woo_com_connected = 'yes'; + } + + // Return array of useful settings for debugging. + return array( + 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ), + 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ), + 'currency' => get_woocommerce_currency(), + 'currency_symbol' => get_woocommerce_currency_symbol(), + 'currency_position' => get_option( 'woocommerce_currency_pos' ), + 'thousand_separator' => wc_get_price_thousand_separator(), + 'decimal_separator' => wc_get_price_decimal_separator(), + 'number_of_decimals' => wc_get_price_decimals(), + 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ), + 'taxonomies' => $term_response, + 'product_visibility_terms' => $product_visibility_terms, + 'woocommerce_com_connected' => $woo_com_connected, + ); + } + + /** + * Returns security tips. + * + * @return array + */ + public function get_security_info() { + $check_page = wc_get_page_permalink( 'shop' ); + return array( + 'secure_connection' => 'https' === substr( $check_page, 0, 5 ), + 'hide_errors' => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), + ); + } + + /** + * Returns a mini-report on WC pages and if they are configured correctly: + * Present, visible, and including the correct shortcode. + * + * @return array + */ + public function get_pages() { + // WC pages to check against. + $check_pages = array( + _x( 'Shop base', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_shop_page_id', + 'shortcode' => '', + ), + _x( 'Cart', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_cart_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', + ), + _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_checkout_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', + ), + _x( 'My account', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_myaccount_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', + ), + _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_terms_page_id', + 'shortcode' => '', + ), + ); + + $pages_output = array(); + foreach ( $check_pages as $page_name => $values ) { + $page_id = get_option( $values['option'] ); + $page_set = false; + $page_exists = false; + $page_visible = false; + $shortcode_present = false; + $shortcode_required = false; + + // Page checks. + if ( $page_id ) { + $page_set = true; + } + if ( get_post( $page_id ) ) { + $page_exists = true; + } + if ( 'publish' === get_post_status( $page_id ) ) { + $page_visible = true; + } + + // Shortcode checks. + if ( $values['shortcode'] && get_post( $page_id ) ) { + $shortcode_required = true; + $page = get_post( $page_id ); + if ( strstr( $page->post_content, $values['shortcode'] ) ) { + $shortcode_present = true; + } + } + + // Wrap up our findings into an output array. + $pages_output[] = array( + 'page_name' => $page_name, + 'page_id' => $page_id, + 'page_set' => $page_set, + 'page_exists' => $page_exists, + 'page_visible' => $page_visible, + 'shortcode' => $values['shortcode'], + 'shortcode_required' => $shortcode_required, + 'shortcode_present' => $shortcode_present, + ); + } + + return $pages_output; + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + + /** + * Prepare the system status response + * + * @param array $system_status System status data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $system_status, $request ) { + $data = $this->add_additional_fields_to_object( $system_status, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + + $response = rest_ensure_response( $data ); + + /** + * Filter the system status returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param mixed $system_status System status + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_system_status', $response, $system_status, $request ); + } +} diff --git a/src/RestApi/Version4/class-wc-rest-terms-controller.php b/src/RestApi/Version4/class-wc-rest-terms-controller.php new file mode 100644 index 00000000000..d9588099149 --- /dev/null +++ b/src/RestApi/Version4/class-wc-rest-terms-controller.php @@ -0,0 +1,806 @@ +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(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( + 'name' => array( + 'type' => 'string', + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'required' => true, + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Check if a given request has access to read the terms. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'read' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'create' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'read' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'edit' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'delete' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'batch' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check permissions. + * + * @param WP_REST_Request $request Full details about the request. + * @param string $context Request context. + * @return bool|WP_Error + */ + protected function check_permissions( $request, $context = 'read' ) { + // Get taxonomy. + $taxonomy = $this->get_taxonomy( $request ); + if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Check permissions for a single term. + $id = intval( $request['id'] ); + if ( $id ) { + $term = get_term( $id, $taxonomy ); + + if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { + return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id ); + } + + return wc_rest_check_product_term_permissions( $taxonomy, $context ); + } + + /** + * Get terms associated with a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $prepared_args = array( + 'exclude' => $request['exclude'], + 'include' => $request['include'], + 'order' => $request['order'], + 'orderby' => $request['orderby'], + 'product' => $request['product'], + 'hide_empty' => $request['hide_empty'], + 'number' => $request['per_page'], + 'search' => $request['search'], + 'slug' => $request['slug'], + ); + + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + + $taxonomy_obj = get_taxonomy( $taxonomy ); + + if ( $taxonomy_obj->hierarchical && isset( $request['parent'] ) ) { + if ( 0 === $request['parent'] ) { + // Only query top-level terms. + $prepared_args['parent'] = 0; + } else { + if ( $request['parent'] ) { + $prepared_args['parent'] = $request['parent']; + } + } + } + + /** + * Filter the query arguments, before passing them to `get_terms()`. + * + * Enables adding extra arguments or setting defaults for a terms + * collection request. + * + * @see https://developer.wordpress.org/reference/functions/get_terms/ + * + * @param array $prepared_args Array of arguments to be + * passed to get_terms. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( "woocommerce_rest_{$taxonomy}_query", $prepared_args, $request ); + + if ( ! empty( $prepared_args['product'] ) ) { + $query_result = $this->get_terms_for_product( $prepared_args, $request ); + $total_terms = $this->total_terms; + } else { + $query_result = get_terms( $taxonomy, $prepared_args ); + + $count_args = $prepared_args; + unset( $count_args['number'] ); + unset( $count_args['offset'] ); + $total_terms = wp_count_terms( $taxonomy, $count_args ); + + // Ensure we don't return results when offset is out of bounds. + // See https://core.trac.wordpress.org/ticket/35935. + if ( $prepared_args['offset'] && $prepared_args['offset'] >= $total_terms ) { + $query_result = array(); + } + + // wp_count_terms can return a falsy value when the term has no children. + if ( ! $total_terms ) { + $total_terms = 0; + } + } + $response = array(); + foreach ( $query_result as $term ) { + $data = $this->prepare_item_for_response( $term, $request ); + $response[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $response ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + $response->header( 'X-WP-Total', (int) $total_terms ); + $max_pages = ceil( $total_terms / $per_page ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $base = str_replace( '(?P[\d]+)', $request['attribute_id'], $this->rest_base ); + $base = add_query_arg( $request->get_query_params(), rest_url( '/' . $this->namespace . '/' . $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; + } + + /** + * Create a single term for a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $name = $request['name']; + $args = array(); + $schema = $this->get_item_schema(); + + if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { + $args['description'] = $request['description']; + } + if ( isset( $request['slug'] ) ) { + $args['slug'] = $request['slug']; + } + if ( isset( $request['parent'] ) ) { + if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + } + $args['parent'] = $request['parent']; + } + + $term = wp_insert_term( $name, $taxonomy, $args ); + if ( is_wp_error( $term ) ) { + $error_data = array( 'status' => 400 ); + + // If we're going to inform the client that the term exists, + // give them the identifier they can actually use. + $term_id = $term->get_error_data( 'term_exists' ); + if ( $term_id ) { + $error_data['resource_id'] = $term_id; + } + + return new WP_Error( $term->get_error_code(), $term->get_error_message(), $error_data ); + } + + $term = get_term( $term['term_id'], $taxonomy ); + + $this->update_additional_fields_for_object( $term, $request ); + + // Add term data. + $meta_fields = $this->update_term_meta_fields( $term, $request ); + if ( is_wp_error( $meta_fields ) ) { + wp_delete_term( $term->term_id, $taxonomy ); + + return $meta_fields; + } + + /** + * Fires after a single term is created or updated via the REST API. + * + * @param WP_Term $term Inserted Term object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating term, false when updating. + */ + do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + + $base = '/' . $this->namespace . '/' . $this->rest_base; + if ( ! empty( $request['attribute_id'] ) ) { + $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); + } + + $response->header( 'Location', rest_url( $base . '/' . $term->term_id ) ); + + return $response; + } + + /** + * Get a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function get_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $term = get_term( (int) $request['id'], $taxonomy ); + + if ( is_wp_error( $term ) ) { + return $term; + } + + $response = $this->prepare_item_for_response( $term, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Update a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $term = get_term( (int) $request['id'], $taxonomy ); + $schema = $this->get_item_schema(); + $prepared_args = array(); + + if ( isset( $request['name'] ) ) { + $prepared_args['name'] = $request['name']; + } + if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { + $prepared_args['description'] = $request['description']; + } + if ( isset( $request['slug'] ) ) { + $prepared_args['slug'] = $request['slug']; + } + if ( isset( $request['parent'] ) ) { + if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + } + $prepared_args['parent'] = $request['parent']; + } + + // Only update the term if we haz something to update. + if ( ! empty( $prepared_args ) ) { + $update = wp_update_term( $term->term_id, $term->taxonomy, $prepared_args ); + if ( is_wp_error( $update ) ) { + return $update; + } + } + + $term = get_term( (int) $request['id'], $taxonomy ); + + $this->update_additional_fields_for_object( $term, $request ); + + // Update term data. + $meta_fields = $this->update_term_meta_fields( $term, $request ); + if ( is_wp_error( $meta_fields ) ) { + return $meta_fields; + } + + /** + * Fires after a single term is created or updated via the REST API. + * + * @param WP_Term $term Inserted Term object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating term, false when updating. + */ + do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + return rest_ensure_response( $response ); + } + + /** + * Delete a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $term = get_term( (int) $request['id'], $taxonomy ); + // Get default category id. + $default_category_id = absint( get_option( 'default_product_cat', 0 ) ); + + // Prevent deleting the default product category. + if ( $default_category_id === (int) $request['id'] ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + + $retval = wp_delete_term( $term->term_id, $term->taxonomy ); + if ( ! $retval ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single term is deleted via the REST API. + * + * @param WP_Term $term The deleted term. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$taxonomy}", $term, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param object $term Term object. + * @param WP_REST_Request $request Full details about the request. + * @return array Links for the given term. + */ + protected function prepare_links( $term, $request ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + + if ( ! empty( $request['attribute_id'] ) ) { + $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); + } + + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $term->term_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + if ( $term->parent ) { + $parent_term = get_term( (int) $term->parent, $term->taxonomy ); + if ( $parent_term ) { + $links['up'] = array( + 'href' => rest_url( trailingslashit( $base ) . $parent_term->term_id ), + ); + } + } + + return $links; + } + + /** + * Update term meta fields. + * + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + return true; + } + + /** + * Get the terms attached to a product. + * + * This is an alternative to `get_terms()` that uses `get_the_terms()` + * instead, which hits the object cache. There are a few things not + * supported, notably `include`, `exclude`. In `self::get_items()` these + * are instead treated as a full query. + * + * @param array $prepared_args Arguments for `get_terms()`. + * @param WP_REST_Request $request Full details about the request. + * @return array List of term objects. (Total count in `$this->total_terms`). + */ + protected function get_terms_for_product( $prepared_args, $request ) { + $taxonomy = $this->get_taxonomy( $request ); + + $query_result = get_the_terms( $prepared_args['product'], $taxonomy ); + if ( empty( $query_result ) ) { + $this->total_terms = 0; + return array(); + } + + // get_items() verifies that we don't have `include` set, and default. + // ordering is by `name`. + if ( ! in_array( $prepared_args['orderby'], array( 'name', 'none', 'include' ), true ) ) { + switch ( $prepared_args['orderby'] ) { + case 'id': + $this->sort_column = 'term_id'; + break; + case 'slug': + case 'term_group': + case 'description': + case 'count': + $this->sort_column = $prepared_args['orderby']; + break; + } + usort( $query_result, array( $this, 'compare_terms' ) ); + } + if ( strtolower( $prepared_args['order'] ) !== 'asc' ) { + $query_result = array_reverse( $query_result ); + } + + // Pagination. + $this->total_terms = count( $query_result ); + $query_result = array_slice( $query_result, $prepared_args['offset'], $prepared_args['number'] ); + + return $query_result; + } + + /** + * Comparison function for sorting terms by a column. + * + * Uses `$this->sort_column` to determine field to sort by. + * + * @param stdClass $left Term object. + * @param stdClass $right Term object. + * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left. + */ + protected function compare_terms( $left, $right ) { + $col = $this->sort_column; + $left_val = $left->$col; + $right_val = $right->$col; + + if ( is_int( $left_val ) && is_int( $right_val ) ) { + return $left_val - $right_val; + } + + return strcmp( $left_val, $right_val ); + } + + /** + * Get the query params for collections + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + if ( '' !== $this->taxonomy && taxonomy_exists( $this->taxonomy ) ) { + $taxonomy = get_taxonomy( $this->taxonomy ); + } else { + $taxonomy = new stdClass(); + $taxonomy->hierarchical = true; + } + + $params['context']['default'] = 'view'; + + $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', + ); + if ( ! $taxonomy->hierarchical ) { + $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', + 'sanitize_callback' => 'sanitize_key', + 'default' => 'asc', + 'enum' => array( + 'asc', + 'desc', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by resource attribute.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'default' => 'name', + 'enum' => array( + 'id', + 'include', + 'name', + 'slug', + 'term_group', + 'description', + 'count', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['hide_empty'] = array( + 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'validate_callback' => 'rest_validate_request_arg', + ); + if ( $taxonomy->hierarchical ) { + $params['parent'] = array( + 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + } + $params['product'] = array( + 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['slug'] = array( + 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Get taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function get_taxonomy( $request ) { + // Check if taxonomy is defined. + // Prevents check for attribute taxonomy more than one time for each query. + if ( '' !== $this->taxonomy ) { + return $this->taxonomy; + } + + if ( ! empty( $request['attribute_id'] ) ) { + $taxonomy = wc_attribute_taxonomy_name_by_id( (int) $request['attribute_id'] ); + + $this->taxonomy = $taxonomy; + } + + return $this->taxonomy; + } +} diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-admin-notes-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-admin-notes-controller.php deleted file mode 100644 index 6872f6b190b..00000000000 --- a/src/RestApi/Version4_temp/class-wc-admin-rest-admin-notes-controller.php +++ /dev/null @@ -1,484 +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-admin' ), - '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-admin' ), - 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-admin' ), 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-admin' ), 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-admin' ), - array( 'status' => 404 ) - ); - } - - // @todo Status is the only field that can be updated at the moment. We should also implement the "date reminder" setting. - $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-admin' ), 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 ( '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-admin' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-admin' ), - '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-admin' ), - 'type' => 'integer', - 'default' => 1, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - 'minimum' => 1, - ); - $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['type'] = array( - 'description' => __( 'Type of note.', 'woocommerce-admin' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => WC_Admin_Note::get_allowed_types(), - 'type' => 'string', - ), - ); - $params['status'] = array( - 'description' => __( 'Status of note.', 'woocommerce-admin' ), - 'type' => 'array', - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => WC_Admin_Note::get_allowed_statuses(), - 'type' => 'string', - ), - ); - return $params; - } - - /** - * 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-admin' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Name of the note.', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'The type of the note (e.g. error, warning, etc.).', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'locale' => array( - 'description' => __( 'Locale used for the note title and content.', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Title of the note.', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'content' => array( - 'description' => __( 'Content of the note.', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'icon' => array( - 'description' => __( 'Icon (gridicon) for the note.', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'content_data' => array( - 'description' => __( 'Content data for the note. JSON string. Available for re-localization.', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'The status of the note (e.g. unactioned, actioned).', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'source' => array( - 'description' => __( 'Source of the note.', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( 'Date the note was created.', 'woocommerce-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'Date the note was created (GMT).', 'woocommerce-admin' ), - '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-admin' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, // @todo Allow date_reminder to be updated. - ), - 'date_reminder_gmt' => array( - 'description' => __( 'Date after which the user should be reminded of the note, if any (GMT).', 'woocommerce-admin' ), - '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-admin' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'actions' => array( - 'description' => __( 'An array of actions, if any, for the note.', 'woocommerce-admin' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-coupons-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-coupons-controller.php deleted file mode 100644 index dfde5b3ae8a..00000000000 --- a/src/RestApi/Version4_temp/class-wc-admin-rest-coupons-controller.php +++ /dev/null @@ -1,93 +0,0 @@ - __( 'Limit results to coupons with codes matching a given string.', 'woocommerce-admin' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } - - - /** - * Add coupon code searching to the WC API. - * - * @param WP_REST_Request $request Request data. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - if ( ! empty( $request['search'] ) ) { - $args['search'] = $request['search']; - $args['s'] = false; - } - - return $args; - } - - /** - * Get a collection of posts and add the code search option to WP_Query. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10, 2 ); - $response = parent::get_items( $request ); - remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10 ); - return $response; - } - - /** - * Add code searching to the WP Query - * - * @param string $where Where clause used to search posts. - * @param object $wp_query WP_Query object. - * @return string - */ - public static function add_wp_query_search_code_filter( $where, $wp_query ) { - global $wpdb; - - $search = $wp_query->get( 'search' ); - if ( $search ) { - $search = $wpdb->esc_like( $search ); - $search = "'%" . $search . "%'"; - $where .= ' AND ' . $wpdb->posts . '.post_title LIKE ' . $search; - } - - return $where; - } - -} diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-customers-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-customers-controller.php deleted file mode 100644 index d7cc898c812..00000000000 --- a/src/RestApi/Version4_temp/class-wc-admin-rest-customers-controller.php +++ /dev/null @@ -1,50 +0,0 @@ - __( 'Limit result set to orders matching part of an order number.', 'woocommerce-admin' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } - - /** - * Prepare objects query. - * - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - global $wpdb; - $args = parent::prepare_objects_query( $request ); - - // Search by partial order number. - if ( ! empty( $request['number'] ) ) { - $partial_number = trim( $request['number'] ); - $limit = intval( $args['posts_per_page'] ); - $order_ids = $wpdb->get_col( - $wpdb->prepare( - "SELECT ID - FROM {$wpdb->prefix}posts - WHERE post_type = 'shop_order' - AND ID LIKE %s - LIMIT %d", - $wpdb->esc_like( absint( $partial_number ) ) . '%', - $limit - ) - ); - - // Force WP_Query return empty if don't found any order. - $order_ids = empty( $order_ids ) ? array( 0 ) : $order_ids; - $args['post__in'] = $order_ids; - } - - return $args; - } -} diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-product-categories-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-product-categories-controller.php deleted file mode 100644 index 672cd0c22ca..00000000000 --- a/src/RestApi/Version4_temp/class-wc-admin-rest-product-categories-controller.php +++ /dev/null @@ -1,26 +0,0 @@ - array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $review->comment_ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - if ( 0 !== (int) $review->comment_post_ID ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $review->comment_post_ID ) ), - 'embeddable' => true, - ); - } - if ( 0 !== (int) $review->user_id ) { - $links['reviewer'] = array( - 'href' => rest_url( 'wp/v2/users/' . $review->user_id ), - 'embeddable' => true, - ); - } - return $links; - } -} diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-products-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-products-controller.php deleted file mode 100644 index d19dec34741..00000000000 --- a/src/RestApi/Version4_temp/class-wc-admin-rest-products-controller.php +++ /dev/null @@ -1,189 +0,0 @@ - __( 'Limit result set to products that are low or out of stock.', 'woocommerce-admin' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - ); - $params['search'] = array( - 'description' => __( 'Search by similar product name or sku.', 'woocommerce-admin' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } - - - /** - * Add product name and sku filtering to the WC API. - * - * @param WP_REST_Request $request Request data. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - if ( ! empty( $request['search'] ) ) { - $args['search'] = trim( $request['search'] ); - unset( $args['s'] ); - } - if ( ! empty( $request['low_in_stock'] ) ) { - $args['low_in_stock'] = $request['low_in_stock']; - $args['post_type'] = array( 'product', 'product_variation' ); - } - - return $args; - } - - /** - * Get a collection of posts and add the post title filter option to WP_Query. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); - add_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10, 2 ); - add_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10, 2 ); - $response = parent::get_items( $request ); - remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10 ); - remove_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10 ); - remove_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10 ); - return $response; - } - - /** - * Add in conditional search filters for products. - * - * @param string $where Where clause used to search posts. - * @param object $wp_query WP_Query object. - * @return string - */ - public static function add_wp_query_filter( $where, $wp_query ) { - global $wpdb; - - $search = $wp_query->get( 'search' ); - if ( $search ) { - $search = $wpdb->esc_like( $search ); - $search = "'%" . $search . "%'"; - $where .= " AND ({$wpdb->posts}.post_title LIKE {$search}"; - $where .= wc_product_sku_enabled() ? ' OR ps_post_meta.meta_key = "_sku" AND ps_post_meta.meta_value LIKE ' . $search . ')' : ')'; - } - - if ( $wp_query->get( 'low_in_stock' ) ) { - $low_stock_amount = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) ); - $where .= " AND lis_postmeta2.meta_key = '_manage_stock' - AND lis_postmeta2.meta_value = 'yes' - AND lis_postmeta.meta_key = '_stock' - AND lis_postmeta.meta_value IS NOT NULL - AND lis_postmeta3.meta_key = '_low_stock_amount' - AND ( - lis_postmeta3.meta_value > '' - AND CAST(lis_postmeta.meta_value AS SIGNED) <= CAST(lis_postmeta3.meta_value AS SIGNED) - OR lis_postmeta3.meta_value <= '' - AND CAST(lis_postmeta.meta_value AS SIGNED) <= {$low_stock_amount} - )"; - } - - return $where; - } - - /** - * Join posts meta tables when product search or low stock query is present. - * - * @param string $join Join clause used to search posts. - * @param object $wp_query WP_Query object. - * @return string - */ - public static function add_wp_query_join( $join, $wp_query ) { - global $wpdb; - - $search = $wp_query->get( 'search' ); - if ( $search && wc_product_sku_enabled() ) { - $join .= " INNER JOIN {$wpdb->postmeta} AS ps_post_meta ON ps_post_meta.post_id = {$wpdb->posts}.ID"; - } - - if ( $wp_query->get( 'low_in_stock' ) ) { - $join .= " INNER JOIN {$wpdb->postmeta} AS lis_postmeta ON {$wpdb->posts}.ID = lis_postmeta.post_id - INNER JOIN {$wpdb->postmeta} AS lis_postmeta2 ON {$wpdb->posts}.ID = lis_postmeta2.post_id - INNER JOIN {$wpdb->postmeta} AS lis_postmeta3 ON {$wpdb->posts}.ID = lis_postmeta3.post_id"; - } - - return $join; - } - - /** - * Group by post ID to prevent duplicates. - * - * @param string $groupby Group by clause used to organize posts. - * @param object $wp_query WP_Query object. - * @return string - */ - public static function add_wp_query_group_by( $groupby, $wp_query ) { - global $wpdb; - - $search = $wp_query->get( 'search' ); - $low_in_stock = $wp_query->get( 'low_in_stock' ); - if ( empty( $groupby ) && ( $search || $low_in_stock ) ) { - $groupby = $wpdb->posts . '.ID'; - } - return $groupby; - } -} diff --git a/src/RestApi/Version4_temp/class-wc-admin-rest-taxes-controller.php b/src/RestApi/Version4_temp/class-wc-admin-rest-taxes-controller.php deleted file mode 100644 index 06698aa8eb1..00000000000 --- a/src/RestApi/Version4_temp/class-wc-admin-rest-taxes-controller.php +++ /dev/null @@ -1,159 +0,0 @@ - __( 'Search by similar tax code.', 'woocommerce-admin' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['include'] = array( - 'description' => __( 'Limit result set to items that have the specified rate ID(s) assigned.', 'woocommerce-admin' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } - - /** - * Get all taxes and allow filtering by tax code. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - global $wpdb; - - $prepared_args = array(); - $prepared_args['order'] = $request['order']; - $prepared_args['number'] = $request['per_page']; - if ( ! empty( $request['offset'] ) ) { - $prepared_args['offset'] = $request['offset']; - } else { - $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; - } - $orderby_possibles = array( - 'id' => 'tax_rate_id', - 'order' => 'tax_rate_order', - ); - $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; - $prepared_args['class'] = $request['class']; - $prepared_args['code'] = $request['code']; - $prepared_args['include'] = $request['include']; - - /** - * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. - * - * @param array $prepared_args Array of arguments for $wpdb->get_results(). - * @param WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request ); - - $query = " - SELECT * - FROM {$wpdb->prefix}woocommerce_tax_rates - WHERE 1 = 1 - "; - - // Filter by tax class. - if ( ! empty( $prepared_args['class'] ) ) { - $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; - $query .= " AND tax_rate_class = '$class'"; - } - - // Filter by tax code. - $tax_code_search = $prepared_args['code']; - if ( $tax_code_search ) { - $tax_code_search = $wpdb->esc_like( $tax_code_search ); - $tax_code_search = ' \'%' . $tax_code_search . '%\''; - $query .= ' AND CONCAT_WS( "-", NULLIF(tax_rate_country, ""), NULLIF(tax_rate_state, ""), NULLIF(tax_rate_name, ""), NULLIF(tax_rate_priority, "") ) LIKE ' . $tax_code_search; - } - - // Filter by included tax rate IDs. - $included_taxes = $prepared_args['include']; - if ( ! empty( $included_taxes ) ) { - $included_taxes = implode( ',', $prepared_args['include'] ); - $query .= " AND tax_rate_id IN ({$included_taxes})"; - } - - // Order tax rates. - $order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) ); - - // Pagination. - $pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] ); - - // Query taxes. - $results = $wpdb->get_results( $query . $order_by . $pagination ); // @codingStandardsIgnoreLine. - - $taxes = array(); - foreach ( $results as $tax ) { - $data = $this->prepare_item_for_response( $tax, $request ); - $taxes[] = $this->prepare_response_for_collection( $data ); - } - - $response = rest_ensure_response( $taxes ); - - // Store pagination values for headers then unset for count query. - $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); - - // Query only for ids. - $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); // @codingStandardsIgnoreLine. - - // Calculate totals. - $total_taxes = (int) $wpdb->num_rows; - $response->header( 'X-WP-Total', (int) $total_taxes ); - $max_pages = ceil( $total_taxes / $per_page ); - $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; - } -} From c6cb9d0be9afe4759ba0652a6f2dcef620025ca8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:32:10 +0100 Subject: [PATCH 034/440] Replace textdomains --- src/RestApi/Version4/Controllers/Reports.php | 38 +++---- ...min-rest-reports-categories-controller.php | 49 ++++----- ...class-wc-admin-rest-reports-controller.php | 38 +++---- ...-admin-rest-reports-coupons-controller.php | 34 +++--- ...-rest-reports-coupons-stats-controller.php | 46 ++++---- ...dmin-rest-reports-customers-controller.php | 100 +++++++++--------- ...est-reports-customers-stats-controller.php | 70 ++++++------ ...dmin-rest-reports-downloads-controller.php | 56 +++++----- ...est-reports-downloads-stats-controller.php | 50 ++++----- ...c-admin-rest-reports-import-controller.php | 12 +-- ...c-admin-rest-reports-orders-controller.php | 50 ++++----- ...n-rest-reports-orders-stats-controller.php | 76 ++++++------- ...orts-performance-indicators-controller.php | 22 ++-- ...admin-rest-reports-products-controller.php | 48 ++++----- ...rest-reports-products-stats-controller.php | 52 ++++----- ...-rest-reports-revenue-stats-controller.php | 58 +++++----- ...wc-admin-rest-reports-stock-controller.php | 34 +++--- ...in-rest-reports-stock-stats-controller.php | 8 +- ...wc-admin-rest-reports-taxes-controller.php | 34 +++--- ...in-rest-reports-taxes-stats-controller.php | 50 ++++----- ...min-rest-reports-variations-controller.php | 44 ++++---- .../class-wc-admin-rest-data-controller.php | 2 +- ...dmin-rest-data-download-ips-controller.php | 6 +- ...-wc-admin-rest-leaderboards-controller.php | 56 +++++----- ...dmin-rest-onboarding-levels-controller.php | 38 +++---- ...min-rest-onboarding-plugins-controller.php | 26 ++--- ...min-rest-onboarding-profile-controller.php | 26 ++--- ...min-rest-product-variations-controller.php | 8 +- 28 files changed, 566 insertions(+), 565 deletions(-) diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php index 6105a7625e6..76113202b5d 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -59,7 +59,7 @@ class Reports extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -77,63 +77,63 @@ class Reports extends WC_REST_Controller { $reports = array( array( 'slug' => 'performance-indicators', - 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce-admin' ), + 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce' ), ), array( 'slug' => 'revenue/stats', - 'description' => __( 'Stats about revenue.', 'woocommerce-admin' ), + 'description' => __( 'Stats about revenue.', 'woocommerce' ), ), array( 'slug' => 'orders/stats', - 'description' => __( 'Stats about orders.', 'woocommerce-admin' ), + 'description' => __( 'Stats about orders.', 'woocommerce' ), ), array( 'slug' => 'products', - 'description' => __( 'Products detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Products detailed reports.', 'woocommerce' ), ), array( 'slug' => 'products/stats', - 'description' => __( 'Stats about products.', 'woocommerce-admin' ), + 'description' => __( 'Stats about products.', 'woocommerce' ), ), array( 'slug' => 'categories', - 'description' => __( 'Product categories detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Product categories detailed reports.', 'woocommerce' ), ), array( 'slug' => 'categories/stats', - 'description' => __( 'Stats about product categories.', 'woocommerce-admin' ), + 'description' => __( 'Stats about product categories.', 'woocommerce' ), ), array( 'slug' => 'coupons', - 'description' => __( 'Coupons detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Coupons detailed reports.', 'woocommerce' ), ), array( 'slug' => 'coupons/stats', - 'description' => __( 'Stats about coupons.', 'woocommerce-admin' ), + 'description' => __( 'Stats about coupons.', 'woocommerce' ), ), array( 'slug' => 'taxes', - 'description' => __( 'Taxes detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Taxes detailed reports.', 'woocommerce' ), ), array( 'slug' => 'taxes/stats', - 'description' => __( 'Stats about taxes.', 'woocommerce-admin' ), + 'description' => __( 'Stats about taxes.', 'woocommerce' ), ), array( 'slug' => 'downloads', - 'description' => __( 'Product downloads detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Product downloads detailed reports.', 'woocommerce' ), ), array( 'slug' => 'downloads/files', - 'description' => __( 'Product download files detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Product download files detailed reports.', 'woocommerce' ), ), array( 'slug' => 'downloads/stats', - 'description' => __( 'Stats about product downloads.', 'woocommerce-admin' ), + 'description' => __( 'Stats about product downloads.', 'woocommerce' ), ), array( 'slug' => 'customers', - 'description' => __( 'Customers detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Customers detailed reports.', 'woocommerce' ), ), ); @@ -253,19 +253,19 @@ class Reports extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-admin' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human-readable description of the resource.', 'woocommerce-admin' ), + 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'path' => array( - 'description' => __( 'API path.', 'woocommerce-admin' ), + 'description' => __( 'API path.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php index ded3e478ffa..2a1fff9fd04 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/categories endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WC_Admin_REST_Reports_Controller; + /** - * REST API Reports categories controller class. - * - * @package WooCommerce/API - * @extends WC_Admin_REST_Reports_Controller + * REST API Category Reports class. */ -class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_Controller { +class Categories extends WC_Admin_REST_Reports_Controller { /** * Endpoint namespace. @@ -70,7 +71,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ } 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-admin' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_reports_categories_invalid_response', __( 'Invalid response from data store.', 'woocommerce' ), array( 'status' => 500 ) ); } $out_data = array(); @@ -162,31 +163,31 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ 'type' => 'object', 'properties' => array( 'category_id' => array( - 'description' => __( 'Category ID.', 'woocommerce-admin' ), + 'description' => __( 'Category ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'items_sold' => array( - 'description' => __( 'Amount of items sold.', 'woocommerce-admin' ), + 'description' => __( 'Amount of items sold.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'net_revenue' => array( - 'description' => __( 'Gross revenue.', 'woocommerce-admin' ), + 'description' => __( 'Gross revenue.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + 'description' => __( 'Amount of orders.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'products_count' => array( - 'description' => __( 'Amount of products.', 'woocommerce-admin' ), + 'description' => __( 'Amount of products.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -196,7 +197,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Category name.', 'woocommerce-admin' ), + 'description' => __( 'Category name.', 'woocommerce' ), ), ), ), @@ -214,7 +215,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -222,7 +223,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -231,26 +232,26 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'category_id', 'enum' => array( @@ -264,7 +265,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ 'validate_callback' => 'rest_validate_request_arg', ); $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce-admin' ), + 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), 'type' => 'string', 'default' => 'week', 'enum' => array( @@ -278,7 +279,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ 'validate_callback' => 'rest_validate_request_arg', ); $params['status_is'] = array( - 'description' => __( 'Limit result set to items that have the specified order status.', 'woocommerce-admin' ), + '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', @@ -288,7 +289,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ ), ); $params['status_is_not'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order status.', 'woocommerce-admin' ), + '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', @@ -298,7 +299,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ ), ); $params['categories'] = array( - 'description' => __( 'Limit result set to all items that have the specified term assigned in the categories taxonomy.', 'woocommerce-admin' ), + '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', @@ -307,7 +308,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_Admin_REST_Reports_ ), ); $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each category to the report.', 'woocommerce-admin' ), + 'description' => __( 'Add additional piece of info about each category to the report.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'wc_string_to_bool', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php index 443e149c5c0..5cae9909de9 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php @@ -58,7 +58,7 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -76,63 +76,63 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller { $reports = array( array( 'slug' => 'performance-indicators', - 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce-admin' ), + 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce' ), ), array( 'slug' => 'revenue/stats', - 'description' => __( 'Stats about revenue.', 'woocommerce-admin' ), + 'description' => __( 'Stats about revenue.', 'woocommerce' ), ), array( 'slug' => 'orders/stats', - 'description' => __( 'Stats about orders.', 'woocommerce-admin' ), + 'description' => __( 'Stats about orders.', 'woocommerce' ), ), array( 'slug' => 'products', - 'description' => __( 'Products detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Products detailed reports.', 'woocommerce' ), ), array( 'slug' => 'products/stats', - 'description' => __( 'Stats about products.', 'woocommerce-admin' ), + 'description' => __( 'Stats about products.', 'woocommerce' ), ), array( 'slug' => 'categories', - 'description' => __( 'Product categories detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Product categories detailed reports.', 'woocommerce' ), ), array( 'slug' => 'categories/stats', - 'description' => __( 'Stats about product categories.', 'woocommerce-admin' ), + 'description' => __( 'Stats about product categories.', 'woocommerce' ), ), array( 'slug' => 'coupons', - 'description' => __( 'Coupons detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Coupons detailed reports.', 'woocommerce' ), ), array( 'slug' => 'coupons/stats', - 'description' => __( 'Stats about coupons.', 'woocommerce-admin' ), + 'description' => __( 'Stats about coupons.', 'woocommerce' ), ), array( 'slug' => 'taxes', - 'description' => __( 'Taxes detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Taxes detailed reports.', 'woocommerce' ), ), array( 'slug' => 'taxes/stats', - 'description' => __( 'Stats about taxes.', 'woocommerce-admin' ), + 'description' => __( 'Stats about taxes.', 'woocommerce' ), ), array( 'slug' => 'downloads', - 'description' => __( 'Product downloads detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Product downloads detailed reports.', 'woocommerce' ), ), array( 'slug' => 'downloads/files', - 'description' => __( 'Product download files detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Product download files detailed reports.', 'woocommerce' ), ), array( 'slug' => 'downloads/stats', - 'description' => __( 'Stats about product downloads.', 'woocommerce-admin' ), + 'description' => __( 'Stats about product downloads.', 'woocommerce' ), ), array( 'slug' => 'customers', - 'description' => __( 'Customers detailed reports.', 'woocommerce-admin' ), + 'description' => __( 'Customers detailed reports.', 'woocommerce' ), ), ); @@ -252,19 +252,19 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-admin' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human-readable description of the resource.', 'woocommerce-admin' ), + 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'path' => array( - 'description' => __( 'API path.', 'woocommerce-admin' ), + 'description' => __( 'API path.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php index 8cc87aafcb4..f2146a7bfe3 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php @@ -150,19 +150,19 @@ class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controlle 'type' => 'object', 'properties' => array( 'coupon_id' => array( - 'description' => __( 'Coupon ID.', 'woocommerce-admin' ), + 'description' => __( 'Coupon ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'amount' => array( - 'description' => __( 'Net discount amount.', 'woocommerce-admin' ), + 'description' => __( 'Net discount amount.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + 'description' => __( 'Amount of orders.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -172,38 +172,38 @@ class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controlle 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Coupon code.', 'woocommerce-admin' ), + 'description' => __( 'Coupon code.', 'woocommerce' ), ), 'date_created' => array( 'type' => 'date-time', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Coupon creation date.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'Coupon creation date in GMT.', 'woocommerce' ), ), 'date_expires' => array( 'type' => 'date-time', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Coupon expiration date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Coupon discount type.', 'woocommerce' ), ), ), ), @@ -221,7 +221,7 @@ class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controlle $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -229,7 +229,7 @@ class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controlle 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -238,26 +238,26 @@ class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controlle 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'coupon_id', 'enum' => array( @@ -269,7 +269,7 @@ class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controlle 'validate_callback' => 'rest_validate_request_arg', ); $params['coupons'] = array( - 'description' => __( 'Limit result set to coupons assigned specific coupon IDs.', 'woocommerce-admin' ), + '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', @@ -278,7 +278,7 @@ class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controlle ), ); $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each coupon to the report.', 'woocommerce-admin' ), + 'description' => __( 'Add additional piece of info about each coupon to the report.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'wc_string_to_bool', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php index 2b4e975b8c6..a416a57dc3f 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php @@ -139,7 +139,7 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con public function get_item_schema() { $data_values = array( 'amount' => array( - 'description' => __( 'Net discount amount.', 'woocommerce-admin' ), + 'description' => __( 'Net discount amount.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -147,13 +147,13 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con 'format' => 'currency', ), 'coupons_count' => array( - 'description' => __( 'Amount of coupons.', 'woocommerce-admin' ), + 'description' => __( 'Amount of coupons.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'orders_count' => array( - 'description' => __( 'Amount of discounted orders.', 'woocommerce-admin' ), + 'description' => __( 'Amount of discounted orders.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -163,7 +163,7 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con $segments = array( 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -171,13 +171,13 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con 'type' => 'object', 'properties' => array( 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'description' => __( 'Segment identificator.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -196,14 +196,14 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con 'type' => 'object', 'properties' => array( 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce-admin' ), + 'description' => __( 'Totals data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => $totals, ), 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -211,38 +211,38 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con 'type' => 'object', 'properties' => array( 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -266,7 +266,7 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -274,7 +274,7 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -283,26 +283,26 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -314,7 +314,7 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con 'validate_callback' => 'rest_validate_request_arg', ); $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce-admin' ), + 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), 'type' => 'string', 'default' => 'week', 'enum' => array( @@ -328,7 +328,7 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con 'validate_callback' => 'rest_validate_request_arg', ); $params['coupons'] = array( - 'description' => __( 'Limit result set to coupons assigned specific coupon IDs.', 'woocommerce-admin' ), + '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', @@ -337,7 +337,7 @@ class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Con ), ); $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce-admin' ), + 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'product', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php index f29bde23d0b..02b974cc922 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php @@ -182,85 +182,85 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Customer ID.', 'woocommerce-admin' ), + 'description' => __( 'Customer ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'user_id' => array( - 'description' => __( 'User ID.', 'woocommerce-admin' ), + 'description' => __( 'User ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Name.', 'woocommerce-admin' ), + 'description' => __( 'Name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'username' => array( - 'description' => __( 'Username.', 'woocommerce-admin' ), + 'description' => __( 'Username.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'country' => array( - 'description' => __( 'Country.', 'woocommerce-admin' ), + 'description' => __( 'Country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'city' => array( - 'description' => __( 'City.', 'woocommerce-admin' ), + 'description' => __( 'City.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-admin' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_registered' => array( - 'description' => __( 'Date registered.', 'woocommerce-admin' ), + 'description' => __( 'Date registered.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_registered_gmt' => array( - 'description' => __( 'Date registered GMT.', 'woocommerce-admin' ), + 'description' => __( 'Date registered GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_last_active' => array( - 'description' => __( 'Date last active.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'Date last active GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'orders_count' => array( - 'description' => __( 'Order count.', 'woocommerce-admin' ), + 'description' => __( 'Order count.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_spend' => array( - 'description' => __( 'Total spend.', 'woocommerce-admin' ), + 'description' => __( 'Total spend.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avg_order_value' => array( - 'description' => __( 'Avg order value.', 'woocommerce-admin' ), + 'description' => __( 'Avg order value.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -279,31 +279,31 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -311,7 +311,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -320,14 +320,14 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date_registered', 'enum' => array( @@ -345,7 +345,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control '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-admin' ), + '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( @@ -355,7 +355,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control '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-admin' ), + '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', ); @@ -370,140 +370,140 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control ), ); $params['name_includes'] = array( - 'description' => __( 'Limit response to objects with specfic names.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Limit result to items with specified customer ids.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php index 0012807e565..5b076fa929b 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php @@ -126,26 +126,26 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C // @todo Should any of these be 'indicator's? $totals = array( 'customers_count' => array( - 'description' => __( 'Number of customers.', 'woocommerce-admin' ), + 'description' => __( 'Number of customers.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avg_orders_count' => array( - 'description' => __( 'Average number of orders.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Average AOV per customer.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -159,7 +159,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C 'type' => 'object', 'properties' => array( 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce-admin' ), + 'description' => __( 'Totals data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -180,19 +180,19 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $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-admin' ), + '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-admin' ), + '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-admin' ), + '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( @@ -202,7 +202,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C '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-admin' ), + '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', ); @@ -217,140 +217,140 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C ), ); $params['name_includes'] = array( - 'description' => __( 'Limit response to objects with specfic names.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Limit result to items with specified customer ids.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php index 2b23d52b27c..9ce998461af 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php @@ -157,22 +157,22 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'ID.', 'woocommerce-admin' ), + 'description' => __( 'ID.', 'woocommerce' ), ), 'product_id' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce-admin' ), + 'description' => __( 'Product ID.', 'woocommerce' ), ), 'date' => array( - 'description' => __( "The date of the download, in the site's timezone.", 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'The date of the download, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -181,55 +181,55 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Download ID.', 'woocommerce-admin' ), + 'description' => __( 'Download ID.', 'woocommerce' ), ), 'file_name' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'File name.', 'woocommerce-admin' ), + 'description' => __( 'File name.', 'woocommerce' ), ), 'file_path' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'File URL.', 'woocommerce-admin' ), + 'description' => __( 'File URL.', 'woocommerce' ), ), 'product_id' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce-admin' ), + 'description' => __( 'Product ID.', 'woocommerce' ), ), 'order_id' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Order ID.', 'woocommerce-admin' ), + 'description' => __( 'Order ID.', 'woocommerce' ), ), 'order_number' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Order Number.', 'woocommerce-admin' ), + 'description' => __( 'Order Number.', 'woocommerce' ), ), 'user_id' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'User ID for the downloader.', 'woocommerce-admin' ), + 'description' => __( 'User ID for the downloader.', 'woocommerce' ), ), 'username' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'User name of the downloader.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'IP address for the downloader.', 'woocommerce' ), ), ), ); @@ -246,7 +246,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -254,7 +254,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -263,26 +263,26 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -292,7 +292,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C '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-admin' ), + '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( @@ -302,7 +302,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C 'validate_callback' => 'rest_validate_request_arg', ); $params['product_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -312,7 +312,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C '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-admin' ), + 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -322,7 +322,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C 'sanitize_callback' => 'wp_parse_id_list', ); $params['order_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified order ids.', 'woocommerce-admin' ), + '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', @@ -331,7 +331,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C ), ); $params['order_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order ids.', 'woocommerce-admin' ), + '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', @@ -340,7 +340,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C ), ); $params['customer_includes'] = array( - 'description' => __( 'Limit response to objects that have the specified user ids.', 'woocommerce-admin' ), + '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', @@ -349,7 +349,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C ), ); $params['customer_excludes'] = array( - 'description' => __( 'Limit response to objects that don\'t have the specified user ids.', 'woocommerce-admin' ), + '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', @@ -358,7 +358,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C ), ); $params['ip_address_includes'] = array( - 'description' => __( 'Limit response to objects that have a specified ip address.', 'woocommerce-admin' ), + 'description' => __( 'Limit response to objects that have a specified ip address.', 'woocommerce' ), 'type' => 'array', 'validate_callback' => 'rest_validate_request_arg', 'items' => array( @@ -367,7 +367,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_C ); $params['ip_address_excludes'] = array( - 'description' => __( 'Limit response to objects that don\'t have a specified ip address.', 'woocommerce-admin' ), + 'description' => __( 'Limit response to objects that don\'t have a specified ip address.', 'woocommerce' ), 'type' => 'array', 'validate_callback' => 'rest_validate_request_arg', 'items' => array( diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php index f627a57894f..4a0234449af 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php @@ -141,7 +141,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C public function get_item_schema() { $totals = array( 'download_count' => array( - 'description' => __( 'Number of downloads.', 'woocommerce-admin' ), + 'description' => __( 'Number of downloads.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -155,14 +155,14 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C 'type' => 'object', 'properties' => array( 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce-admin' ), + 'description' => __( 'Totals data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => $totals, ), 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -170,38 +170,38 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C 'type' => 'object', 'properties' => array( 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -225,7 +225,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -233,7 +233,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -242,26 +242,26 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -271,7 +271,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C 'validate_callback' => 'rest_validate_request_arg', ); $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce-admin' ), + 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), 'type' => 'string', 'default' => 'week', 'enum' => array( @@ -285,7 +285,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C '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-admin' ), + '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( @@ -295,7 +295,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C 'validate_callback' => 'rest_validate_request_arg', ); $params['product_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -305,7 +305,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C ); $params['product_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -314,7 +314,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C 'sanitize_callback' => 'wp_parse_id_list', ); $params['order_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified order ids.', 'woocommerce-admin' ), + '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', @@ -323,7 +323,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C ), ); $params['order_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order ids.', 'woocommerce-admin' ), + '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', @@ -332,7 +332,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C ), ); $params['customer_includes'] = array( - 'description' => __( 'Limit response to objects that have the specified customer ids.', 'woocommerce-admin' ), + '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', @@ -341,7 +341,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C ), ); $params['customer_excludes'] = array( - 'description' => __( 'Limit response to objects that don\'t have the specified customer ids.', 'woocommerce-admin' ), + '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', @@ -350,7 +350,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C ), ); $params['ip_address_includes'] = array( - 'description' => __( 'Limit response to objects that have a specified ip address.', 'woocommerce-admin' ), + 'description' => __( 'Limit response to objects that have a specified ip address.', 'woocommerce' ), 'type' => 'array', 'validate_callback' => 'rest_validate_request_arg', 'items' => array( @@ -359,7 +359,7 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C ); $params['ip_address_excludes'] = array( - 'description' => __( 'Limit response to objects that don\'t have a specified ip address.', 'woocommerce-admin' ), + 'description' => __( 'Limit response to objects that don\'t have a specified ip address.', 'woocommerce' ), 'type' => 'array', 'validate_callback' => 'rest_validate_request_arg', 'items' => array( diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php index ad3c37af911..b0f16d997b4 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php @@ -106,7 +106,7 @@ class WC_Admin_REST_Reports_Import_Controller extends WC_Admin_REST_Reports_Cont */ 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-admin' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -183,14 +183,14 @@ class WC_Admin_REST_Reports_Import_Controller extends WC_Admin_REST_Reports_Cont public function get_import_collection_params() { $params = array(); $params['days'] = array( - 'description' => __( 'Number of days to import.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'Skip importing existing order data.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'wc_string_to_bool', @@ -211,13 +211,13 @@ class WC_Admin_REST_Reports_Import_Controller extends WC_Admin_REST_Reports_Cont 'type' => 'object', 'properties' => array( 'status' => array( - 'description' => __( 'Regeneration status.', 'woocommerce-admin' ), + 'description' => __( 'Regeneration status.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'message' => array( - 'description' => __( 'Regenerate data message.', 'woocommerce-admin' ), + 'description' => __( 'Regenerate data message.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -239,7 +239,7 @@ class WC_Admin_REST_Reports_Import_Controller extends WC_Admin_REST_Reports_Cont $result = array( 'status' => 'success', - 'message' => __( 'All pending and in-progress import actions have been cancelled.', 'woocommerce-admin' ), + 'message' => __( 'All pending and in-progress import actions have been cancelled.', 'woocommerce' ), ); $response = $this->prepare_item_for_response( $result, $request ); diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php index 2e6f171709f..20535bd3632 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php @@ -158,49 +158,49 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'type' => 'object', 'properties' => array( 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce-admin' ), + 'description' => __( 'Order ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'order_number' => array( - 'description' => __( 'Order Number.', 'woocommerce-admin' ), + 'description' => __( 'Order Number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( 'Date the order was created.', 'woocommerce-admin' ), + 'description' => __( 'Date the order was created.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Order status.', 'woocommerce-admin' ), + 'description' => __( 'Order status.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_id' => array( - 'description' => __( 'Customer ID.', 'woocommerce-admin' ), + 'description' => __( 'Customer ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'num_items_sold' => array( - 'description' => __( 'Number of items sold.', 'woocommerce-admin' ), + 'description' => __( 'Number of items sold.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'net_total' => array( - 'description' => __( 'Net total revenue.', 'woocommerce-admin' ), + 'description' => __( 'Net total revenue.', 'woocommerce' ), 'type' => 'float', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_type' => array( - 'description' => __( 'Returning or new customer.', 'woocommerce-admin' ), + 'description' => __( 'Returning or new customer.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -210,13 +210,13 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'List of product IDs and names.', 'woocommerce-admin' ), + 'description' => __( 'List of product IDs and names.', 'woocommerce' ), ), 'categories' => array( 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Category IDs.', 'woocommerce-admin' ), + 'description' => __( 'Category IDs.', 'woocommerce' ), ), ), ), @@ -234,7 +234,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -242,7 +242,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 0, @@ -251,26 +251,26 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -281,7 +281,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'validate_callback' => 'rest_validate_request_arg', ); $params['product_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -291,7 +291,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont '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-admin' ), + 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -301,7 +301,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'sanitize_callback' => 'wp_parse_id_list', ); $params['coupon_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified coupon(s) assigned.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to items that have the specified coupon(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -311,7 +311,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont '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-admin' ), + 'description' => __( 'Limit result set to items that don\'t have the specified coupon(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -321,7 +321,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'sanitize_callback' => 'wp_parse_id_list', ); $params['status_is'] = array( - 'description' => __( 'Limit result set to items that have the specified order status.', 'woocommerce-admin' ), + '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', @@ -331,7 +331,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont ), ); $params['status_is_not'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order status.', 'woocommerce-admin' ), + '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', @@ -341,7 +341,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont ), ); $params['customer_type'] = array( - 'description' => __( 'Limit result set to returning or new customers.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to returning or new customers.', 'woocommerce' ), 'type' => 'string', 'default' => '', 'enum' => array( @@ -352,7 +352,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'validate_callback' => 'rest_validate_request_arg', ); $params['refunds'] = array( - 'description' => __( 'Limit result set to specific types of refunds.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to specific types of refunds.', 'woocommerce' ), 'type' => 'string', 'default' => '', 'enum' => array( @@ -365,7 +365,7 @@ class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Cont 'validate_callback' => 'rest_validate_request_arg', ); $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each coupon to the report.', 'woocommerce-admin' ), + 'description' => __( 'Add additional piece of info about each coupon to the report.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'wc_string_to_bool', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php index 0e0f89243b9..33a2fc4aa87 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php @@ -148,21 +148,21 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report public function get_item_schema() { $data_values = array( 'net_revenue' => array( - 'description' => __( 'Net revenue.', 'woocommerce-admin' ), + 'description' => __( 'Net revenue.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'format' => 'currency', ), 'orders_count' => array( - 'description' => __( 'Amount of orders', 'woocommerce-admin' ), + 'description' => __( 'Amount of orders', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'indicator' => true, ), 'avg_order_value' => array( - 'description' => __( 'Average order value.', 'woocommerce-admin' ), + 'description' => __( 'Average order value.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -170,43 +170,43 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'format' => 'currency', ), 'avg_items_per_order' => array( - 'description' => __( 'Average items per order', 'woocommerce-admin' ), + 'description' => __( 'Average items per order', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'num_items_sold' => array( - 'description' => __( 'Number of items sold', 'woocommerce-admin' ), + 'description' => __( 'Number of items sold', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'coupons' => array( - 'description' => __( 'Amount discounted by coupons.', 'woocommerce-admin' ), + 'description' => __( 'Amount discounted by coupons.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'coupons_count' => array( - 'description' => __( 'Unique coupons count.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Number of distinct products sold.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -215,7 +215,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report $segments = array( 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -223,13 +223,13 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'type' => 'object', 'properties' => array( 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'description' => __( 'Segment identificator.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -253,14 +253,14 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'type' => 'object', 'properties' => array( 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce-admin' ), + 'description' => __( 'Totals data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => $totals, ), 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -268,38 +268,38 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'type' => 'object', 'properties' => array( 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -323,7 +323,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -331,7 +331,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -340,26 +340,26 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -371,7 +371,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'validate_callback' => 'rest_validate_request_arg', ); $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce-admin' ), + 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), 'type' => 'string', 'default' => 'week', 'enum' => array( @@ -385,7 +385,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report '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-admin' ), + '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( @@ -395,7 +395,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'validate_callback' => 'rest_validate_request_arg', ); $params['status_is'] = array( - 'description' => __( 'Limit result set to items that have the specified order status.', 'woocommerce-admin' ), + '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', @@ -406,7 +406,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report ), ); $params['status_is_not'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified order status.', 'woocommerce-admin' ), + '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', @@ -416,7 +416,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report ), ); $params['product_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -426,7 +426,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report ); $params['product_excludes'] = array( - 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -435,7 +435,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'sanitize_callback' => 'wp_parse_id_list', ); $params['coupon_includes'] = array( - 'description' => __( 'Limit result set to items that have the specified coupon(s) assigned.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to items that have the specified coupon(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -444,7 +444,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report '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-admin' ), + 'description' => __( 'Limit result set to items that don\'t have the specified coupon(s) assigned.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -453,7 +453,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report '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-admin' ), + 'description' => __( 'Limit result set to items that don\'t have the specified coupon(s) assigned.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'new', @@ -462,7 +462,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'validate_callback' => 'rest_validate_request_arg', ); $params['refunds'] = array( - 'description' => __( 'Limit result set to specific types of refunds.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to specific types of refunds.', 'woocommerce' ), 'type' => 'string', 'default' => '', 'enum' => array( @@ -475,7 +475,7 @@ class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Report 'validate_callback' => 'rest_validate_request_arg', ); $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce-admin' ), + 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'product', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php index 1e4cf18a06b..84ad882da6a 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php @@ -122,7 +122,7 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re $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-admin' ) ); + return new WP_Error( 'woocommerce_reports_performance_indicators_result_failed', __( 'Sorry, fetching performance indicators failed.', 'woocommerce' ) ); } foreach ( $endpoints as $endpoint ) { @@ -261,7 +261,7 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re $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-admin' ), 400 ); + return new WP_Error( 'woocommerce_reports_performance_indicators_empty_query', __( 'A list of stats to query must be provided.', 'woocommerce' ), 400 ); } $stats = array(); @@ -412,33 +412,33 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re 'type' => 'object', 'properties' => array( 'stat' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Human readable label for the stat.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'format' => array( - 'description' => __( 'Format of the stat.', 'woocommerce-admin' ), + '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-admin' ), + '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, @@ -469,7 +469,7 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re 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-admin' ); + $allowed_stats = __( 'There was an issue loading the report endpoints', 'woocommerce' ); } else { $allowed_stats = implode( ', ', $this->allowed_stats ); } @@ -479,7 +479,7 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re $params['stats'] = array( 'description' => sprintf( /* translators: Allowed values is a list of stat endpoints. */ - __( 'Limit response to specific report stats. Allowed values: %s.', 'woocommerce-admin' ), + __( 'Limit response to specific report stats. Allowed values: %s.', 'woocommerce' ), $allowed_stats ), 'type' => 'array', @@ -489,13 +489,13 @@ class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Re ), ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php index 0e34901149d..ef64c8aae10 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php @@ -155,86 +155,86 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce-admin' ), + 'description' => __( 'Product ID.', 'woocommerce' ), ), 'items_sold' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Number of items sold.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Product name.', 'woocommerce' ), ), 'price' => array( 'type' => 'number', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product price.', 'woocommerce-admin' ), + 'description' => __( 'Product price.', 'woocommerce' ), ), 'image' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product image.', 'woocommerce-admin' ), + 'description' => __( 'Product image.', 'woocommerce' ), ), 'permalink' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product link.', 'woocommerce-admin' ), + 'description' => __( 'Product link.', 'woocommerce' ), ), 'attributes' => array( 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product attributes.', 'woocommerce-admin' ), + 'description' => __( 'Product attributes.', 'woocommerce' ), ), 'stock_status' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory status.', 'woocommerce-admin' ), + 'description' => __( 'Product inventory status.', 'woocommerce' ), ), 'stock_quantity' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory quantity.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'Product inventory threshold for low stock.', 'woocommerce' ), ), 'variations' => array( 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product variations IDs.', 'woocommerce-admin' ), + 'description' => __( 'Product variations IDs.', 'woocommerce' ), ), 'sku' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product SKU.', 'woocommerce-admin' ), + 'description' => __( 'Product SKU.', 'woocommerce' ), ), ), ), @@ -252,7 +252,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -260,7 +260,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -269,26 +269,26 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -303,7 +303,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll 'validate_callback' => 'rest_validate_request_arg', ); $params['categories'] = array( - 'description' => __( 'Limit result to items from the specified categories.', 'woocommerce-admin' ), + 'description' => __( 'Limit result to items from the specified categories.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -312,7 +312,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll ), ); $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-admin' ), + '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( @@ -322,7 +322,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll 'validate_callback' => 'rest_validate_request_arg', ); $params['products'] = array( - 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce-admin' ), + 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -332,7 +332,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll ); $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each product to the report.', 'woocommerce-admin' ), + 'description' => __( 'Add additional piece of info about each product to the report.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'wc_string_to_bool', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php index fd9fd4bd390..3cfeb1c6f3c 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php @@ -153,21 +153,21 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co public function get_item_schema() { $data_values = array( 'items_sold' => array( - 'description' => __( 'Number of items sold.', 'woocommerce-admin' ), + 'description' => __( 'Number of items sold.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'indicator' => true, ), 'net_revenue' => array( - 'description' => __( 'Net revenue.', 'woocommerce-admin' ), + 'description' => __( 'Net revenue.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'format' => 'currency', ), 'orders_count' => array( - 'description' => __( 'Number of orders.', 'woocommerce-admin' ), + 'description' => __( 'Number of orders.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -176,7 +176,7 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co $segments = array( 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -184,20 +184,20 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co 'type' => 'object', 'properties' => array( 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -216,14 +216,14 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co 'type' => 'object', 'properties' => array( 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce-admin' ), + 'description' => __( 'Totals data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => $totals, ), 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -231,38 +231,38 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co 'type' => 'object', 'properties' => array( 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -307,7 +307,7 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -315,7 +315,7 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -324,26 +324,26 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -360,7 +360,7 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co 'validate_callback' => 'rest_validate_request_arg', ); $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce-admin' ), + 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), 'type' => 'string', 'default' => 'week', 'enum' => array( @@ -374,7 +374,7 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co 'validate_callback' => 'rest_validate_request_arg', ); $params['categories'] = array( - 'description' => __( 'Limit result to items from the specified categories.', 'woocommerce-admin' ), + 'description' => __( 'Limit result to items from the specified categories.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -383,7 +383,7 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co ), ); $params['products'] = array( - 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce-admin' ), + 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -392,7 +392,7 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co ), ); $params['variations'] = array( - 'description' => __( 'Limit result to items with specified variation ids.', 'woocommerce-admin' ), + 'description' => __( 'Limit result to items with specified variation ids.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -401,7 +401,7 @@ class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Co ), ); $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce-admin' ), + 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'product', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php index 9d9c72c5b93..33c78e1e35e 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php @@ -137,7 +137,7 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con public function get_item_schema() { $data_values = array( 'gross_revenue' => array( - 'description' => __( 'Gross revenue.', 'woocommerce-admin' ), + 'description' => __( 'Gross revenue.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -145,7 +145,7 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'format' => 'currency', ), 'net_revenue' => array( - 'description' => __( 'Net revenue.', 'woocommerce-admin' ), + 'description' => __( 'Net revenue.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -153,20 +153,20 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'format' => 'currency', ), 'coupons' => array( - 'description' => __( 'Amount discounted by coupons.', 'woocommerce-admin' ), + 'description' => __( 'Amount discounted by coupons.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'coupons_count' => array( - 'description' => __( 'Unique coupons count.', 'woocommerce-admin' ), + 'description' => __( 'Unique coupons count.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'format' => 'currency', ), 'shipping' => array( - 'description' => __( 'Total of shipping.', 'woocommerce-admin' ), + 'description' => __( 'Total of shipping.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -174,14 +174,14 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'format' => 'currency', ), 'taxes' => array( - 'description' => __( 'Total of taxes.', 'woocommerce-admin' ), + 'description' => __( 'Total of taxes.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'format' => 'currency', ), 'refunds' => array( - 'description' => __( 'Total of refunds.', 'woocommerce-admin' ), + 'description' => __( 'Total of refunds.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -189,19 +189,19 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'format' => 'currency', ), 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + 'description' => __( 'Amount of orders.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'num_items_sold' => array( - 'description' => __( 'Items sold.', 'woocommerce-admin' ), + 'description' => __( 'Items sold.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'products' => array( - 'description' => __( 'Products sold.', 'woocommerce-admin' ), + 'description' => __( 'Products sold.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -210,7 +210,7 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con $segments = array( 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -218,13 +218,13 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'type' => 'object', 'properties' => array( 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'description' => __( 'Segment identificator.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -248,14 +248,14 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'type' => 'object', 'properties' => array( 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce-admin' ), + 'description' => __( 'Totals data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => $totals, ), 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -263,38 +263,38 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'type' => 'object', 'properties' => array( 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -318,7 +318,7 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -326,7 +326,7 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -335,26 +335,26 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -371,7 +371,7 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'validate_callback' => 'rest_validate_request_arg', ); $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce-admin' ), + 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), 'type' => 'string', 'default' => 'week', 'enum' => array( @@ -385,7 +385,7 @@ class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Con 'validate_callback' => 'rest_validate_request_arg', ); $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce-admin' ), + 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'product', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php index 1fc5eefbbb3..7a4c4535f8c 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php @@ -270,44 +270,44 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-admin' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-admin' ), + 'description' => __( 'Product parent ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-admin' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-admin' ), + 'description' => __( 'Unique identifier.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'stock_status' => array( - 'description' => __( 'Stock status.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'Stock quantity.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'manage_stock' => array( - 'description' => __( 'Manage stock.', 'woocommerce-admin' ), + 'description' => __( 'Manage stock.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -327,7 +327,7 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -335,7 +335,7 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -344,7 +344,7 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller 'validate_callback' => 'rest_validate_request_arg', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-admin' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -353,7 +353,7 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -362,20 +362,20 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'stock_status', 'enum' => array( @@ -390,7 +390,7 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller 'validate_callback' => 'rest_validate_request_arg', ); $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -399,7 +399,7 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller 'default' => array(), ); $params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce-admin' ), + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -408,7 +408,7 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller 'default' => array(), ); $params['type'] = array( - 'description' => __( 'Limit result set to items assigned a stock report type.', 'woocommerce-admin' ), + '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() ) ), diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php index c4782dd8e9d..6d3b091da56 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php @@ -83,13 +83,13 @@ class WC_Admin_REST_Reports_Stock_Stats_Controller extends WC_REST_Reports_Contr public function get_item_schema() { $totals = array( 'products' => array( - 'description' => __( 'Number of products.', 'woocommerce-admin' ), + 'description' => __( 'Number of products.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'lowstock' => array( - 'description' => __( 'Number of low stock products.', 'woocommerce-admin' ), + 'description' => __( 'Number of low stock products.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -100,7 +100,7 @@ class WC_Admin_REST_Reports_Stock_Stats_Controller extends WC_REST_Reports_Contr 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-admin' ), $label ), + 'description' => sprintf( __( 'Number of %s products.', 'woocommerce' ), $label ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -113,7 +113,7 @@ class WC_Admin_REST_Reports_Stock_Stats_Controller extends WC_REST_Reports_Contr 'type' => 'object', 'properties' => array( 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce-admin' ), + 'description' => __( 'Totals data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php index 6729c9a3e89..b4f1ca1f968 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php @@ -148,61 +148,61 @@ class WC_Admin_REST_Reports_Taxes_Controller extends WC_REST_Reports_Controller 'type' => 'object', 'properties' => array( 'tax_rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-admin' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Tax rate name.', 'woocommerce-admin' ), + 'description' => __( 'Tax rate name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_rate' => array( - 'description' => __( 'Tax rate.', 'woocommerce-admin' ), + 'description' => __( 'Tax rate.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'country' => array( - 'description' => __( 'Country.', 'woocommerce-admin' ), + 'description' => __( 'Country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'state' => array( - 'description' => __( 'State.', 'woocommerce-admin' ), + 'description' => __( 'State.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'priority' => array( - 'description' => __( 'Priority.', 'woocommerce-admin' ), + 'description' => __( 'Priority.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Total tax.', 'woocommerce-admin' ), + 'description' => __( 'Total tax.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'order_tax' => array( - 'description' => __( 'Order tax.', 'woocommerce-admin' ), + 'description' => __( 'Order tax.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax' => array( - 'description' => __( 'Shipping tax.', 'woocommerce-admin' ), + 'description' => __( 'Shipping tax.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + 'description' => __( 'Amount of orders.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -222,7 +222,7 @@ class WC_Admin_REST_Reports_Taxes_Controller extends WC_REST_Reports_Controller $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -230,7 +230,7 @@ class WC_Admin_REST_Reports_Taxes_Controller extends WC_REST_Reports_Controller 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -239,26 +239,26 @@ class WC_Admin_REST_Reports_Taxes_Controller extends WC_REST_Reports_Controller 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'tax_rate_id', 'enum' => array( @@ -274,7 +274,7 @@ class WC_Admin_REST_Reports_Taxes_Controller extends WC_REST_Reports_Controller 'validate_callback' => 'rest_validate_request_arg', ); $params['taxes'] = array( - 'description' => __( 'Limit result set to items assigned one or more tax rates.', 'woocommerce-admin' ), + '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', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php index 340f142a795..35d7baf8e7e 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php @@ -164,7 +164,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr public function get_item_schema() { $data_values = array( 'total_tax' => array( - 'description' => __( 'Total tax.', 'woocommerce-admin' ), + 'description' => __( 'Total tax.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -172,7 +172,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'format' => 'currency', ), 'order_tax' => array( - 'description' => __( 'Order tax.', 'woocommerce-admin' ), + 'description' => __( 'Order tax.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -180,7 +180,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'format' => 'currency', ), 'shipping_tax' => array( - 'description' => __( 'Shipping tax.', 'woocommerce-admin' ), + 'description' => __( 'Shipping tax.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -188,13 +188,13 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'format' => 'currency', ), 'orders_count' => array( - 'description' => __( 'Amount of orders.', 'woocommerce-admin' ), + 'description' => __( 'Amount of orders.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_codes' => array( - 'description' => __( 'Amount of tax codes.', 'woocommerce-admin' ), + 'description' => __( 'Amount of tax codes.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -203,7 +203,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr $segments = array( 'segments' => array( - 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by segment condition.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -211,13 +211,13 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'type' => 'object', 'properties' => array( 'segment_id' => array( - 'description' => __( 'Segment identificator.', 'woocommerce-admin' ), + 'description' => __( 'Segment identificator.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -236,14 +236,14 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'type' => 'object', 'properties' => array( 'totals' => array( - 'description' => __( 'Totals data.', 'woocommerce-admin' ), + 'description' => __( 'Totals data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => $totals, ), 'intervals' => array( - 'description' => __( 'Reports data grouped by intervals.', 'woocommerce-admin' ), + 'description' => __( 'Reports data grouped by intervals.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -251,38 +251,38 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'type' => 'object', 'properties' => array( 'interval' => array( - 'description' => __( 'Type of interval.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'The date the report end, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotals' => array( - 'description' => __( 'Interval subtotals.', 'woocommerce-admin' ), + 'description' => __( 'Interval subtotals.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -306,7 +306,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -314,7 +314,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -323,26 +323,26 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -355,7 +355,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr 'validate_callback' => 'rest_validate_request_arg', ); $params['interval'] = array( - 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce-admin' ), + 'description' => __( 'Time interval to use for buckets in the returned data.', 'woocommerce' ), 'type' => 'string', 'default' => 'week', 'enum' => array( @@ -369,7 +369,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr '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-admin' ), + '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', @@ -378,7 +378,7 @@ class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Contr ), ); $params['segmentby'] = array( - 'description' => __( 'Segment the response by additional constraint.', 'woocommerce-admin' ), + 'description' => __( 'Segment the response by additional constraint.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'tax_rate_id', diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php index a64e187e9da..ed2ebb8818d 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php @@ -158,80 +158,80 @@ class WC_Admin_REST_Reports_Variations_Controller extends WC_REST_Reports_Contro 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce-admin' ), + 'description' => __( 'Product ID.', 'woocommerce' ), ), 'variation_id' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product ID.', 'woocommerce-admin' ), + 'description' => __( 'Product ID.', 'woocommerce' ), ), 'items_sold' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Number of items sold.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Product name.', 'woocommerce' ), ), 'price' => array( 'type' => 'number', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product price.', 'woocommerce-admin' ), + 'description' => __( 'Product price.', 'woocommerce' ), ), 'image' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product image.', 'woocommerce-admin' ), + 'description' => __( 'Product image.', 'woocommerce' ), ), 'permalink' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product link.', 'woocommerce-admin' ), + 'description' => __( 'Product link.', 'woocommerce' ), ), 'attributes' => array( 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product attributes.', 'woocommerce-admin' ), + 'description' => __( 'Product attributes.', 'woocommerce' ), ), 'stock_status' => array( 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory status.', 'woocommerce-admin' ), + 'description' => __( 'Product inventory status.', 'woocommerce' ), ), 'stock_quantity' => array( 'type' => 'integer', 'readonly' => true, 'context' => array( 'view', 'edit' ), - 'description' => __( 'Product inventory quantity.', 'woocommerce-admin' ), + '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-admin' ), + 'description' => __( 'Product inventory threshold for low stock.', 'woocommerce' ), ), ), ), @@ -249,7 +249,7 @@ class WC_Admin_REST_Reports_Variations_Controller extends WC_REST_Reports_Contro $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -257,7 +257,7 @@ class WC_Admin_REST_Reports_Variations_Controller extends WC_REST_Reports_Contro 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -266,26 +266,26 @@ class WC_Admin_REST_Reports_Variations_Controller extends WC_REST_Reports_Contro 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -298,7 +298,7 @@ class WC_Admin_REST_Reports_Variations_Controller extends WC_REST_Reports_Contro 'validate_callback' => 'rest_validate_request_arg', ); $params['products'] = array( - 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce-admin' ), + 'description' => __( 'Limit result to items with specified product ids.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -307,7 +307,7 @@ class WC_Admin_REST_Reports_Variations_Controller extends WC_REST_Reports_Contro ), ); $params['variations'] = array( - 'description' => __( 'Limit result to items with specified variation ids.', 'woocommerce-admin' ), + 'description' => __( 'Limit result to items with specified variation ids.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -316,7 +316,7 @@ class WC_Admin_REST_Reports_Variations_Controller extends WC_REST_Reports_Contro ), ); $params['extended_info'] = array( - 'description' => __( 'Add additional piece of info about each product to the report.', 'woocommerce-admin' ), + 'description' => __( 'Add additional piece of info about each product to the report.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'wc_string_to_bool', diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-controller.php b/src/RestApi/Version4/class-wc-admin-rest-data-controller.php index d83006728ce..227ec85a150 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-data-controller.php +++ b/src/RestApi/Version4/class-wc-admin-rest-data-controller.php @@ -36,7 +36,7 @@ class WC_Admin_REST_Data_Controller extends WC_REST_Data_Controller { $this->prepare_item_for_response( (object) array( 'slug' => 'download-ips', - 'description' => __( 'An endpoint used for searching download logs for a specific IP address.', 'woocommerce-admin' ), + 'description' => __( 'An endpoint used for searching download logs for a specific IP address.', 'woocommerce' ), ), $request ) diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php b/src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php index 8f264f0d417..36e2431d0b9 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php +++ b/src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php @@ -70,7 +70,7 @@ class WC_Admin_REST_Data_Download_Ips_Controller extends WC_REST_Data_Controller ) ); } else { - return new WP_Error( 'woocommerce_rest_data_download_ips_invalid_request', __( 'Invalid request. Please pass the match parameter.', 'woocommerce-admin' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_data_download_ips_invalid_request', __( 'Invalid request. Please pass the match parameter.', 'woocommerce' ), array( 'status' => 400 ) ); } $data = array(); @@ -134,7 +134,7 @@ class WC_Admin_REST_Data_Download_Ips_Controller extends WC_REST_Data_Controller $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['match'] = array( - 'description' => __( 'A partial IP address can be passed and matching results will be returned.', 'woocommerce-admin' ), + 'description' => __( 'A partial IP address can be passed and matching results will be returned.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); @@ -155,7 +155,7 @@ class WC_Admin_REST_Data_Download_Ips_Controller extends WC_REST_Data_Controller 'properties' => array( 'user_ip_address' => array( 'type' => 'string', - 'description' => __( 'IP address.', 'woocommerce-admin' ), + 'description' => __( 'IP address.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php b/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php index d0016317749..ee05e836193 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php +++ b/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php @@ -112,16 +112,16 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { return array( 'id' => 'coupons', - 'label' => __( 'Top Coupons - Number of Orders', 'woocommerce-admin' ), + 'label' => __( 'Top Coupons - Number of Orders', 'woocommerce' ), 'headers' => array( array( - 'label' => __( 'Coupon Code', 'woocommerce-admin' ), + 'label' => __( 'Coupon Code', 'woocommerce' ), ), array( - 'label' => __( 'Orders', 'woocommerce-admin' ), + 'label' => __( 'Orders', 'woocommerce' ), ), array( - 'label' => __( 'Amount Discounted', 'woocommerce-admin' ), + 'label' => __( 'Amount Discounted', 'woocommerce' ), ), ), 'rows' => $rows, @@ -178,16 +178,16 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { return array( 'id' => 'categories', - 'label' => __( 'Top Categories - Items Sold', 'woocommerce-admin' ), + 'label' => __( 'Top Categories - Items Sold', 'woocommerce' ), 'headers' => array( array( - 'label' => __( 'Category', 'woocommerce-admin' ), + 'label' => __( 'Category', 'woocommerce' ), ), array( - 'label' => __( 'Items Sold', 'woocommerce-admin' ), + 'label' => __( 'Items Sold', 'woocommerce' ), ), array( - 'label' => __( 'Net Revenue', 'woocommerce-admin' ), + 'label' => __( 'Net Revenue', 'woocommerce' ), ), ), 'rows' => $rows, @@ -242,16 +242,16 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { return array( 'id' => 'customers', - 'label' => __( 'Top Customers - Total Spend', 'woocommerce-admin' ), + 'label' => __( 'Top Customers - Total Spend', 'woocommerce' ), 'headers' => array( array( - 'label' => __( 'Customer Name', 'woocommerce-admin' ), + 'label' => __( 'Customer Name', 'woocommerce' ), ), array( - 'label' => __( 'Orders', 'woocommerce-admin' ), + 'label' => __( 'Orders', 'woocommerce' ), ), array( - 'label' => __( 'Total Spend', 'woocommerce-admin' ), + 'label' => __( 'Total Spend', 'woocommerce' ), ), ), 'rows' => $rows, @@ -308,16 +308,16 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { return array( 'id' => 'products', - 'label' => __( 'Top Products - Items Sold', 'woocommerce-admin' ), + 'label' => __( 'Top Products - Items Sold', 'woocommerce' ), 'headers' => array( array( - 'label' => __( 'Product', 'woocommerce-admin' ), + 'label' => __( 'Product', 'woocommerce' ), ), array( - 'label' => __( 'Items Sold', 'woocommerce-admin' ), + 'label' => __( 'Items Sold', 'woocommerce' ), ), array( - 'label' => __( 'Net Revenue', 'woocommerce-admin' ), + 'label' => __( 'Net Revenue', 'woocommerce' ), ), ), 'rows' => $rows, @@ -428,7 +428,7 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { public function get_collection_params() { $params = array(); $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-admin' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -436,7 +436,7 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-admin' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 5, 'minimum' => 1, @@ -445,19 +445,19 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-admin' ), + '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-admin' ), + '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-admin' ), + 'description' => __( 'URL query to persist across links.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); @@ -477,26 +477,26 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { 'properties' => array( 'id' => array( 'type' => 'string', - 'description' => __( 'Leaderboard ID.', 'woocommerce-admin' ), + 'description' => __( 'Leaderboard ID.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'label' => array( 'type' => 'string', - 'description' => __( 'Displayed title for the leaderboard.', 'woocommerce-admin' ), + 'description' => __( 'Displayed title for the leaderboard.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'headers' => array( 'type' => 'array', - 'description' => __( 'Table headers.', 'woocommerce-admin' ), + 'description' => __( 'Table headers.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( 'type' => 'array', 'properties' => array( 'label' => array( - 'description' => __( 'Table column header.', 'woocommerce-admin' ), + 'description' => __( 'Table column header.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -506,20 +506,20 @@ class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { ), 'rows' => array( 'type' => 'array', - 'description' => __( 'Table rows.', 'woocommerce-admin' ), + 'description' => __( 'Table rows.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( 'type' => 'array', 'properties' => array( 'display' => array( - 'description' => __( 'Table cell display.', 'woocommerce-admin' ), + 'description' => __( 'Table cell display.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Table cell value.', 'woocommerce-admin' ), + 'description' => __( 'Table cell value.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php index 29622add12e..e661d0e7623 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php +++ b/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php @@ -58,8 +58,8 @@ class WC_Admin_REST_Onboarding_Levels_Controller extends WC_REST_Data_Controller 'account' => array( 'tasks' => array( 'create_account' => array( - 'label' => __( 'Create an account', 'woocommerce-admin' ), - 'description' => __( 'Speed up & secure your store', 'woocommerce-admin' ), + 'label' => __( 'Create an account', 'woocommerce' ), + 'description' => __( 'Speed up & secure your store', 'woocommerce' ), 'illustration' => '', 'status' => 'visible', 'is_required' => false, @@ -69,15 +69,15 @@ class WC_Admin_REST_Onboarding_Levels_Controller extends WC_REST_Data_Controller 'storefront' => array( 'tasks' => array( 'add_products' => array( - 'label' => __( 'Add your products', 'woocommerce-admin' ), - 'description' => __( 'Bring your store to life', 'woocommerce-admin' ), + 'label' => __( 'Add your products', 'woocommerce' ), + 'description' => __( 'Bring your store to life', 'woocommerce' ), 'illustration' => '', 'status' => 'visible', 'is_required' => true, ), 'customize_appearance' => array( - 'label' => __( 'Customize Appearance', 'woocommerce-admin' ), - 'description' => __( 'Ensure your store is on-brand', 'woocommerce-admin' ), + 'label' => __( 'Customize Appearance', 'woocommerce' ), + 'description' => __( 'Ensure your store is on-brand', 'woocommerce' ), 'illustration' => '', 'status' => 'visible', 'is_required' => false, @@ -88,22 +88,22 @@ class WC_Admin_REST_Onboarding_Levels_Controller extends WC_REST_Data_Controller 'id' => 'checkout', 'tasks' => array( 'configure_shipping' => array( - 'label' => __( 'Configure shipping', 'woocommerce-admin' ), - 'description' => __( 'Set up prices and destinations', 'woocommerce-admin' ), + 'label' => __( 'Configure shipping', 'woocommerce' ), + 'description' => __( 'Set up prices and destinations', 'woocommerce' ), 'illustration' => '', 'status' => 'visible', 'is_required' => true, ), 'configure_taxes' => array( - 'label' => __( 'Configure taxes', 'woocommerce-admin' ), - 'description' => __( 'Set up sales tax rates', 'woocommerce-admin' ), + 'label' => __( 'Configure taxes', 'woocommerce' ), + 'description' => __( 'Set up sales tax rates', 'woocommerce' ), 'illustration' => '', 'status' => 'visible', 'is_required' => false, ), 'configure_payments' => array( - 'label' => __( 'Configure payments', 'woocommerce-admin' ), - 'description' => __( 'Choose payment providers', 'woocommerce-admin' ), + 'label' => __( 'Configure payments', 'woocommerce' ), + 'description' => __( 'Choose payment providers', 'woocommerce' ), 'illustration' => '', 'status' => 'visible', 'is_required' => true, @@ -210,44 +210,44 @@ class WC_Admin_REST_Onboarding_Levels_Controller extends WC_REST_Data_Controller 'properties' => array( 'id' => array( 'type' => 'string', - 'description' => __( 'Level ID.', 'woocommerce-admin' ), + 'description' => __( 'Level ID.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'tasks' => array( 'type' => 'array', - 'description' => __( 'Array of tasks under the level.', 'woocommerce-admin' ), + 'description' => __( 'Array of tasks under the level.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Task ID.', 'woocommerce-admin' ), + 'description' => __( 'Task ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Task label.', 'woocommerce-admin' ), + 'description' => __( 'Task label.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Task description.', 'woocommerce-admin' ), + 'description' => __( 'Task description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'illustration' => array( - 'description' => __( 'URL for illustration used.', 'woocommerce-admin' ), + 'description' => __( 'URL for illustration used.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Task status.', 'woocommerce-admin' ), + 'description' => __( 'Task status.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php index 002010257de..398aa0b0f25 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php +++ b/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php @@ -82,7 +82,7 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle */ public function update_item_permissions_check( $request ) { if ( ! current_user_can( 'install_plugins' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot manage plugins.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot manage plugins.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -110,7 +110,7 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle $allowed_plugins = $this->get_allowed_plugins(); $plugin = sanitize_title_with_dashes( $request['plugin'] ); if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) { - return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce-admin' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); } require_once ABSPATH . 'wp-admin/includes/plugin.php'; @@ -144,14 +144,14 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle ); if ( is_wp_error( $api ) ) { - return new WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce-admin' ), 500 ); + return new WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce' ), 500 ); } $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); $result = $upgrader->install( $api->download_link ); if ( is_wp_error( $result ) || is_null( $result ) ) { - return new WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce-admin' ), 500 ); + return new WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce' ), 500 ); } return array( @@ -171,7 +171,7 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle $allowed_plugins = $this->get_allowed_plugins(); $plugin = sanitize_title_with_dashes( $request['plugin'] ); if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) { - return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce-admin' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); } require_once ABSPATH . 'wp-admin/includes/plugin.php'; @@ -181,12 +181,12 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle $installed_plugins = get_plugins(); if ( ! in_array( $path, array_keys( $installed_plugins ), true ) ) { - return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce-admin' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); } $result = activate_plugin( $path ); if ( ! is_null( $result ) ) { - return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'The requested plugin could not be activated.', 'woocommerce-admin' ), 500 ); + return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'The requested plugin could not be activated.', 'woocommerce' ), 500 ); } return( array( @@ -203,7 +203,7 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle */ public function connect_jetpack() { if ( ! class_exists( 'Jetpack' ) ) { - return new WP_Error( 'woocommerce_rest_jetpack_not_active', __( 'Jetpack is not installed or active.', 'woocommerce-admin' ), 404 ); + return new WP_Error( 'woocommerce_rest_jetpack_not_active', __( 'Jetpack is not installed or active.', 'woocommerce' ), 404 ); } $next_step_slug = apply_filters( 'woocommerce_onboarding_after_jetpack_step', 'store-details' ); @@ -230,7 +230,7 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle return( array( 'slug' => $slug, - 'name' => __( 'Jetpack', 'woocommerce-admin' ), + 'name' => __( 'Jetpack', 'woocommerce' ), 'connectAction' => $connect_url, ) ); } @@ -247,19 +247,19 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'Plugin slug.', 'woocommerce-admin' ), + 'description' => __( 'Plugin slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Plugin name.', 'woocommerce-admin' ), + 'description' => __( 'Plugin name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Plugin status.', 'woocommerce-admin' ), + 'description' => __( 'Plugin status.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -279,7 +279,7 @@ class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controlle $schema = $this->get_item_schema(); unset( $schema['properties']['status'] ); $schema['properties']['connectAction'] = array( - 'description' => __( 'Action that should be completed to connect Jetpack.', 'woocommerce-admin' ), + 'description' => __( 'Action that should be completed to connect Jetpack.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php b/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php index 3cd2727e87f..4555932e993 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php +++ b/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php @@ -69,7 +69,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -83,7 +83,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle */ public function update_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot edit this resource.', 'woocommerce-admin' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -124,7 +124,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle $result = array( 'status' => 'success', - 'message' => __( 'Onboarding profile data has been updated.', 'woocommerce-admin' ), + 'message' => __( 'Onboarding profile data has been updated.', 'woocommerce' ), ); $response = $this->prepare_item_for_response( $result, $request ); @@ -195,21 +195,21 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle $properties = array( 'completed' => array( 'type' => 'boolean', - 'description' => __( 'Whether or not the profile was completed.', 'woocommerce-admin' ), + 'description' => __( 'Whether or not the profile was completed.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'validate_callback' => 'rest_validate_request_arg', ), 'skipped' => array( 'type' => 'boolean', - 'description' => __( 'Whether or not the profile was skipped.', 'woocommerce-admin' ), + 'description' => __( 'Whether or not the profile was skipped.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'validate_callback' => 'rest_validate_request_arg', ), 'account_type' => array( 'type' => 'string', - 'description' => __( 'Account type used for Jetpack.', 'woocommerce-admin' ), + 'description' => __( 'Account type used for Jetpack.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'validate_callback' => 'rest_validate_request_arg', @@ -221,7 +221,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle ), 'industry' => array( 'type' => 'array', - 'description' => __( 'Industry.', 'woocommerce-admin' ), + 'description' => __( 'Industry.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'sanitize_callback' => 'wp_parse_slug_list', @@ -233,7 +233,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle ), 'product_types' => array( 'type' => 'array', - 'description' => __( 'Types of products sold.', 'woocommerce-admin' ), + 'description' => __( 'Types of products sold.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'sanitize_callback' => 'wp_parse_slug_list', @@ -245,7 +245,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle ), 'product_count' => array( 'type' => 'string', - 'description' => __( 'Number of products to be added.', 'woocommerce-admin' ), + 'description' => __( 'Number of products to be added.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'validate_callback' => 'rest_validate_request_arg', @@ -258,7 +258,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle ), 'selling_venues' => array( 'type' => 'string', - 'description' => __( 'Other places the store is selling products.', 'woocommerce-admin' ), + 'description' => __( 'Other places the store is selling products.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'validate_callback' => 'rest_validate_request_arg', @@ -271,7 +271,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle ), 'other_platform' => array( 'type' => 'string', - 'description' => __( 'Name of other platform used to sell.', 'woocommerce-admin' ), + 'description' => __( 'Name of other platform used to sell.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'validate_callback' => 'rest_validate_request_arg', @@ -285,7 +285,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle ), 'theme' => array( 'type' => 'string', - 'description' => __( 'Selected store theme.', 'woocommerce-admin' ), + 'description' => __( 'Selected store theme.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'sanitize_callback' => 'sanitize_title_with_dashes', @@ -293,7 +293,7 @@ class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controlle ), 'items_purchased' => array( 'type' => 'boolean', - 'description' => __( 'Whether or not the user opted to purchase items now or later.', 'woocommerce-admin' ), + 'description' => __( 'Whether or not the user opted to purchase items now or later.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php b/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php index 92f4d866a28..1e96ce78c99 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php +++ b/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php @@ -31,7 +31,7 @@ class WC_Admin_REST_Product_Variations_Controller extends WC_REST_Product_Variat public function get_collection_params() { $params = parent::get_collection_params(); $params['search'] = array( - 'description' => __( 'Search by similar product name or sku.', 'woocommerce-admin' ), + 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); @@ -81,19 +81,19 @@ class WC_Admin_REST_Product_Variations_Controller extends WC_REST_Product_Variat $schema = parent::get_item_schema(); $schema['properties']['name'] = array( - 'description' => __( 'Product parent name.', 'woocommerce-admin' ), + 'description' => __( 'Product parent name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ); $schema['properties']['type'] = array( - 'description' => __( 'Product type.', 'woocommerce-admin' ), + 'description' => __( 'Product type.', 'woocommerce' ), 'type' => 'string', 'default' => 'variation', 'enum' => array( 'variation' ), 'context' => array( 'view', 'edit' ), ); $schema['properties']['parent_id'] = array( - 'description' => __( 'Product parent ID.', 'woocommerce-admin' ), + 'description' => __( 'Product parent ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); From f02417114ffa5aac48d35d0c3ac82bc8636e7646 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:48:30 +0100 Subject: [PATCH 035/440] Reports --- src/RestApi/Version4/Controllers/Reports.php | 18 -- ...tegories-controller.php => Categories.php} | 6 +- ...s-stats-controller.php => CouponStats.php} | 13 +- ...rts-coupons-controller.php => Coupons.php} | 13 +- ...stats-controller.php => CustomerStats.php} | 13 +- ...customers-controller.php => Customers.php} | 13 +- ...stats-controller.php => DownloadStats.php} | 13 +- ...downloads-controller.php => Downloads.php} | 13 +- ...ports-import-controller.php => Import.php} | 13 +- ...rs-stats-controller.php => OrderStats.php} | 13 +- ...ports-orders-controller.php => Orders.php} | 13 +- ...ntroller.php => PerformanceIndicators.php} | 13 +- ...-stats-controller.php => ProductStats.php} | 13 +- ...s-products-controller.php => Products.php} | 13 +- ...-stats-controller.php => RevenueStats.php} | 13 +- ...reports-stock-controller.php => Stock.php} | 13 +- ...ck-stats-controller.php => StockStats.php} | 13 +- ...axes-stats-controller.php => TaxStats.php} | 13 +- ...reports-taxes-controller.php => Taxes.php} | 13 +- ...riations-controller.php => Variations.php} | 13 +- ...class-wc-admin-rest-reports-controller.php | 303 ------------------ ...est-reports-downloads-files-controller.php | 33 -- src/RestApi/Version4/changelog.md | 20 +- 23 files changed, 148 insertions(+), 466 deletions(-) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-categories-controller.php => Categories.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-coupons-stats-controller.php => CouponStats.php} (97%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-coupons-controller.php => Coupons.php} (97%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-customers-stats-controller.php => CustomerStats.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-customers-controller.php => Customers.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-downloads-stats-controller.php => DownloadStats.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-downloads-controller.php => Downloads.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-import-controller.php => Import.php} (97%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-orders-stats-controller.php => OrderStats.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-orders-controller.php => Orders.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-performance-indicators-controller.php => PerformanceIndicators.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-products-stats-controller.php => ProductStats.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-products-controller.php => Products.php} (97%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-revenue-stats-controller.php => RevenueStats.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-stock-controller.php => Stock.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-stock-stats-controller.php => StockStats.php} (93%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-taxes-stats-controller.php => TaxStats.php} (98%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-taxes-controller.php => Taxes.php} (97%) rename src/RestApi/Version4/Controllers/Reports/{class-wc-admin-rest-reports-variations-controller.php => Variations.php} (97%) delete mode 100644 src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php delete mode 100644 src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-files-controller.php diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php index 76113202b5d..72a8dc96631 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -123,10 +123,6 @@ class Reports extends WC_REST_Controller { 'slug' => 'downloads', 'description' => __( 'Product downloads detailed reports.', 'woocommerce' ), ), - array( - 'slug' => 'downloads/files', - 'description' => __( 'Product download files detailed reports.', 'woocommerce' ), - ), array( 'slug' => 'downloads/stats', 'description' => __( 'Stats about product downloads.', 'woocommerce' ), @@ -301,18 +297,4 @@ class Reports extends WC_REST_Controller { return $order_statuses; } - - /** - * Check whether a given request has permission to read reports. - * - * @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( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } } diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php b/src/RestApi/Version4/Controllers/Reports/Categories.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php rename to src/RestApi/Version4/Controllers/Reports/Categories.php index 2a1fff9fd04..d5cde576636 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-categories-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Categories.php @@ -11,12 +11,12 @@ namespace WooCommerce\RestApi\Version4\Controllers\Reports; defined( 'ABSPATH' ) || exit; -use \WC_Admin_REST_Reports_Controller; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; /** - * REST API Category Reports class. + * REST API Categories Reports class. */ -class Categories extends WC_Admin_REST_Reports_Controller { +class Categories extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/CouponStats.php similarity index 97% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/CouponStats.php index a416a57dc3f..fe655e18af9 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/CouponStats.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/coupons/stats endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports coupons stats controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API CouponStats Reports class. */ -class WC_Admin_REST_Reports_Coupons_Stats_Controller extends WC_REST_Reports_Controller { +class CouponStats extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php b/src/RestApi/Version4/Controllers/Reports/Coupons.php similarity index 97% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php rename to src/RestApi/Version4/Controllers/Reports/Coupons.php index f2146a7bfe3..3821e17bd07 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-coupons-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Coupons.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/coupons endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports coupons controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API Coupons Reports class. */ -class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controller { +class Coupons extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/CustomerStats.php index 5b076fa929b..e604aeacb97 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/customers/stats endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports customers stats controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API CustomerStats Reports class. */ -class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_Controller { +class CustomerStats extends Reports { /** * Endpoint namespace. * diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php b/src/RestApi/Version4/Controllers/Reports/Customers.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php rename to src/RestApi/Version4/Controllers/Reports/Customers.php index 02b974cc922..da23ebb5d15 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-customers-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Customers.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/customers endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports customers controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API Customers Reports class. */ -class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Controller { +class Customers extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/DownloadStats.php index 4a0234449af..08da58d69ab 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/downloads/stats endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports downloads stats controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API DownloadStats Reports class. */ -class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_Controller { +class DownloadStats extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php b/src/RestApi/Version4/Controllers/Reports/Downloads.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php rename to src/RestApi/Version4/Controllers/Reports/Downloads.php index 9ce998461af..256117c37ca 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Downloads.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/downloads endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports downloads controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API Downloads Reports class. */ -class WC_Admin_REST_Reports_Downloads_Controller extends WC_Admin_REST_Reports_Controller { +class Downloads extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php b/src/RestApi/Version4/Controllers/Reports/Import.php similarity index 97% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php rename to src/RestApi/Version4/Controllers/Reports/Import.php index b0f16d997b4..26db4b41ce3 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-import-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Import.php @@ -4,18 +4,19 @@ * * Handles requests to /reports/import * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * Reports Imports controller. - * - * @package WooCommerce Admin/API - * @extends WC_REST_Data_Controller + * REST API Import Reports class. */ -class WC_Admin_REST_Reports_Import_Controller extends WC_Admin_REST_Reports_Controller { +class Import extends Reports { /** * Endpoint namespace. * diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/OrderStats.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/OrderStats.php index 33a2fc4aa87..4f60962102a 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/OrderStats.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/orders/stats endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports orders stats controller class. - * - * @package WooCommerce/API - * @extends WC_Admin_REST_Reports_Controller + * REST API OrderStats Reports class. */ -class WC_Admin_REST_Reports_Orders_Stats_Controller extends WC_Admin_REST_Reports_Controller { +class OrderStats extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php b/src/RestApi/Version4/Controllers/Reports/Orders.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php rename to src/RestApi/Version4/Controllers/Reports/Orders.php index 20535bd3632..2d7a8ec9f07 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-orders-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Orders.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/orders endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports orders controller class. - * - * @package WooCommerce/API - * @extends WC_Admin_REST_Reports_Controller + * REST API Orders Reports class. */ -class WC_Admin_REST_Reports_Orders_Controller extends WC_Admin_REST_Reports_Controller { +class Orders extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php rename to src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php index 84ad882da6a..ebc0bf052ac 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-performance-indicators-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/store-performance endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports Performance indicators controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API PerformanceIndicators class. */ -class WC_Admin_REST_Reports_Performance_Indicators_Controller extends WC_REST_Reports_Controller { +class PerformanceIndicators extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/ProductStats.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/ProductStats.php index 3cfeb1c6f3c..acb4b42d6cc 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/ProductStats.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/products/stats endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports products stats controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API ProductStats Reports class. */ -class WC_Admin_REST_Reports_Products_Stats_Controller extends WC_REST_Reports_Controller { +class ProductStats extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php b/src/RestApi/Version4/Controllers/Reports/Products.php similarity index 97% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php rename to src/RestApi/Version4/Controllers/Reports/Products.php index ef64c8aae10..214506b6bd8 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-products-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Products.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/products endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports products controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API Products Reports class. */ -class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controller { +class Products extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/RevenueStats.php index 33c78e1e35e..5533a211a6b 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-revenue-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/revenue/stats endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports revenue stats controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API RevenueStats Reports class. */ -class WC_Admin_REST_Reports_Revenue_Stats_Controller extends WC_REST_Reports_Controller { +class RevenueStats extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php b/src/RestApi/Version4/Controllers/Reports/Stock.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php rename to src/RestApi/Version4/Controllers/Reports/Stock.php index 7a4c4535f8c..9ff7535bf53 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Stock.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/stock endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports stock controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API Stock Reports class. */ -class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller { +class Stock extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/StockStats.php similarity index 93% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/StockStats.php index 6d3b091da56..101f90369f1 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-stock-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/StockStats.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/stock/stats endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports stock stats controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API StockStats Reports class. */ -class WC_Admin_REST_Reports_Stock_Stats_Controller extends WC_REST_Reports_Controller { +class StockStats extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php b/src/RestApi/Version4/Controllers/Reports/TaxStats.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php rename to src/RestApi/Version4/Controllers/Reports/TaxStats.php index 35d7baf8e7e..ae81a1c2626 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-stats-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/TaxStats.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/taxes/stats endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports taxes stats controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API TaxesStats Reports class. */ -class WC_Admin_REST_Reports_Taxes_Stats_Controller extends WC_REST_Reports_Controller { +class TaxStats extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php b/src/RestApi/Version4/Controllers/Reports/Taxes.php similarity index 97% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php rename to src/RestApi/Version4/Controllers/Reports/Taxes.php index b4f1ca1f968..2a68ba10266 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-taxes-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Taxes.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/taxes endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports taxes controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API Taxes Reports class. */ -class WC_Admin_REST_Reports_Taxes_Controller extends WC_REST_Reports_Controller { +class Taxes extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php b/src/RestApi/Version4/Controllers/Reports/Variations.php similarity index 97% rename from src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php rename to src/RestApi/Version4/Controllers/Reports/Variations.php index ed2ebb8818d..f2fed45f205 100644 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-variations-controller.php +++ b/src/RestApi/Version4/Controllers/Reports/Variations.php @@ -4,18 +4,19 @@ * * Handles requests to the /reports/products endpoint. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Reports; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; + /** - * REST API Reports products controller class. - * - * @package WooCommerce/API - * @extends WC_REST_Reports_Controller + * REST API Variations Reports class. */ -class WC_Admin_REST_Reports_Variations_Controller extends WC_REST_Reports_Controller { +class Variations extends Reports { /** * Endpoint namespace. diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php deleted file mode 100644 index 5cae9909de9..00000000000 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-controller.php +++ /dev/null @@ -1,303 +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' ), - ) - ); - } - - /** - * Check whether a given request has permission to read reports. - * - * @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( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - - /** - * Get all reports. - * - * @param WP_REST_Request $request Request data. - * @return array|WP_Error - */ - public function get_items( $request ) { - $data = array(); - $reports = array( - array( - 'slug' => 'performance-indicators', - 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce' ), - ), - array( - 'slug' => 'revenue/stats', - 'description' => __( 'Stats about revenue.', 'woocommerce' ), - ), - array( - 'slug' => 'orders/stats', - 'description' => __( 'Stats about orders.', 'woocommerce' ), - ), - array( - 'slug' => 'products', - 'description' => __( 'Products detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'products/stats', - 'description' => __( 'Stats about products.', 'woocommerce' ), - ), - array( - 'slug' => 'categories', - 'description' => __( 'Product categories detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'categories/stats', - 'description' => __( 'Stats about product categories.', 'woocommerce' ), - ), - array( - 'slug' => 'coupons', - 'description' => __( 'Coupons detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'coupons/stats', - 'description' => __( 'Stats about coupons.', 'woocommerce' ), - ), - array( - 'slug' => 'taxes', - 'description' => __( 'Taxes detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'taxes/stats', - 'description' => __( 'Stats about taxes.', 'woocommerce' ), - ), - array( - 'slug' => 'downloads', - 'description' => __( 'Product downloads detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'downloads/files', - 'description' => __( 'Product download files detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'downloads/stats', - 'description' => __( 'Stats about product downloads.', 'woocommerce' ), - ), - array( - 'slug' => 'customers', - 'description' => __( 'Customers detailed reports.', 'woocommerce' ), - ), - ); - - /** - * Filter the list of allowed reports, so that data can be loaded from third party extensions in addition to WooCommerce core. - * Array items should be in format of array( 'slug' => 'downloads/stats', 'description' => '', - * 'url' => '', and 'path' => '/wc-ext/v1/...'. - * - * @param array $endpoints The list of allowed reports.. - */ - $reports = apply_filters( 'woocommerce_admin_reports', $reports ); - - foreach ( $reports as $report ) { - if ( empty( $report['slug'] ) ) { - continue; - } - - if ( empty( $report['path'] ) ) { - $report['path'] = '/' . $this->namespace . '/reports/' . $report['slug']; - } - - // Allows a different admin page to be loaded here, - // or allows an empty url if no report exists for a set of performance indicators. - if ( ! isset( $report['url'] ) ) { - if ( '/stats' === substr( $report['slug'], -6 ) ) { - $url_slug = substr( $report['slug'], 0, -6 ); - } else { - $url_slug = $report['slug']; - } - - $report['url'] = '/analytics/' . $url_slug; - } - - $item = $this->prepare_item_for_response( (object) $report, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - return rest_ensure_response( $data ); - } - - /** - * Get the order number for an order. If no filter is present for `woocommerce_order_number`, we can just return the ID. - * Returns the parent order number if the order is actually a refund. - * - * @param int $order_id Order ID. - * @return string - */ - public function get_order_number( $order_id ) { - $order = wc_get_order( $order_id ); - - if ( 'shop_order_refund' === $order->get_type() ) { - $order = wc_get_order( $order->get_parent_id() ); - } - - if ( ! has_filter( 'woocommerce_order_number' ) ) { - return $order->get_id(); - } - - return $order->get_order_number(); - } - - /** - * 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 = array( - 'slug' => $report->slug, - 'description' => $report->description, - 'path' => $report->path, - ); - - $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( - array( - 'self' => array( - 'href' => rest_url( $report->path ), - ), - 'report' => array( - 'href' => $report->url, - ), - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - ) - ); - - /** - * 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', $response, $report, $request ); - } - - /** - * 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', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'path' => array( - 'description' => __( 'API path.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } - - /** - * Get order statuses without prefixes. - * - * @return array - */ - public function get_order_statuses() { - $order_statuses = array(); - - foreach ( array_keys( wc_get_order_statuses() ) as $status ) { - $order_statuses[] = str_replace( 'wc-', '', $status ); - } - - return $order_statuses; - } -} diff --git a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-files-controller.php b/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-files-controller.php deleted file mode 100644 index d0f54fbdc66..00000000000 --- a/src/RestApi/Version4/Controllers/Reports/class-wc-admin-rest-reports-downloads-files-controller.php +++ /dev/null @@ -1,33 +0,0 @@ - Date: Thu, 30 May 2019 14:51:32 +0100 Subject: [PATCH 036/440] Onboarding --- .../Onboarding/Levels.php} | 9 +++++++-- .../Onboarding/Plugins.php} | 8 ++++++-- .../Onboarding/Profile.php} | 9 +++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) rename src/RestApi/Version4/{class-wc-admin-rest-onboarding-levels-controller.php => Controllers/Onboarding/Levels.php} (97%) rename src/RestApi/Version4/{class-wc-admin-rest-onboarding-plugins-controller.php => Controllers/Onboarding/Plugins.php} (97%) rename src/RestApi/Version4/{class-wc-admin-rest-onboarding-profile-controller.php => Controllers/Onboarding/Profile.php} (98%) diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php b/src/RestApi/Version4/Controllers/Onboarding/Levels.php similarity index 97% rename from src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php rename to src/RestApi/Version4/Controllers/Onboarding/Levels.php index e661d0e7623..4ac4f6e7411 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-onboarding-levels-controller.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Levels.php @@ -4,18 +4,23 @@ * * Handles requests to /onboarding/levels * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Onboarding; + defined( 'ABSPATH' ) || exit; +use \WC_REST_Data_Controller; + /** * Onboarding Levels controller. * * @package WooCommerce Admin/API * @extends WC_REST_Data_Controller */ -class WC_Admin_REST_Onboarding_Levels_Controller extends WC_REST_Data_Controller { +class Levels extends WC_REST_Data_Controller { + /** * Endpoint namespace. * diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php b/src/RestApi/Version4/Controllers/Onboarding/Plugins.php similarity index 97% rename from src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php rename to src/RestApi/Version4/Controllers/Onboarding/Plugins.php index 398aa0b0f25..e7e602c0266 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-onboarding-plugins-controller.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Plugins.php @@ -4,18 +4,22 @@ * * Handles requests to install and activate depedent plugins. * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Onboarding; + defined( 'ABSPATH' ) || exit; +use \WC_REST_Data_Controller; + /** * Onboarding Plugins Controller. * * @package WooCommerce Admin/API * @extends WC_REST_Data_Controller */ -class WC_Admin_REST_Onboarding_Plugins_Controller extends WC_REST_Data_Controller { +class Plugins extends WC_REST_Data_Controller { /** * Endpoint namespace. * diff --git a/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php b/src/RestApi/Version4/Controllers/Onboarding/Profile.php similarity index 98% rename from src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php rename to src/RestApi/Version4/Controllers/Onboarding/Profile.php index 4555932e993..36baa65c460 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-onboarding-profile-controller.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Profile.php @@ -4,18 +4,23 @@ * * Handles requests to /onboarding/profile * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Onboarding; + defined( 'ABSPATH' ) || exit; +use \WC_REST_Data_Controller; + /** * Onboarding Profile controller. * * @package WooCommerce Admin/API * @extends WC_REST_Data_Controller */ -class WC_Admin_REST_Onboarding_Profile_Controller extends WC_REST_Data_Controller { +class Profile extends WC_REST_Data_Controller { + /** * Endpoint namespace. * From 28b0d9c3317c11054f450d59a964a84cf261f001 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 14:55:12 +0100 Subject: [PATCH 037/440] Removed old reports --- src/RestApi/Version4/changelog.md | 9 +- ...-rest-report-coupons-totals-controller.php | 143 ---------------- ...est-report-customers-totals-controller.php | 154 ------------------ ...c-rest-report-orders-totals-controller.php | 127 --------------- ...rest-report-products-totals-controller.php | 133 --------------- ...-rest-report-reviews-totals-controller.php | 132 --------------- 6 files changed, 7 insertions(+), 691 deletions(-) delete mode 100644 src/RestApi/Version4/class-wc-rest-report-coupons-totals-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-report-customers-totals-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-report-orders-totals-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-report-products-totals-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-report-reviews-totals-controller.php diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md index b83e5394fe0..c76f50bcdb9 100644 --- a/src/RestApi/Version4/changelog.md +++ b/src/RestApi/Version4/changelog.md @@ -34,5 +34,10 @@ ## Removed endpoints -- Removed `reports/top_sellers` endpoint. -- Removed `reports/sales` endpoint. +- `reports/top_sellers` +- `reports/sales` +- `reports/customers/totals` +- `reports/orders/totals` +- `reports/coupons/totals` +- `reports/reviews/totals` +- `reports/products/totals` diff --git a/src/RestApi/Version4/class-wc-rest-report-coupons-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-coupons-totals-controller.php deleted file mode 100644 index d999b349703..00000000000 --- a/src/RestApi/Version4/class-wc-rest-report-coupons-totals-controller.php +++ /dev/null @@ -1,143 +0,0 @@ - $name ) { - $results = $wpdb->get_results( - $wpdb->prepare( " - SELECT count(meta_id) AS total - FROM $wpdb->postmeta - WHERE meta_key = 'discount_type' - AND meta_value = %s - ", $slug ) - ); - - $total = isset( $results[0] ) ? (int) $results[0]->total : 0; - - $data[] = array( - 'slug' => $slug, - 'name' => $name, - 'total' => $total, - ); - } - - set_transient( 'rest_api_coupons_type_count', $data, YEAR_IN_SECONDS ); - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_count', $response, $report, $request ); - } - - /** - * 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_coupon_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Coupon type name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of coupons.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Version4/class-wc-rest-report-customers-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-customers-totals-controller.php deleted file mode 100644 index c32b170e2db..00000000000 --- a/src/RestApi/Version4/class-wc-rest-report-customers-totals-controller.php +++ /dev/null @@ -1,154 +0,0 @@ - $total ) { - if ( in_array( $role, array( 'administrator', 'shop_manager' ), true ) ) { - continue; - } - - $total_customers += (int) $total; - } - - $customers_query = new WP_User_Query( - array( - 'role__not_in' => array( 'administrator', 'shop_manager' ), - 'number' => 0, - 'fields' => 'ID', - 'count_total' => true, - 'meta_query' => array( // WPCS: slow query ok. - array( - 'key' => 'paying_customer', - 'value' => 1, - 'compare' => '=', - ), - ), - ) - ); - - $total_paying = (int) $customers_query->get_total(); - - $data = array( - array( - 'slug' => 'paying', - 'name' => __( 'Paying customer', 'woocommerce' ), - 'total' => $total_paying, - ), - array( - 'slug' => 'non_paying', - 'name' => __( 'Non-paying customer', 'woocommerce' ), - 'total' => $total_customers - $total_paying, - ), - ); - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_count', $response, $report, $request ); - } - - /** - * 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_customer_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Customer type name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of customers.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Version4/class-wc-rest-report-orders-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-orders-totals-controller.php deleted file mode 100644 index 3fdc4619351..00000000000 --- a/src/RestApi/Version4/class-wc-rest-report-orders-totals-controller.php +++ /dev/null @@ -1,127 +0,0 @@ - $name ) { - if ( ! isset( $totals->$slug ) ) { - continue; - } - - $data[] = array( - 'slug' => str_replace( 'wc-', '', $slug ), - 'name' => $name, - 'total' => (int) $totals->$slug, - ); - } - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_count', $response, $report, $request ); - } - - /** - * 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_order_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Order status name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of orders.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Version4/class-wc-rest-report-products-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-products-totals-controller.php deleted file mode 100644 index adb42b0d276..00000000000 --- a/src/RestApi/Version4/class-wc-rest-report-products-totals-controller.php +++ /dev/null @@ -1,133 +0,0 @@ - 'product_type', - 'hide_empty' => false, - ) - ); - $data = array(); - - foreach ( $terms as $product_type ) { - if ( ! isset( $types[ $product_type->name ] ) ) { - continue; - } - - $data[] = array( - 'slug' => $product_type->name, - 'name' => $types[ $product_type->name ], - 'total' => (int) $product_type->count, - ); - } - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_count', $response, $report, $request ); - } - - /** - * 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_product_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product type name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of products.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Version4/class-wc-rest-report-reviews-totals-controller.php b/src/RestApi/Version4/class-wc-rest-report-reviews-totals-controller.php deleted file mode 100644 index ef7ce098baa..00000000000 --- a/src/RestApi/Version4/class-wc-rest-report-reviews-totals-controller.php +++ /dev/null @@ -1,132 +0,0 @@ - true, - 'post_type' => 'product', - 'meta_key' => 'rating', // WPCS: slow query ok. - 'meta_value' => '', // WPCS: slow query ok. - ); - - for ( $i = 1; $i <= 5; $i++ ) { - $query_data['meta_value'] = $i; - - $data[] = array( - 'slug' => 'rated_' . $i . '_out_of_5', - /* translators: %s: average rating */ - 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $i ), - 'total' => (int) get_comments( $query_data ), - ); - } - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_reviews_count', $response, $report, $request ); - } - - /** - * 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_review_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Review type name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of reviews.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} From b44f6eb0d50dc7a66f52bb707174a949ddefe7fa Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 15:04:03 +0100 Subject: [PATCH 038/440] Data --- .../Data.php} | 22 +++++---- .../Data/Continents.php} | 25 ++++++---- .../Data/Countries.php} | 22 +++++---- .../Data/Currencies.php} | 23 +++++---- .../Data/DownloadIPs.php} | 11 +++-- src/RestApi/Version4/changelog.md | 38 +++++++-------- .../class-wc-admin-rest-data-controller.php | 47 ------------------- ...c-admin-rest-data-countries-controller.php | 27 ----------- 8 files changed, 82 insertions(+), 133 deletions(-) rename src/RestApi/Version4/{class-wc-rest-data-controller.php => Controllers/Data.php} (91%) rename src/RestApi/Version4/{class-wc-rest-data-continents-controller.php => Controllers/Data/Continents.php} (96%) rename src/RestApi/Version4/{class-wc-rest-data-countries-controller.php => Controllers/Data/Countries.php} (94%) rename src/RestApi/Version4/{class-wc-rest-data-currencies-controller.php => Controllers/Data/Currencies.php} (93%) rename src/RestApi/Version4/{class-wc-admin-rest-data-download-ips-controller.php => Controllers/Data/DownloadIPs.php} (95%) delete mode 100644 src/RestApi/Version4/class-wc-admin-rest-data-controller.php delete mode 100644 src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php diff --git a/src/RestApi/Version4/class-wc-rest-data-controller.php b/src/RestApi/Version4/Controllers/Data.php similarity index 91% rename from src/RestApi/Version4/class-wc-rest-data-controller.php rename to src/RestApi/Version4/Controllers/Data.php index 71c6dd9029a..141d7f2f166 100644 --- a/src/RestApi/Version4/class-wc-rest-data-controller.php +++ b/src/RestApi/Version4/Controllers/Data.php @@ -5,25 +5,25 @@ * Handles requests to the /data endpoint. * * @package WooCommerce/RestApi - * @since 3.5.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; +use \WC_REST_Controller; + /** - * REST API Data controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller + * REST API Coupons controller class. */ -class WC_REST_Data_Controller extends WC_REST_Controller { +class Data extends WC_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v3'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -39,7 +39,9 @@ class WC_REST_Data_Controller extends WC_REST_Controller { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -100,6 +102,10 @@ class WC_REST_Data_Controller extends WC_REST_Controller { 'slug' => 'currencies', 'description' => __( 'List of supported currencies.', 'woocommerce' ), ), + array( + 'slug' => 'download-ips', + 'description' => __( 'An endpoint used for searching download logs for a specific IP address.', 'woocommerce' ), + ), ); foreach ( $resources as $resource ) { diff --git a/src/RestApi/Version4/class-wc-rest-data-continents-controller.php b/src/RestApi/Version4/Controllers/Data/Continents.php similarity index 96% rename from src/RestApi/Version4/class-wc-rest-data-continents-controller.php rename to src/RestApi/Version4/Controllers/Data/Continents.php index ccf64086b3f..a47f30c9f29 100644 --- a/src/RestApi/Version4/class-wc-rest-data-continents-controller.php +++ b/src/RestApi/Version4/Controllers/Data/Continents.php @@ -5,25 +5,25 @@ * Handles requests to the /data/continents endpoint. * * @package WooCommerce/RestApi - * @since 3.5.0 */ +namespace WooCommerce\RestApi\Version4\Controllers\Data; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; + /** - * REST API Data continents controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller + * REST API Data Continents controller class. */ -class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { +class Continents extends DataController { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v3'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -39,7 +39,9 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -49,7 +51,9 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { ) ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]+)', + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), @@ -104,7 +108,8 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { if ( array_key_exists( $country_code, $locale_info ) ) { // Defensive programming against unexpected changes in locale-info.php. $country_data = wp_parse_args( - $locale_info[ $country_code ], array( + $locale_info[ $country_code ], + array( 'currency_code' => 'USD', 'currency_pos' => 'left', 'decimal_sep' => '.', diff --git a/src/RestApi/Version4/class-wc-rest-data-countries-controller.php b/src/RestApi/Version4/Controllers/Data/Countries.php similarity index 94% rename from src/RestApi/Version4/class-wc-rest-data-countries-controller.php rename to src/RestApi/Version4/Controllers/Data/Countries.php index ff659b67e09..597bad1d1f4 100644 --- a/src/RestApi/Version4/class-wc-rest-data-countries-controller.php +++ b/src/RestApi/Version4/Controllers/Data/Countries.php @@ -5,25 +5,25 @@ * Handles requests to the /data/countries endpoint. * * @package WooCommerce/RestApi - * @since 3.5.0 */ +namespace WooCommerce\RestApi\Version4\Controllers\Data; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; + /** - * REST API Data countries controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller + * REST API Data Countries controller class. */ -class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { +class Countries extends DataController { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v3'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -39,7 +39,9 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -49,7 +51,9 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { ) ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]+)', + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), diff --git a/src/RestApi/Version4/class-wc-rest-data-currencies-controller.php b/src/RestApi/Version4/Controllers/Data/Currencies.php similarity index 93% rename from src/RestApi/Version4/class-wc-rest-data-currencies-controller.php rename to src/RestApi/Version4/Controllers/Data/Currencies.php index b5439695d0d..57a29917c0e 100644 --- a/src/RestApi/Version4/class-wc-rest-data-currencies-controller.php +++ b/src/RestApi/Version4/Controllers/Data/Currencies.php @@ -5,24 +5,25 @@ * Handles requests to the /data/currencies endpoint. * * @package WooCommerce/RestApi - * @since 3.5.0 */ +namespace WooCommerce\RestApi\Version4\Controllers\Data; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; + /** * REST API Data Currencies controller class. - * - * @package WooCommerce/RestApi */ -class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { +class Currencies extends DataController { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v3'; + protected $namespace = 'wc/v4'; /** * Route base. @@ -36,7 +37,9 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -46,7 +49,9 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { ) ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/current', array( + $this->namespace, + '/' . $this->rest_base . '/current', + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_current_item' ), @@ -56,7 +61,9 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { ) ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]{3})', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]{3})', + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php similarity index 95% rename from src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php rename to src/RestApi/Version4/Controllers/Data/DownloadIPs.php index 36e2431d0b9..14e85fd24a7 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-data-download-ips-controller.php +++ b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php @@ -4,18 +4,19 @@ * * Handles requests to /data/download-ips * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers\Data; + defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; + /** * Data Download IP controller. - * - * @package WooCommerce Admin/API - * @extends WC_REST_Data_Controller */ -class WC_Admin_REST_Data_Download_Ips_Controller extends WC_REST_Data_Controller { +class DownloadIPs extends DataController { /** * Endpoint namespace. * diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md index c76f50bcdb9..9359f75b0ec 100644 --- a/src/RestApi/Version4/changelog.md +++ b/src/RestApi/Version4/changelog.md @@ -12,25 +12,25 @@ ## New endpoints -- Added `reports/products` endpoint. -- Added `reports/products/stats` endpoint. -- Added `reports/categories` endpoint. -- Added `reports/orders` endpoint. -- Added `reports/orders/stats` endpoint. -- Added `reports/performance-indicators` endpoint. -- Added `reports/revenue/stats` endpoint. -- Added `reports/stock` endpoint. -- Added `reports/stock/stats` endpoint. -- Added `reports/taxes` endpoint. -- Added `reports/taxes/stats` endpoint. -- Added `reports/variations` endpoint. -- Added `reports/coupons` endpoint. -- Added `reports/coupons/stats` endpoint. -- Added `reports/customer` endpoint. -- Added `reports/customers/stats` endpoint. -- Added `reports/downloads` endpoint. -- Added `reports/downloads/stats` endpoint. -- Added `reports/import` endpoint. +- `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` ## Removed endpoints diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-controller.php b/src/RestApi/Version4/class-wc-admin-rest-data-controller.php deleted file mode 100644 index 227ec85a150..00000000000 --- a/src/RestApi/Version4/class-wc-admin-rest-data-controller.php +++ /dev/null @@ -1,47 +0,0 @@ -data[] = $this->prepare_response_for_collection( - $this->prepare_item_for_response( - (object) array( - 'slug' => 'download-ips', - 'description' => __( 'An endpoint used for searching download logs for a specific IP address.', 'woocommerce' ), - ), - $request - ) - ); - return $response; - } - -} diff --git a/src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php b/src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php deleted file mode 100644 index f4f7ea0bda8..00000000000 --- a/src/RestApi/Version4/class-wc-admin-rest-data-countries-controller.php +++ /dev/null @@ -1,27 +0,0 @@ - Date: Thu, 30 May 2019 15:34:34 +0100 Subject: [PATCH 039/440] Continued namespacing --- ...-controller.php => AbstractController.php} | 17 ++++++------ ...ller.php => AbstractObjectsController.php} | 21 +++++---------- ...roller.php => AbstractPostsController.php} | 23 ++++++---------- ...hp => AbstractShippingZonesController.php} | 19 +++++-------- ...troller.php => AbstractTermsContoller.php} | 11 ++++---- src/RestApi/Version4/Controllers/Coupons.php | 7 ----- .../Controllers/CustomerDownloads.php | 7 ----- .../Version4/Controllers/Customers.php | 7 ----- src/RestApi/Version4/Controllers/Data.php | 7 ----- .../Version4/Controllers/Data/Continents.php | 7 ----- .../Version4/Controllers/Data/Countries.php | 7 ----- .../Version4/Controllers/Data/Currencies.php | 7 ----- .../Version4/Controllers/Data/DownloadIPs.php | 6 ----- .../Version4/Controllers/OrderNotes.php | 7 ----- .../Version4/Controllers/OrderRefunds.php | 7 ----- src/RestApi/Version4/Controllers/Orders.php | 8 ------ .../Controllers/ProductAttributeTerms.php | 11 ++------ .../Controllers/ProductAttributes.php | 7 ----- .../Controllers/ProductCategories.php | 11 ++------ .../Version4/Controllers/ProductReviews.php | 7 ----- .../Controllers/ProductShippingClasses.php | 11 ++------ .../Version4/Controllers/ProductTags.php | 11 ++------ src/RestApi/Version4/Controllers/Products.php | 7 ----- src/RestApi/Version4/Controllers/Reports.php | 7 ----- .../Controllers/Reports/Categories.php | 7 ----- .../Controllers/Reports/CouponStats.php | 8 ------ .../Version4/Controllers/Reports/Coupons.php | 7 ----- .../Controllers/Reports/CustomerStats.php | 6 ----- .../Controllers/Reports/Customers.php | 7 ----- .../Controllers/Reports/DownloadStats.php | 7 ----- .../Controllers/Reports/Downloads.php | 7 ----- .../Version4/Controllers/Reports/Import.php | 6 ----- .../Controllers/Reports/OrderStats.php | 7 ----- .../Version4/Controllers/Reports/Orders.php | 7 ----- .../Reports/PerformanceIndicators.php | 7 ----- .../Controllers/Reports/ProductStats.php | 7 ----- .../Version4/Controllers/Reports/Products.php | 7 ----- .../Controllers/Reports/RevenueStats.php | 7 ----- .../Version4/Controllers/Reports/Stock.php | 7 ----- .../Controllers/Reports/StockStats.php | 7 ----- .../Version4/Controllers/Reports/TaxStats.php | 7 ----- .../Version4/Controllers/Reports/Taxes.php | 7 ----- .../Controllers/Reports/Variations.php | 7 ----- .../SystemStatus.php} | 21 +++++---------- .../SystemStatusTools.php} | 21 +++++---------- .../Version4/Controllers/TaxClasses.php | 7 ----- src/RestApi/Version4/Controllers/Taxes.php | 7 ----- src/RestApi/Version4/Controllers/Webhooks.php | 7 ----- src/RestApi/Version4/changelog.md | 1 + ...-admin-rest-setting-options-controller.php | 27 ------------------- ...lass-wc-rest-network-orders-controller.php | 27 ------------------- ...ss-wc-rest-shipping-methods-controller.php | 27 ------------------- ...est-shipping-zone-locations-controller.php | 27 ------------------- ...-rest-shipping-zone-methods-controller.php | 27 ------------------- ...lass-wc-rest-shipping-zones-controller.php | 27 ------------------- ...class-wc-rest-system-status-controller.php | 27 ------------------- ...wc-rest-system-status-tools-controller.php | 27 ------------------- 57 files changed, 59 insertions(+), 593 deletions(-) rename src/RestApi/Version4/{class-wc-rest-controller.php => AbstractController.php} (97%) rename src/RestApi/Version4/{class-wc-rest-crud-controller.php => AbstractObjectsController.php} (98%) rename src/RestApi/Version4/{class-wc-rest-posts-controller.php => AbstractPostsController.php} (98%) rename src/RestApi/Version4/{class-wc-rest-shipping-zones-controller-base.php => AbstractShippingZonesController.php} (93%) rename src/RestApi/Version4/{class-wc-rest-terms-controller.php => AbstractTermsContoller.php} (99%) rename src/RestApi/Version4/{class-wc-rest-system-status-v2-controller.php => Controllers/SystemStatus.php} (99%) rename src/RestApi/Version4/{class-wc-rest-system-status-tools-v2-controller.php => Controllers/SystemStatusTools.php} (98%) delete mode 100644 src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-network-orders-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-shipping-methods-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zone-locations-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zone-methods-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-shipping-zones-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-system-status-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-system-status-tools-controller.php diff --git a/src/RestApi/Version4/class-wc-rest-controller.php b/src/RestApi/Version4/AbstractController.php similarity index 97% rename from src/RestApi/Version4/class-wc-rest-controller.php rename to src/RestApi/Version4/AbstractController.php index e0ff5c4732c..d49a1df39d8 100644 --- a/src/RestApi/Version4/class-wc-rest-controller.php +++ b/src/RestApi/Version4/AbstractController.php @@ -8,17 +8,16 @@ * It's required to follow "Controller Classes" guide before extending this class: * * - * NOTE THAT ONLY CODE RELEVANT FOR MOST ENDPOINTS SHOULD BE INCLUDED INTO THIS CLASS. - * If necessary extend this class and create new abstract classes like `WC_REST_CRUD_Controller` or `WC_REST_Terms_Controller`. - * * @class WC_REST_Controller - * @package WooCommerce/RestApi * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ + * @package WooCommerce/RestApi */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4; + +defined( 'ABSPATH' ) || exit; + +use \WP_REST_Controller; /** * Abstract Rest Controller Class @@ -27,14 +26,14 @@ if ( ! defined( 'ABSPATH' ) ) { * @extends WP_REST_Controller * @version 2.6.0 */ -abstract class WC_REST_Controller extends WP_REST_Controller { +abstract class AbstractController extends WP_REST_Controller { /** * Endpoint namespace. * * @var string */ - protected $namespace = 'wc/v1'; + protected $namespace = 'wc/v4'; /** * Route base. diff --git a/src/RestApi/Version4/class-wc-rest-crud-controller.php b/src/RestApi/Version4/AbstractObjectsController.php similarity index 98% rename from src/RestApi/Version4/class-wc-rest-crud-controller.php rename to src/RestApi/Version4/AbstractObjectsController.php index 6953ee2cb52..005ee51f3aa 100644 --- a/src/RestApi/Version4/class-wc-rest-crud-controller.php +++ b/src/RestApi/Version4/AbstractObjectsController.php @@ -2,28 +2,21 @@ /** * Abstract Rest CRUD Controller Class * - * @class WC_REST_CRUD_Controller * @package WooCommerce/RestApi - * @version 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4; + +defined( 'ABSPATH' ) || exit; + +use AbstractPostsController; /** - * WC_REST_CRUD_Controller class. + * CRUD Object Controller. * * @extends WC_REST_Posts_Controller */ -abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; +abstract class AbstractObjectsController extends AbstractPostsController { /** * If object is hierarchical. diff --git a/src/RestApi/Version4/class-wc-rest-posts-controller.php b/src/RestApi/Version4/AbstractPostsController.php similarity index 98% rename from src/RestApi/Version4/class-wc-rest-posts-controller.php rename to src/RestApi/Version4/AbstractPostsController.php index d5966551502..931aa9a82a1 100644 --- a/src/RestApi/Version4/class-wc-rest-posts-controller.php +++ b/src/RestApi/Version4/AbstractPostsController.php @@ -2,28 +2,21 @@ /** * Abstract Rest Posts Controller Class * - * @class WC_REST_Posts_Controller * @package WooCommerce/RestApi */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4; + +defined( 'ABSPATH' ) || exit; + +use AbstractController; /** - * WC_REST_Posts_Controller + * POSTS Controller. * - * @package WooCommerce/RestApi - * @version 2.6.0 + * @extends AbstractController */ -abstract class WC_REST_Posts_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; +abstract class AbstractPostsController extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zones-controller-base.php b/src/RestApi/Version4/AbstractShippingZonesController.php similarity index 93% rename from src/RestApi/Version4/class-wc-rest-shipping-zones-controller-base.php rename to src/RestApi/Version4/AbstractShippingZonesController.php index 7b8cc282f3b..d8b25e23a23 100644 --- a/src/RestApi/Version4/class-wc-rest-shipping-zones-controller-base.php +++ b/src/RestApi/Version4/AbstractShippingZonesController.php @@ -8,24 +8,19 @@ * @since 3.0.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use AbstractController; /** * REST API Shipping Zones base class. * * @package WooCommerce/RestApi - * @extends WC_REST_Controller + * @extends AbstractController */ -abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; +abstract class WC_REST_Shipping_Zones_Controller_Base extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/class-wc-rest-terms-controller.php b/src/RestApi/Version4/AbstractTermsContoller.php similarity index 99% rename from src/RestApi/Version4/class-wc-rest-terms-controller.php rename to src/RestApi/Version4/AbstractTermsContoller.php index d9588099149..7363fa98781 100644 --- a/src/RestApi/Version4/class-wc-rest-terms-controller.php +++ b/src/RestApi/Version4/AbstractTermsContoller.php @@ -3,17 +3,18 @@ * Abstract Rest Terms Controller * * @package WooCommerce/RestApi - * @version 3.3.0 */ -if ( ! defined( 'ABSPATH' ) ) { - exit; -} +namespace WooCommerce\RestApi\Version4\Controllers; + +defined( 'ABSPATH' ) || exit; + +use AbstractController; /** * Terms controller class. */ -abstract class WC_REST_Terms_Controller extends WC_REST_Controller { +abstract class AbstractTermsContoller extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/RestApi/Version4/Controllers/Coupons.php index c71704ab234..85cc298229f 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -18,13 +18,6 @@ use \WC_REST_Posts_Controller; */ class Coupons extends WC_REST_Posts_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/CustomerDownloads.php b/src/RestApi/Version4/Controllers/CustomerDownloads.php index 07331636d4b..2e6de771f6b 100644 --- a/src/RestApi/Version4/Controllers/CustomerDownloads.php +++ b/src/RestApi/Version4/Controllers/CustomerDownloads.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class CustomerDownloads extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/RestApi/Version4/Controllers/Customers.php index 221f64c2069..e5f866b82d8 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class Customers extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Data.php b/src/RestApi/Version4/Controllers/Data.php index 141d7f2f166..b78d89a4d71 100644 --- a/src/RestApi/Version4/Controllers/Data.php +++ b/src/RestApi/Version4/Controllers/Data.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class Data extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Data/Continents.php b/src/RestApi/Version4/Controllers/Data/Continents.php index a47f30c9f29..d8d05249b60 100644 --- a/src/RestApi/Version4/Controllers/Data/Continents.php +++ b/src/RestApi/Version4/Controllers/Data/Continents.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; */ class Continents extends DataController { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Data/Countries.php b/src/RestApi/Version4/Controllers/Data/Countries.php index 597bad1d1f4..2f95f9ca0ba 100644 --- a/src/RestApi/Version4/Controllers/Data/Countries.php +++ b/src/RestApi/Version4/Controllers/Data/Countries.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; */ class Countries extends DataController { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Data/Currencies.php b/src/RestApi/Version4/Controllers/Data/Currencies.php index 57a29917c0e..ab6149e8604 100644 --- a/src/RestApi/Version4/Controllers/Data/Currencies.php +++ b/src/RestApi/Version4/Controllers/Data/Currencies.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; */ class Currencies extends DataController { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php index 14e85fd24a7..127b19b0642 100644 --- a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php +++ b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php @@ -17,12 +17,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; * Data Download IP controller. */ class DownloadIPs extends DataController { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; /** * Route base. diff --git a/src/RestApi/Version4/Controllers/OrderNotes.php b/src/RestApi/Version4/Controllers/OrderNotes.php index 30121db7203..7861423963b 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class OrderNotes extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/OrderRefunds.php b/src/RestApi/Version4/Controllers/OrderRefunds.php index 9a88b320052..6e55da12263 100644 --- a/src/RestApi/Version4/Controllers/OrderRefunds.php +++ b/src/RestApi/Version4/Controllers/OrderRefunds.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Orders as Orders; */ class OrderRefunds extends Orders { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index 96920472531..cb76817f527 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -18,14 +18,6 @@ use \WC_REST_CRUD_Controller; */ class Orders extends WC_REST_CRUD_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php index abeb9c8c8d3..141e17c74e6 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php +++ b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php @@ -11,19 +11,12 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Terms_Controller; +use AbstractTermsContoller; /** * REST API Product Attribute Terms controller class. */ -class ProductAttributeTerms extends WC_REST_Terms_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; +class ProductAttributeTerms extends AbstractTermsContoller { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/ProductAttributes.php b/src/RestApi/Version4/Controllers/ProductAttributes.php index c03b84a2fb7..bb701caa81a 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributes.php +++ b/src/RestApi/Version4/Controllers/ProductAttributes.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class ProductAttributes extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/ProductCategories.php b/src/RestApi/Version4/Controllers/ProductCategories.php index 743bcd511a6..25e8527198f 100644 --- a/src/RestApi/Version4/Controllers/ProductCategories.php +++ b/src/RestApi/Version4/Controllers/ProductCategories.php @@ -11,19 +11,12 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Terms_Controller; +use AbstractTermsContoller; /** * REST API Product Categories controller class. */ -class ProductCategories extends WC_REST_Terms_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; +class ProductCategories extends AbstractTermsContoller { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/RestApi/Version4/Controllers/ProductReviews.php index 4eab95ee7a1..026ff50c933 100644 --- a/src/RestApi/Version4/Controllers/ProductReviews.php +++ b/src/RestApi/Version4/Controllers/ProductReviews.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class ProductReviews extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/ProductShippingClasses.php b/src/RestApi/Version4/Controllers/ProductShippingClasses.php index 47e150a5272..dc8aee04bbd 100644 --- a/src/RestApi/Version4/Controllers/ProductShippingClasses.php +++ b/src/RestApi/Version4/Controllers/ProductShippingClasses.php @@ -11,19 +11,12 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Terms_Controller; +use AbstractTermsContoller; /** * REST API Product Shipping Classes controller class. */ -class ProductShippingClasses extends WC_REST_Terms_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; +class ProductShippingClasses extends AbstractTermsContoller { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/ProductTags.php b/src/RestApi/Version4/Controllers/ProductTags.php index 77d6118dfea..bf360176d60 100644 --- a/src/RestApi/Version4/Controllers/ProductTags.php +++ b/src/RestApi/Version4/Controllers/ProductTags.php @@ -11,19 +11,12 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Terms_Controller; +use AbstractTermsContoller; /** * REST API Product Tags controller class. */ -class ProductTags extends WC_REST_Terms_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; +class ProductTags extends AbstractTermsContoller { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/RestApi/Version4/Controllers/Products.php index d60b523df75..ca139ab7a39 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -18,13 +18,6 @@ use \WC_REST_CRUD_Controller; */ class Products extends WC_REST_CRUD_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php index 72a8dc96631..d8f16389084 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class Reports extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/Categories.php b/src/RestApi/Version4/Controllers/Reports/Categories.php index d5cde576636..fa12c0b15f8 100644 --- a/src/RestApi/Version4/Controllers/Reports/Categories.php +++ b/src/RestApi/Version4/Controllers/Reports/Categories.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Categories extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/CouponStats.php b/src/RestApi/Version4/Controllers/Reports/CouponStats.php index fe655e18af9..c2fd328f86a 100644 --- a/src/RestApi/Version4/Controllers/Reports/CouponStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CouponStats.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class CouponStats extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * @@ -32,7 +25,6 @@ class CouponStats extends Reports { */ protected $rest_base = 'reports/coupons/stats'; - /** * Maps query arguments from the REST request. * diff --git a/src/RestApi/Version4/Controllers/Reports/Coupons.php b/src/RestApi/Version4/Controllers/Reports/Coupons.php index 3821e17bd07..73872d44d34 100644 --- a/src/RestApi/Version4/Controllers/Reports/Coupons.php +++ b/src/RestApi/Version4/Controllers/Reports/Coupons.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Coupons extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php index e604aeacb97..3ae9ef010e2 100644 --- a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php @@ -17,12 +17,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; * REST API CustomerStats Reports class. */ class CustomerStats extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Reports/Customers.php b/src/RestApi/Version4/Controllers/Reports/Customers.php index da23ebb5d15..b732c37dc5c 100644 --- a/src/RestApi/Version4/Controllers/Reports/Customers.php +++ b/src/RestApi/Version4/Controllers/Reports/Customers.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Customers extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php index 08da58d69ab..26fbae46b83 100644 --- a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php +++ b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class DownloadStats extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/Downloads.php b/src/RestApi/Version4/Controllers/Reports/Downloads.php index 256117c37ca..9f0c6e56ca8 100644 --- a/src/RestApi/Version4/Controllers/Reports/Downloads.php +++ b/src/RestApi/Version4/Controllers/Reports/Downloads.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Downloads extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/Import.php b/src/RestApi/Version4/Controllers/Reports/Import.php index 26db4b41ce3..e6bd5e29f60 100644 --- a/src/RestApi/Version4/Controllers/Reports/Import.php +++ b/src/RestApi/Version4/Controllers/Reports/Import.php @@ -17,12 +17,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; * REST API Import Reports class. */ class Import extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Reports/OrderStats.php b/src/RestApi/Version4/Controllers/Reports/OrderStats.php index 4f60962102a..cbe04fff6ac 100644 --- a/src/RestApi/Version4/Controllers/Reports/OrderStats.php +++ b/src/RestApi/Version4/Controllers/Reports/OrderStats.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class OrderStats extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/Orders.php b/src/RestApi/Version4/Controllers/Reports/Orders.php index 2d7a8ec9f07..21addc6ce79 100644 --- a/src/RestApi/Version4/Controllers/Reports/Orders.php +++ b/src/RestApi/Version4/Controllers/Reports/Orders.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Orders extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php index ebc0bf052ac..9fd1becb564 100644 --- a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php +++ b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class PerformanceIndicators extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/ProductStats.php b/src/RestApi/Version4/Controllers/Reports/ProductStats.php index acb4b42d6cc..ec0b82eec0b 100644 --- a/src/RestApi/Version4/Controllers/Reports/ProductStats.php +++ b/src/RestApi/Version4/Controllers/Reports/ProductStats.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class ProductStats extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/Products.php b/src/RestApi/Version4/Controllers/Reports/Products.php index 214506b6bd8..e9c7622d262 100644 --- a/src/RestApi/Version4/Controllers/Reports/Products.php +++ b/src/RestApi/Version4/Controllers/Reports/Products.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Products extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php index 5533a211a6b..ac15f34cd0c 100644 --- a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php +++ b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class RevenueStats extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/Stock.php b/src/RestApi/Version4/Controllers/Reports/Stock.php index 9ff7535bf53..e8e9757474f 100644 --- a/src/RestApi/Version4/Controllers/Reports/Stock.php +++ b/src/RestApi/Version4/Controllers/Reports/Stock.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Stock extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/StockStats.php b/src/RestApi/Version4/Controllers/Reports/StockStats.php index 101f90369f1..83343e44abc 100644 --- a/src/RestApi/Version4/Controllers/Reports/StockStats.php +++ b/src/RestApi/Version4/Controllers/Reports/StockStats.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class StockStats extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/TaxStats.php b/src/RestApi/Version4/Controllers/Reports/TaxStats.php index ae81a1c2626..b93e24fcc45 100644 --- a/src/RestApi/Version4/Controllers/Reports/TaxStats.php +++ b/src/RestApi/Version4/Controllers/Reports/TaxStats.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class TaxStats extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/Taxes.php b/src/RestApi/Version4/Controllers/Reports/Taxes.php index 2a68ba10266..49fdfea5b07 100644 --- a/src/RestApi/Version4/Controllers/Reports/Taxes.php +++ b/src/RestApi/Version4/Controllers/Reports/Taxes.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Taxes extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Reports/Variations.php b/src/RestApi/Version4/Controllers/Reports/Variations.php index f2fed45f205..0b3599ceec8 100644 --- a/src/RestApi/Version4/Controllers/Reports/Variations.php +++ b/src/RestApi/Version4/Controllers/Reports/Variations.php @@ -18,13 +18,6 @@ use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; */ class Variations extends Reports { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/class-wc-rest-system-status-v2-controller.php b/src/RestApi/Version4/Controllers/SystemStatus.php similarity index 99% rename from src/RestApi/Version4/class-wc-rest-system-status-v2-controller.php rename to src/RestApi/Version4/Controllers/SystemStatus.php index d141e656009..2919b5557c7 100644 --- a/src/RestApi/Version4/class-wc-rest-system-status-v2-controller.php +++ b/src/RestApi/Version4/Controllers/SystemStatus.php @@ -5,25 +5,18 @@ * Handles requests to the /system_status endpoint. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; -/** - * System status controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller - */ -class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { +use \WC_REST_Controller; - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; +/** + * REST API System Status controller class. + */ +class SystemStatus extends WC_REST_Controller { /** * Route base. diff --git a/src/RestApi/Version4/class-wc-rest-system-status-tools-v2-controller.php b/src/RestApi/Version4/Controllers/SystemStatusTools.php similarity index 98% rename from src/RestApi/Version4/class-wc-rest-system-status-tools-v2-controller.php rename to src/RestApi/Version4/Controllers/SystemStatusTools.php index a0e91c97346..f38b4762c35 100644 --- a/src/RestApi/Version4/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/RestApi/Version4/Controllers/SystemStatusTools.php @@ -5,25 +5,18 @@ * Handles requests to the /system_status/tools/* endpoints. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; -/** - * System status tools controller. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller - */ -class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { +use \WC_REST_Controller; - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; +/** + * REST API System Status Tools controller class. + */ +class SystemStatusTools extends WC_REST_Controller { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/RestApi/Version4/Controllers/TaxClasses.php index 8587cdaf472..b5bf627c647 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class TaxClasses extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Taxes.php b/src/RestApi/Version4/Controllers/Taxes.php index c5f5af74f43..00bed597d31 100644 --- a/src/RestApi/Version4/Controllers/Taxes.php +++ b/src/RestApi/Version4/Controllers/Taxes.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class Taxes extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/Controllers/Webhooks.php b/src/RestApi/Version4/Controllers/Webhooks.php index 69f882c76a2..c70adcd0a58 100644 --- a/src/RestApi/Version4/Controllers/Webhooks.php +++ b/src/RestApi/Version4/Controllers/Webhooks.php @@ -18,13 +18,6 @@ use \WC_REST_Controller; */ class Webhooks extends WC_REST_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - /** * Route base. * diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md index 9359f75b0ec..4db377e409b 100644 --- a/src/RestApi/Version4/changelog.md +++ b/src/RestApi/Version4/changelog.md @@ -31,6 +31,7 @@ - `reports/downloads` - `reports/downloads/stats` - `reports/import` +- `data/download-ips` ## Removed endpoints diff --git a/src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php b/src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php deleted file mode 100644 index bfa1a2fe6ec..00000000000 --- a/src/RestApi/Version4/class-wc-admin-rest-setting-options-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/locations endpoint. - * - * @package WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Shipping Zone Locations class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Shipping_Zone_Locations_V2_Controller - */ -class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zone_Locations_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; -} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-controller.php b/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-controller.php deleted file mode 100644 index 3ed5cf4e08b..00000000000 --- a/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/methods endpoint. - * - * @package WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Shipping Zone Methods class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Shipping_Zone_Methods_V2_Controller - */ -class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zone_Methods_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; -} diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zones-controller.php b/src/RestApi/Version4/class-wc-rest-shipping-zones-controller.php deleted file mode 100644 index 778861bff5c..00000000000 --- a/src/RestApi/Version4/class-wc-rest-shipping-zones-controller.php +++ /dev/null @@ -1,27 +0,0 @@ - Date: Thu, 30 May 2019 15:45:46 +0100 Subject: [PATCH 040/440] Abstracts --- .../{ => Controllers}/AbstractController.php | 2 +- .../AbstractObjectsController.php | 2 -- .../AbstractPostsController.php | 0 .../AbstractShippingZonesController.php | 2 +- .../AbstractTermsContoller.php | 0 src/RestApi/Version4/Controllers/Coupons.php | 4 +--- .../Controllers/CustomerDownloads.php | 4 +--- .../Version4/Controllers/Customers.php | 4 +--- src/RestApi/Version4/Controllers/Data.php | 4 +--- .../Version4/Controllers/OrderNotes.php | 4 +--- .../Version4/Controllers/OrderRefunds.php | 2 -- src/RestApi/Version4/Controllers/Orders.php | 4 +--- .../Controllers/ProductAttributeTerms.php | 2 -- .../Controllers/ProductAttributes.php | 4 +--- .../Controllers/ProductCategories.php | 2 -- .../Version4/Controllers/ProductReviews.php | 4 +--- .../Controllers/ProductShippingClasses.php | 2 -- .../Version4/Controllers/ProductTags.php | 2 -- src/RestApi/Version4/Controllers/Products.php | 4 +--- src/RestApi/Version4/Controllers/Reports.php | 4 +--- .../ShippingZoneLocations.php} | 12 ++++++------ .../ShippingZoneMethods.php} | 19 +++++++++++-------- .../ShippingZones.php} | 19 +++++++++++-------- .../Version4/Controllers/SystemStatus.php | 4 +--- .../Controllers/SystemStatusTools.php | 4 +--- .../Version4/Controllers/TaxClasses.php | 4 +--- src/RestApi/Version4/Controllers/Taxes.php | 4 +--- src/RestApi/Version4/Controllers/Webhooks.php | 4 +--- 28 files changed, 45 insertions(+), 81 deletions(-) rename src/RestApi/Version4/{ => Controllers}/AbstractController.php (99%) rename src/RestApi/Version4/{ => Controllers}/AbstractObjectsController.php (99%) rename src/RestApi/Version4/{ => Controllers}/AbstractPostsController.php (100%) rename src/RestApi/Version4/{ => Controllers}/AbstractShippingZonesController.php (97%) rename src/RestApi/Version4/{ => Controllers}/AbstractTermsContoller.php (100%) rename src/RestApi/Version4/{class-wc-rest-shipping-zone-locations-v2-controller.php => Controllers/ShippingZoneLocations.php} (94%) rename src/RestApi/Version4/{class-wc-rest-shipping-zone-methods-v2-controller.php => Controllers/ShippingZoneMethods.php} (97%) rename src/RestApi/Version4/{class-wc-rest-shipping-zones-v2-controller.php => Controllers/ShippingZones.php} (96%) diff --git a/src/RestApi/Version4/AbstractController.php b/src/RestApi/Version4/Controllers/AbstractController.php similarity index 99% rename from src/RestApi/Version4/AbstractController.php rename to src/RestApi/Version4/Controllers/AbstractController.php index d49a1df39d8..883f6d96b3e 100644 --- a/src/RestApi/Version4/AbstractController.php +++ b/src/RestApi/Version4/Controllers/AbstractController.php @@ -13,7 +13,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4; +namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/AbstractObjectsController.php b/src/RestApi/Version4/Controllers/AbstractObjectsController.php similarity index 99% rename from src/RestApi/Version4/AbstractObjectsController.php rename to src/RestApi/Version4/Controllers/AbstractObjectsController.php index 005ee51f3aa..6373502db3b 100644 --- a/src/RestApi/Version4/AbstractObjectsController.php +++ b/src/RestApi/Version4/Controllers/AbstractObjectsController.php @@ -13,8 +13,6 @@ use AbstractPostsController; /** * CRUD Object Controller. - * - * @extends WC_REST_Posts_Controller */ abstract class AbstractObjectsController extends AbstractPostsController { diff --git a/src/RestApi/Version4/AbstractPostsController.php b/src/RestApi/Version4/Controllers/AbstractPostsController.php similarity index 100% rename from src/RestApi/Version4/AbstractPostsController.php rename to src/RestApi/Version4/Controllers/AbstractPostsController.php diff --git a/src/RestApi/Version4/AbstractShippingZonesController.php b/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php similarity index 97% rename from src/RestApi/Version4/AbstractShippingZonesController.php rename to src/RestApi/Version4/Controllers/AbstractShippingZonesController.php index d8b25e23a23..f99a3cc547c 100644 --- a/src/RestApi/Version4/AbstractShippingZonesController.php +++ b/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php @@ -20,7 +20,7 @@ use AbstractController; * @package WooCommerce/RestApi * @extends AbstractController */ -abstract class WC_REST_Shipping_Zones_Controller_Base extends AbstractController { +abstract class AbstractShippingZonesController extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/AbstractTermsContoller.php b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php similarity index 100% rename from src/RestApi/Version4/AbstractTermsContoller.php rename to src/RestApi/Version4/Controllers/AbstractTermsContoller.php diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/RestApi/Version4/Controllers/Coupons.php index 85cc298229f..a1ef7cfb71c 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Posts_Controller; - /** * REST API Coupons controller class. */ -class Coupons extends WC_REST_Posts_Controller { +class Coupons extends AbstractPostsController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/CustomerDownloads.php b/src/RestApi/Version4/Controllers/CustomerDownloads.php index 2e6de771f6b..e29e1e7867f 100644 --- a/src/RestApi/Version4/Controllers/CustomerDownloads.php +++ b/src/RestApi/Version4/Controllers/CustomerDownloads.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Customer Downloads controller class. */ -class CustomerDownloads extends WC_REST_Controller { +class CustomerDownloads extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/RestApi/Version4/Controllers/Customers.php index e5f866b82d8..34e0d1d373f 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Customers controller class. */ -class Customers extends WC_REST_Controller { +class Customers extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Data.php b/src/RestApi/Version4/Controllers/Data.php index b78d89a4d71..767183e26d5 100644 --- a/src/RestApi/Version4/Controllers/Data.php +++ b/src/RestApi/Version4/Controllers/Data.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Coupons controller class. */ -class Data extends WC_REST_Controller { +class Data extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/OrderNotes.php b/src/RestApi/Version4/Controllers/OrderNotes.php index 7861423963b..496da144226 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Order Notes controller class. */ -class OrderNotes extends WC_REST_Controller { +class OrderNotes extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/OrderRefunds.php b/src/RestApi/Version4/Controllers/OrderRefunds.php index 6e55da12263..8f060695af5 100644 --- a/src/RestApi/Version4/Controllers/OrderRefunds.php +++ b/src/RestApi/Version4/Controllers/OrderRefunds.php @@ -11,8 +11,6 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Orders as Orders; - /** * REST API Order Refunds controller class. */ diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index cb76817f527..3d96ac4d35b 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_CRUD_Controller; - /** * REST API Orders controller class. */ -class Orders extends WC_REST_CRUD_Controller { +class Orders extends AbstractObjectsController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php index 141e17c74e6..06caad9a04f 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php +++ b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php @@ -11,8 +11,6 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use AbstractTermsContoller; - /** * REST API Product Attribute Terms controller class. */ diff --git a/src/RestApi/Version4/Controllers/ProductAttributes.php b/src/RestApi/Version4/Controllers/ProductAttributes.php index bb701caa81a..7a5031dad33 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributes.php +++ b/src/RestApi/Version4/Controllers/ProductAttributes.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Product Attributes controller class. */ -class ProductAttributes extends WC_REST_Controller { +class ProductAttributes extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/ProductCategories.php b/src/RestApi/Version4/Controllers/ProductCategories.php index 25e8527198f..d708ebb39f2 100644 --- a/src/RestApi/Version4/Controllers/ProductCategories.php +++ b/src/RestApi/Version4/Controllers/ProductCategories.php @@ -11,8 +11,6 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use AbstractTermsContoller; - /** * REST API Product Categories controller class. */ diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/RestApi/Version4/Controllers/ProductReviews.php index 026ff50c933..432b4c77316 100644 --- a/src/RestApi/Version4/Controllers/ProductReviews.php +++ b/src/RestApi/Version4/Controllers/ProductReviews.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Product Reviews controller class. */ -class ProductReviews extends WC_REST_Controller { +class ProductReviews extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/ProductShippingClasses.php b/src/RestApi/Version4/Controllers/ProductShippingClasses.php index dc8aee04bbd..2d23f4538d2 100644 --- a/src/RestApi/Version4/Controllers/ProductShippingClasses.php +++ b/src/RestApi/Version4/Controllers/ProductShippingClasses.php @@ -11,8 +11,6 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use AbstractTermsContoller; - /** * REST API Product Shipping Classes controller class. */ diff --git a/src/RestApi/Version4/Controllers/ProductTags.php b/src/RestApi/Version4/Controllers/ProductTags.php index bf360176d60..1c88233f4aa 100644 --- a/src/RestApi/Version4/Controllers/ProductTags.php +++ b/src/RestApi/Version4/Controllers/ProductTags.php @@ -11,8 +11,6 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use AbstractTermsContoller; - /** * REST API Product Tags controller class. */ diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/RestApi/Version4/Controllers/Products.php index ca139ab7a39..df2c7e7fd56 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_CRUD_Controller; - /** * REST API Products controller class. */ -class Products extends WC_REST_CRUD_Controller { +class Products extends AbstractObjectsController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php index d8f16389084..5ca2d516e75 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API reports controller class. */ -class Reports extends WC_REST_Controller { +class Reports extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zone-locations-v2-controller.php b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php similarity index 94% rename from src/RestApi/Version4/class-wc-rest-shipping-zone-locations-v2-controller.php rename to src/RestApi/Version4/Controllers/ShippingZoneLocations.php index 4fd40bc9060..19a9d5c29b3 100644 --- a/src/RestApi/Version4/class-wc-rest-shipping-zone-locations-v2-controller.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php @@ -5,25 +5,25 @@ * Handles requests to the /shipping/zones//locations endpoint. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Locations class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Shipping_Zones_Controller_Base */ -class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { +class ShippingZoneLocations extends AbstractShippingZonesController { /** * Register the routes for Shipping Zone Locations. */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/locations', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)/locations', + array( 'args' => array( 'id' => array( 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-v2-controller.php b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php similarity index 97% rename from src/RestApi/Version4/class-wc-rest-shipping-zone-methods-v2-controller.php rename to src/RestApi/Version4/Controllers/ShippingZoneMethods.php index 3cd52028ea6..979026f0948 100644 --- a/src/RestApi/Version4/class-wc-rest-shipping-zone-methods-v2-controller.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php @@ -5,25 +5,25 @@ * Handles requests to the /shipping/zones//methods endpoint. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Methods class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Shipping_Zones_Controller_Base */ -class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { +class ShippingZoneMethods extends AbstractShippingZonesController { /** * Register the routes for Shipping Zone Methods. */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)/methods', + array( 'args' => array( 'zone_id' => array( 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), @@ -40,7 +40,8 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( 'method_id' => array( 'required' => true, 'readonly' => false, @@ -54,7 +55,9 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', + array( 'args' => array( 'zone_id' => array( 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), diff --git a/src/RestApi/Version4/class-wc-rest-shipping-zones-v2-controller.php b/src/RestApi/Version4/Controllers/ShippingZones.php similarity index 96% rename from src/RestApi/Version4/class-wc-rest-shipping-zones-v2-controller.php rename to src/RestApi/Version4/Controllers/ShippingZones.php index 17038d2d9e5..5b689046078 100644 --- a/src/RestApi/Version4/class-wc-rest-shipping-zones-v2-controller.php +++ b/src/RestApi/Version4/Controllers/ShippingZones.php @@ -5,25 +5,25 @@ * Handles requests to the /shipping/zones endpoint. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zones class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Shipping_Zones_Controller_Base */ -class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { +class ShippingZones extends AbstractShippingZonesController { /** * Register the routes for Shipping Zones. */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -34,7 +34,8 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( 'name' => array( 'required' => true, 'type' => 'string', @@ -48,7 +49,9 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d-]+)', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d-]+)', + array( 'args' => array( 'id' => array( 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), diff --git a/src/RestApi/Version4/Controllers/SystemStatus.php b/src/RestApi/Version4/Controllers/SystemStatus.php index 2919b5557c7..de3298cd846 100644 --- a/src/RestApi/Version4/Controllers/SystemStatus.php +++ b/src/RestApi/Version4/Controllers/SystemStatus.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API System Status controller class. */ -class SystemStatus extends WC_REST_Controller { +class SystemStatus extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/SystemStatusTools.php b/src/RestApi/Version4/Controllers/SystemStatusTools.php index f38b4762c35..d60944a7ef1 100644 --- a/src/RestApi/Version4/Controllers/SystemStatusTools.php +++ b/src/RestApi/Version4/Controllers/SystemStatusTools.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API System Status Tools controller class. */ -class SystemStatusTools extends WC_REST_Controller { +class SystemStatusTools extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/RestApi/Version4/Controllers/TaxClasses.php index b5bf627c647..fd31c64b14c 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Tax Class controller class. */ -class TaxClasses extends WC_REST_Controller { +class TaxClasses extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Taxes.php b/src/RestApi/Version4/Controllers/Taxes.php index 00bed597d31..a0d0387bd1a 100644 --- a/src/RestApi/Version4/Controllers/Taxes.php +++ b/src/RestApi/Version4/Controllers/Taxes.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Taxes controller class. */ -class Taxes extends WC_REST_Controller { +class Taxes extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/Controllers/Webhooks.php b/src/RestApi/Version4/Controllers/Webhooks.php index c70adcd0a58..3a8989654ba 100644 --- a/src/RestApi/Version4/Controllers/Webhooks.php +++ b/src/RestApi/Version4/Controllers/Webhooks.php @@ -11,12 +11,10 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use \WC_REST_Controller; - /** * REST API Webhooks controller class. */ -class Webhooks extends WC_REST_Controller { +class Webhooks extends AbstractController { /** * Route base. From a870b7332c342231c34b0f1142c9ebf4d6c8302d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 15:47:39 +0100 Subject: [PATCH 041/440] ShippingMethods --- .../ShippingMethods.php} | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) rename src/RestApi/Version4/{class-wc-rest-shipping-methods-v2-controller.php => Controllers/ShippingMethods.php} (94%) diff --git a/src/RestApi/Version4/class-wc-rest-shipping-methods-v2-controller.php b/src/RestApi/Version4/Controllers/ShippingMethods.php similarity index 94% rename from src/RestApi/Version4/class-wc-rest-shipping-methods-v2-controller.php rename to src/RestApi/Version4/Controllers/ShippingMethods.php index 9b8442a12fc..01154d3433d 100644 --- a/src/RestApi/Version4/class-wc-rest-shipping-methods-v2-controller.php +++ b/src/RestApi/Version4/Controllers/ShippingMethods.php @@ -5,25 +5,16 @@ * Handles requests to the /shipping_methods endpoint. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** * Shipping methods controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller */ -class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; +class ShippingMethods extends AbstractController { /** * Route base. @@ -37,7 +28,9 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -48,7 +41,9 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { ) ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]+)', + array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), From ddd75d71d6a93ae40b79c01f6c125086eb884b1e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 15:49:36 +0100 Subject: [PATCH 042/440] PaymentGateways --- .../PaymentGateways.php} | 35 ++- ...ss-wc-rest-payment-gateways-controller.php | 226 ------------------ 2 files changed, 17 insertions(+), 244 deletions(-) rename src/RestApi/Version4/{class-wc-rest-payment-gateways-v2-controller.php => Controllers/PaymentGateways.php} (96%) delete mode 100644 src/RestApi/Version4/class-wc-rest-payment-gateways-controller.php diff --git a/src/RestApi/Version4/class-wc-rest-payment-gateways-v2-controller.php b/src/RestApi/Version4/Controllers/PaymentGateways.php similarity index 96% rename from src/RestApi/Version4/class-wc-rest-payment-gateways-v2-controller.php rename to src/RestApi/Version4/Controllers/PaymentGateways.php index 96eece65ae4..eae55e59cbb 100644 --- a/src/RestApi/Version4/class-wc-rest-payment-gateways-v2-controller.php +++ b/src/RestApi/Version4/Controllers/PaymentGateways.php @@ -5,25 +5,16 @@ * Handles requests to the /payment_gateways endpoint. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** - * Paymenga gateways controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller + * Payment gateways controller class. */ -class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; +class PaymentGateways extends AbstractController { /** * Route base. @@ -258,6 +249,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { 'enabled' => ( 'yes' === $gateway->enabled ), 'method_title' => $gateway->get_method_title(), 'method_description' => $gateway->get_method_description(), + 'method_supports' => $gateway->supports, 'settings' => $this->get_settings( $gateway ), ); @@ -281,7 +273,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { /** * Return settings associated with this payment gateway. * - * @param WC_Payment_Gateway $gateway Gateway data. + * @param WC_Payment_Gateway $gateway Gateway instance. * * @return array */ @@ -293,14 +285,12 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { if ( empty( $field['title'] ) || empty( $field['type'] ) ) { continue; } - // Ignore 'title' settings/fields -- they are UI only. - if ( 'title' === $field['type'] ) { - continue; - } + // Ignore 'enabled' and 'description' which get included elsewhere. if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { continue; } + $data = array( 'id' => $id, 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], @@ -391,6 +381,15 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { 'context' => array( 'view', 'edit' ), 'readonly' => true, ), + 'method_supports' => array( + 'description' => __( 'Supported features for this payment gateway.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), 'settings' => array( 'description' => __( 'Payment gateway settings.', 'woocommerce' ), 'type' => 'object', diff --git a/src/RestApi/Version4/class-wc-rest-payment-gateways-controller.php b/src/RestApi/Version4/class-wc-rest-payment-gateways-controller.php deleted file mode 100644 index dc71790b6f7..00000000000 --- a/src/RestApi/Version4/class-wc-rest-payment-gateways-controller.php +++ /dev/null @@ -1,226 +0,0 @@ - $gateway->id, - 'title' => $gateway->title, - 'description' => $gateway->description, - 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', - 'enabled' => ( 'yes' === $gateway->enabled ), - 'method_title' => $gateway->get_method_title(), - 'method_description' => $gateway->get_method_description(), - 'method_supports' => $gateway->supports, - 'settings' => $this->get_settings( $gateway ), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $gateway, $request ) ); - - /** - * Filter payment gateway objects returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); - } - - /** - * Return settings associated with this payment gateway. - * - * @param WC_Payment_Gateway $gateway Gateway instance. - * - * @return array - */ - public function get_settings( $gateway ) { - $settings = array(); - $gateway->init_form_fields(); - foreach ( $gateway->form_fields as $id => $field ) { - // Make sure we at least have a title and type. - if ( empty( $field['title'] ) || empty( $field['type'] ) ) { - continue; - } - - // Ignore 'enabled' and 'description' which get included elsewhere. - if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { - continue; - } - - $data = array( - 'id' => $id, - 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - - /** - * Get the payment gateway schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'payment_gateway', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'absint', - ), - ), - 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - ), - 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_supports' => array( - 'description' => __( 'Supported features for this payment gateway.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} From 2b343e8a6712397eca1a959547f235b6847d926f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 15:54:11 +0100 Subject: [PATCH 043/440] Settings --- .../Version4/Controllers/PaymentGateways.php | 8 +- .../Settings.php} | 73 ++++++++---- .../class-wc-rest-settings-controller.php | 112 ------------------ 3 files changed, 56 insertions(+), 137 deletions(-) rename src/RestApi/Version4/{class-wc-rest-settings-v2-controller.php => Controllers/Settings.php} (78%) delete mode 100644 src/RestApi/Version4/class-wc-rest-settings-controller.php diff --git a/src/RestApi/Version4/Controllers/PaymentGateways.php b/src/RestApi/Version4/Controllers/PaymentGateways.php index eae55e59cbb..e5c511de844 100644 --- a/src/RestApi/Version4/Controllers/PaymentGateways.php +++ b/src/RestApi/Version4/Controllers/PaymentGateways.php @@ -28,7 +28,9 @@ class PaymentGateways extends AbstractController { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -39,7 +41,9 @@ class PaymentGateways extends AbstractController { ) ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]+)', + array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), diff --git a/src/RestApi/Version4/class-wc-rest-settings-v2-controller.php b/src/RestApi/Version4/Controllers/Settings.php similarity index 78% rename from src/RestApi/Version4/class-wc-rest-settings-v2-controller.php rename to src/RestApi/Version4/Controllers/Settings.php index 3b1dd0be705..38e59c3fe79 100644 --- a/src/RestApi/Version4/class-wc-rest-settings-v2-controller.php +++ b/src/RestApi/Version4/Controllers/Settings.php @@ -5,25 +5,16 @@ * Handles requests to the /settings endpoints. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** * REST API Settings controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller */ -class WC_REST_Settings_V2_Controller extends WC_REST_Controller { - - /** - * WP REST API namespace/version. - * - * @var string - */ - protected $namespace = 'wc/v2'; +class Settings extends AbstractController { /** * Route base. @@ -39,7 +30,9 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -48,6 +41,45 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { 'schema' => array( $this, 'get_public_item_schema' ), ) ); + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_batch_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 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; + } + + /** + * Update a setting. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $options_controller = new WC_REST_Setting_Options_Controller(); + $response = $options_controller->update_item( $request ); + + return $response; } /** @@ -197,32 +229,27 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { 'id' => array( 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, + 'context' => array( 'view', 'edit' ), ), 'label' => array( 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, + 'context' => array( 'view', 'edit' ), ), 'description' => array( 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, + 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( 'description' => __( 'ID of parent grouping.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, + 'context' => array( 'view', 'edit' ), ), 'sub_groups' => array( 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, + 'context' => array( 'view', 'edit' ), ), ), ); diff --git a/src/RestApi/Version4/class-wc-rest-settings-controller.php b/src/RestApi/Version4/class-wc-rest-settings-controller.php deleted file mode 100644 index 869f725144f..00000000000 --- a/src/RestApi/Version4/class-wc-rest-settings-controller.php +++ /dev/null @@ -1,112 +0,0 @@ -namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_batch_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 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; - } - - /** - * Update a setting. - * - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $options_controller = new WC_REST_Setting_Options_Controller(); - $response = $options_controller->update_item( $request ); - - return $response; - } - - /** - * Get the groups schema, conforming to JSON Schema. - * - * @since 3.0.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'setting_group', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} From f1186eaae1e67d5fced09341fad06add70cf7b61 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 15:55:11 +0100 Subject: [PATCH 044/440] NetworkOrders --- .../NetworkOrders.php} | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) rename src/RestApi/Version4/{class-wc-rest-network-orders-v2-controller.php => Controllers/NetworkOrders.php} (94%) diff --git a/src/RestApi/Version4/class-wc-rest-network-orders-v2-controller.php b/src/RestApi/Version4/Controllers/NetworkOrders.php similarity index 94% rename from src/RestApi/Version4/class-wc-rest-network-orders-v2-controller.php rename to src/RestApi/Version4/Controllers/NetworkOrders.php index 26213306ceb..ff3481e1b21 100644 --- a/src/RestApi/Version4/class-wc-rest-network-orders-v2-controller.php +++ b/src/RestApi/Version4/Controllers/NetworkOrders.php @@ -5,25 +5,16 @@ * Handles requests to the /orders/network endpoint * * @package WooCommerce/RestApi - * @since 3.4.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** * REST API Network Orders controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Orders_V2_Controller */ -class WC_REST_Network_Orders_V2_Controller extends WC_REST_Orders_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; +class NetworkOrders extends Orders { /** * Register the routes for network orders. From 47bfc21c978868f1ca536f64dd42aa9941d4d648 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 16:10:49 +0100 Subject: [PATCH 045/440] Leaderboards --- .../Leaderboards.php} | 17 +- .../ProductVariations.php} | 342 +++++-- .../SettingsOptions.php} | 70 +- src/RestApi/Version4/changelog.md | 3 + ...min-rest-product-variations-controller.php | 124 --- ...-wc-rest-product-variations-controller.php | 860 ------------------ ...ass-wc-rest-setting-options-controller.php | 250 ----- 7 files changed, 332 insertions(+), 1334 deletions(-) rename src/RestApi/Version4/{class-wc-admin-rest-leaderboards-controller.php => Controllers/Leaderboards.php} (98%) rename src/RestApi/Version4/{class-wc-rest-product-variations-v2-controller.php => Controllers/ProductVariations.php} (77%) rename src/RestApi/Version4/{class-wc-rest-setting-options-v2-controller.php => Controllers/SettingsOptions.php} (92%) delete mode 100644 src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-product-variations-controller.php delete mode 100644 src/RestApi/Version4/class-wc-rest-setting-options-controller.php diff --git a/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php b/src/RestApi/Version4/Controllers/Leaderboards.php similarity index 98% rename from src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php rename to src/RestApi/Version4/Controllers/Leaderboards.php index ee05e836193..6e22b5ddbf5 100644 --- a/src/RestApi/Version4/class-wc-admin-rest-leaderboards-controller.php +++ b/src/RestApi/Version4/Controllers/Leaderboards.php @@ -4,24 +4,17 @@ * * Handles requests to /leaderboards * - * @package WooCommerce Admin/API + * @package WooCommerce/RestApi */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** - * Leaderboards controller. - * - * @package WooCommerce Admin/API - * @extends WC_REST_Data_Controller + * REST API Leaderboards class. */ -class WC_Admin_REST_Leaderboards_Controller extends WC_REST_Data_Controller { - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; +class Leaderboards extends AbstractController { /** * Route base. diff --git a/src/RestApi/Version4/class-wc-rest-product-variations-v2-controller.php b/src/RestApi/Version4/Controllers/ProductVariations.php similarity index 77% rename from src/RestApi/Version4/class-wc-rest-product-variations-v2-controller.php rename to src/RestApi/Version4/Controllers/ProductVariations.php index d1fdb90e72f..5df9f81eb1a 100644 --- a/src/RestApi/Version4/class-wc-rest-product-variations-v2-controller.php +++ b/src/RestApi/Version4/Controllers/ProductVariations.php @@ -5,25 +5,16 @@ * Handles requests to the /products//variations endpoints. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** * REST API variations controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Products_V2_Controller */ -class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; +class ProductVariations extends Products { /** * Route base. @@ -52,7 +43,9 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( 'args' => array( 'product_id' => array( 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), @@ -75,7 +68,9 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ) ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( 'args' => array( 'product_id' => array( 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), @@ -120,7 +115,8 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ) ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', array( + $this->namespace, '/' . $this->rest_base . '/batch', + array( 'args' => array( 'product_id' => array( 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), @@ -173,7 +169,6 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr /** * Prepare a single variation output for response. * - * @since 3.0.0 * @param WC_Data $object Object data. * @param WP_REST_Request $request Request object. * @return WP_REST_Response @@ -181,6 +176,9 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr public function prepare_object_for_response( $object, $request ) { $data = array( 'id' => $object->get_id(), + 'name' => $object->get_name( $context ), + 'type' => $object->get_type(), + 'parent_id' => $object->get_parent_id( $context ), 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), @@ -196,7 +194,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), 'on_sale' => $object->is_on_sale(), - 'visible' => $object->is_visible(), + 'status' => $object->get_status(), 'purchasable' => $object->is_purchasable(), 'virtual' => $object->is_virtual(), 'downloadable' => $object->is_downloadable(), @@ -207,7 +205,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'tax_class' => $object->get_tax_class(), 'manage_stock' => $object->managing_stock(), 'stock_quantity' => $object->get_stock_quantity(), - 'in_stock' => $object->is_in_stock(), + 'stock_status' => $object->get_stock_status(), 'backorders' => $object->get_backorders(), 'backorders_allowed' => $object->backorders_allowed(), 'backordered' => $object->is_on_backorder(), @@ -219,7 +217,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), 'shipping_class' => $object->get_shipping_class(), 'shipping_class_id' => $object->get_shipping_class_id(), - 'image' => current( $this->get_images( $object ) ), + 'image' => $this->get_image( $object ), 'attributes' => $this->get_attributes( $object ), 'menu_order' => $object->get_menu_order(), 'meta_data' => $object->get_meta_data(), @@ -244,6 +242,90 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } + /** + * Get the image for a product variation. + * + * @param WC_Product_Variation $variation Variation data. + * @return array + */ + protected function get_image( $variation ) { + if ( ! $variation->get_image_id() ) { + return; + } + + $attachment_id = $variation->get_image_id(); + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + return; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + return; + } + + if ( ! isset( $image ) ) { + return array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + } + + /** + * Set variation image. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product_Variation $variation Variation instance. + * @param array $image Image data. + * @return WC_Product_Variation + */ + protected function set_variation_image( $variation, $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $variation->get_id(), array( $image ) ) ) { + throw new WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $variation->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: attachment ID */ + throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $variation->set_image_id( $attachment_id ); + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + + return $variation; + } + /** * Prepare objects query. * @@ -254,8 +336,79 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr protected function prepare_objects_query( $request ) { $args = parent::prepare_objects_query( $request ); + // Set post_status. + $args['post_status'] = $request['status']; + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product based on stock_status. + if ( ! empty( $request['stock_status'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_stock_status', + 'value' => $request['stock_status'], + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + $args['post_parent'] = $request['product_id']; + if ( ! empty( $request['search'] ) ) { + $args['search'] = $request['search']; + unset( $args['s'] ); + } + return $args; } @@ -273,14 +426,11 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $variation = new WC_Product_Variation(); } - // Update parent ID just once. - if ( 0 === $variation->get_parent_id() ) { - $variation->set_parent_id( absint( $request['product_id'] ) ); - } + $variation->set_parent_id( absint( $request['product_id'] ) ); // Status. - if ( isset( $request['visible'] ) ) { - $variation->set_status( false === $request['visible'] ? 'private' : 'publish' ); + if ( isset( $request['status'] ) ) { + $variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); } // SKU. @@ -290,13 +440,8 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr // Thumbnail. if ( isset( $request['image'] ) ) { - if ( is_array( $request['image'] ) && ! empty( $request['image'] ) ) { - $image = $request['image']; - if ( is_array( $image ) ) { - $image['position'] = 0; - } - - $variation = $this->set_product_images( $variation, array( $image ) ); + if ( is_array( $request['image'] ) ) { + $variation = $this->set_variation_image( $variation, $request['image'] ); } else { $variation->set_image_id( '' ); } @@ -335,15 +480,11 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr // Stock handling. if ( isset( $request['manage_stock'] ) ) { - if ( 'parent' === $request['manage_stock'] ) { - $variation->set_manage_stock( false ); // This just indicates the variation does not manage stock, but the parent does. - } else { - $variation->set_manage_stock( wc_string_to_bool( $request['manage_stock'] ) ); - } + $variation->set_manage_stock( $request['manage_stock'] ); } - if ( isset( $request['in_stock'] ) ) { - $variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' ); + if ( isset( $request['stock_status'] ) ) { + $variation->set_stock_status( $request['stock_status'] ); } if ( isset( $request['backorders'] ) ) { @@ -401,8 +542,18 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr // Update taxonomies. if ( isset( $request['attributes'] ) ) { - $attributes = array(); - $parent = wc_get_product( $variation->get_parent_id() ); + $attributes = array(); + $parent = wc_get_product( $variation->get_parent_id() ); + + if ( ! $parent ) { + return new WP_Error( + // Translators: %d parent ID. + "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $variation->get_parent_id() ), array( + 'status' => 404, + ) + ); + } + $parent_attributes = $parent->get_attributes(); foreach ( $request['attributes'] as $attribute ) { @@ -411,18 +562,16 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr // Check ID for global attributes or name for product attributes. if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $raw_attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); } elseif ( ! empty( $attribute['name'] ) ) { - $raw_attribute_name = sanitize_title( $attribute['name'] ); + $attribute_name = sanitize_title( $attribute['name'] ); } - if ( ! $attribute_id && ! $raw_attribute_name ) { + if ( ! $attribute_id && ! $attribute_name ) { continue; } - $attribute_name = sanitize_title( $raw_attribute_name ); - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { continue; } @@ -432,7 +581,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $raw_attribute_name ); // @codingStandardsIgnoreLine + $term = get_term_by( 'name', $attribute_value, $attribute_name ); if ( $term && ! is_wp_error( $term ) ) { $attribute_value = $term->slug; @@ -659,6 +808,23 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'context' => array( 'view', 'edit' ), 'readonly' => true, ), + 'name' => array( + 'description' => __( 'Product parent name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'variation', + 'enum' => array( 'variation' ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), 'date_created' => array( 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', @@ -720,7 +886,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), @@ -730,10 +896,11 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'visible' => array( - 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce' ), - 'type' => 'boolean', - 'default' => true, + 'status' => array( + 'description' => __( 'Variation status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_keys( get_post_statuses() ), 'context' => array( 'view', 'edit' ), ), 'purchasable' => array( @@ -805,7 +972,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), 'manage_stock' => array( 'description' => __( 'Stock management at variation level.', 'woocommerce' ), - 'type' => 'mixed', + 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), @@ -814,10 +981,11 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), - 'in_stock' => array( - 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => true, + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), 'context' => array( 'view', 'edit' ), ), 'backorders' => array( @@ -931,11 +1099,6 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'type' => 'string', 'context' => array( 'view', 'edit' ), ), - 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), ), ), 'attributes' => array( @@ -996,7 +1159,58 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), ), ); - return $this->add_additional_fields_schema( $schema ); } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + unset( + $params['in_stock'], + $params['type'], + $params['featured'], + $params['category'], + $params['tag'], + $params['shipping_class'], + $params['attribute'], + $params['attribute_term'] + ); + + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['search'] = array( + 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Get a collection of posts and add the post title filter option to WP_Query. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + add_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10, 2 ); + add_filter( 'posts_join', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_join' ), 10, 2 ); + add_filter( 'posts_groupby', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_group_by' ), 10, 2 ); + $response = parent::get_items( $request ); + remove_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10 ); + remove_filter( 'posts_join', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_join' ), 10 ); + remove_filter( 'posts_groupby', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_group_by' ), 10 ); + return $response; + } } diff --git a/src/RestApi/Version4/class-wc-rest-setting-options-v2-controller.php b/src/RestApi/Version4/Controllers/SettingsOptions.php similarity index 92% rename from src/RestApi/Version4/class-wc-rest-setting-options-v2-controller.php rename to src/RestApi/Version4/Controllers/SettingsOptions.php index 7136459b925..6d3437b5e58 100644 --- a/src/RestApi/Version4/class-wc-rest-setting-options-v2-controller.php +++ b/src/RestApi/Version4/Controllers/SettingsOptions.php @@ -5,25 +5,16 @@ * Handles requests to the /settings/$group/$setting endpoints. * * @package WooCommerce/RestApi - * @since 3.0.0 */ +namespace WooCommerce\RestApi\Version4\Controllers; + defined( 'ABSPATH' ) || exit; /** * REST API Setting Options controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Controller */ -class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { - - /** - * WP REST API namespace/version. - * - * @var string - */ - protected $namespace = 'wc/v2'; +class SettingsOptions extends AbstractController { /** * Route base. @@ -39,7 +30,9 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, array( + $this->namespace, + '/' . $this->rest_base, + array( 'args' => array( 'group' => array( 'description' => __( 'Settings group ID.', 'woocommerce' ), @@ -56,7 +49,9 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', array( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( 'args' => array( 'group' => array( 'description' => __( 'Settings group ID.', 'woocommerce' ), @@ -74,7 +69,9 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]+)', + array( 'args' => array( 'group' => array( 'description' => __( 'Settings group ID.', 'woocommerce' ), @@ -150,7 +147,6 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { /** * Get all settings in a group. * - * @since 3.0.0 * @param string $group_id Group ID. * @return array|WP_Error */ @@ -159,7 +155,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } - $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores if ( empty( $settings ) ) { return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); @@ -185,6 +181,20 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { } elseif ( 'single_select_country' === $setting['type'] ) { $setting['type'] = 'select'; $setting['options'] = $this->get_countries_and_states(); + } elseif ( 'single_select_page' === $setting['type'] ) { + $pages = get_pages( + array( + 'sort_column' => 'menu_order', + 'sort_order' => 'ASC', + 'hierarchical' => 0, + ) + ); + $options = array(); + foreach ( $pages as $page ) { + $options[ $page->ID ] = ! empty( $page->post_title ) ? $page->post_title : '#' . $page->ID; + } + $setting['type'] = 'select'; + $setting['options'] = $options; } $filtered_settings[] = $setting; @@ -204,11 +214,10 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { if ( ! $countries ) { return array(); } - $output = array(); - foreach ( $countries as $key => $value ) { $states = WC()->countries->get_states( $key ); + if ( $states ) { foreach ( $states as $state_key => $state_value ) { $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; @@ -217,7 +226,6 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $output[ $key ] = $value; } } - return $output; } @@ -252,6 +260,12 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } + if ( is_wp_error( $setting ) ) { + return $setting; + } + + $setting['group_id'] = $group_id; + return $setting; } @@ -442,7 +456,6 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { /** * Callback for allowed keys for each setting response. * - * @since 3.0.0 * @param string $key Key to check. * @return boolean */ @@ -450,6 +463,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { return in_array( $key, array( 'id', + 'group_id', 'label', 'description', 'default', @@ -459,7 +473,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'options', 'value', 'option_key', - ) + ), true ); } @@ -492,7 +506,6 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { /** * Get the settings schema, conforming to JSON Schema. * - * @since 3.0.0 * @return array */ public function get_item_schema() { @@ -510,6 +523,15 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'context' => array( 'view', 'edit' ), 'readonly' => true, ), + 'group_id' => array( + 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), 'label' => array( 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', @@ -564,7 +586,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'sanitize_callback' => 'sanitize_text_field', ), 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox', 'thumbnail_cropping' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'options' => array( diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md index 4db377e409b..070667c9c7c 100644 --- a/src/RestApi/Version4/changelog.md +++ b/src/RestApi/Version4/changelog.md @@ -7,6 +7,8 @@ - Orders - Added order number to schema. - Product Reviews - Updated response links. - Products - Added `low_in_stock` and `search` parameter. +- Product Variations - Added `search` parameter. +- Product Variations - Added `name`, `type`, `parent_id` to schema. - Reports - Updated with updated list of available reports. - Taxes - Added `code` and `include` params. @@ -32,6 +34,7 @@ - `reports/downloads/stats` - `reports/import` - `data/download-ips` +- `leaderboards` ## Removed endpoints diff --git a/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php b/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php deleted file mode 100644 index 1e96ce78c99..00000000000 --- a/src/RestApi/Version4/class-wc-admin-rest-product-variations-controller.php +++ /dev/null @@ -1,124 +0,0 @@ - __( 'Search by similar product name or sku.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } - - /** - * Add product name and sku filtering to the WC API. - * - * @param WP_REST_Request $request Request data. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - if ( ! empty( $request['search'] ) ) { - $args['search'] = $request['search']; - unset( $args['s'] ); - } - - return $args; - } - - /** - * Get a collection of posts and add the post title filter option to WP_Query. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - add_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10, 2 ); - add_filter( 'posts_join', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_join' ), 10, 2 ); - add_filter( 'posts_groupby', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_group_by' ), 10, 2 ); - $response = parent::get_items( $request ); - remove_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10 ); - remove_filter( 'posts_join', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_join' ), 10 ); - remove_filter( 'posts_groupby', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_group_by' ), 10 ); - return $response; - } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = parent::get_item_schema(); - - $schema['properties']['name'] = array( - 'description' => __( 'Product parent name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ); - $schema['properties']['type'] = array( - 'description' => __( 'Product type.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'variation', - 'enum' => array( 'variation' ), - 'context' => array( 'view', 'edit' ), - ); - $schema['properties']['parent_id'] = array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ); - - return $schema; - } - - /** - * Prepare a single variation output for response. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $response = parent::prepare_object_for_response( $object, $request ); - $data = $response->get_data(); - - $data['name'] = $object->get_name( $context ); - $data['type'] = $object->get_type(); - $data['parent_id'] = $object->get_parent_id( $context ); - - $response->set_data( $data ); - - return $response; - } -} diff --git a/src/RestApi/Version4/class-wc-rest-product-variations-controller.php b/src/RestApi/Version4/class-wc-rest-product-variations-controller.php deleted file mode 100644 index 5b69656b0ab..00000000000 --- a/src/RestApi/Version4/class-wc-rest-product-variations-controller.php +++ /dev/null @@ -1,860 +0,0 @@ -/variations endpoints. - * - * @package WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API variations controller class. - * - * @package WooCommerce/RestApi - * @extends WC_REST_Product_Variations_V2_Controller - */ -class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; - - /** - * Prepare a single variation output for response. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $data = array( - 'id' => $object->get_id(), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), - 'description' => wc_format_content( $object->get_description() ), - 'permalink' => $object->get_permalink(), - 'sku' => $object->get_sku(), - 'price' => $object->get_price(), - 'regular_price' => $object->get_regular_price(), - 'sale_price' => $object->get_sale_price(), - 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), - 'on_sale' => $object->is_on_sale(), - 'status' => $object->get_status(), - 'purchasable' => $object->is_purchasable(), - 'virtual' => $object->is_virtual(), - 'downloadable' => $object->is_downloadable(), - 'downloads' => $this->get_downloads( $object ), - 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, - 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, - 'tax_status' => $object->get_tax_status(), - 'tax_class' => $object->get_tax_class(), - 'manage_stock' => $object->managing_stock(), - 'stock_quantity' => $object->get_stock_quantity(), - 'stock_status' => $object->get_stock_status(), - 'backorders' => $object->get_backorders(), - 'backorders_allowed' => $object->backorders_allowed(), - 'backordered' => $object->is_on_backorder(), - 'weight' => $object->get_weight(), - 'dimensions' => array( - 'length' => $object->get_length(), - 'width' => $object->get_width(), - 'height' => $object->get_height(), - ), - 'shipping_class' => $object->get_shipping_class(), - 'shipping_class_id' => $object->get_shipping_class_id(), - 'image' => $this->get_image( $object ), - 'attributes' => $this->get_attributes( $object ), - 'menu_order' => $object->get_menu_order(), - 'meta_data' => $object->get_meta_data(), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - - /** - * Prepare a single variation for create or update. - * - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - if ( isset( $request['id'] ) ) { - $variation = wc_get_product( absint( $request['id'] ) ); - } else { - $variation = new WC_Product_Variation(); - } - - $variation->set_parent_id( absint( $request['product_id'] ) ); - - // Status. - if ( isset( $request['status'] ) ) { - $variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); - } - - // SKU. - if ( isset( $request['sku'] ) ) { - $variation->set_sku( wc_clean( $request['sku'] ) ); - } - - // Thumbnail. - if ( isset( $request['image'] ) ) { - if ( is_array( $request['image'] ) ) { - $variation = $this->set_variation_image( $variation, $request['image'] ); - } else { - $variation->set_image_id( '' ); - } - } - - // Virtual variation. - if ( isset( $request['virtual'] ) ) { - $variation->set_virtual( $request['virtual'] ); - } - - // Downloadable variation. - if ( isset( $request['downloadable'] ) ) { - $variation->set_downloadable( $request['downloadable'] ); - } - - // Downloads. - if ( $variation->get_downloadable() ) { - // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); - } - - // Download limit. - if ( isset( $request['download_limit'] ) ) { - $variation->set_download_limit( $request['download_limit'] ); - } - - // Download expiry. - if ( isset( $request['download_expiry'] ) ) { - $variation->set_download_expiry( $request['download_expiry'] ); - } - } - - // Shipping data. - $variation = $this->save_product_shipping_data( $variation, $request ); - - // Stock handling. - if ( isset( $request['manage_stock'] ) ) { - $variation->set_manage_stock( $request['manage_stock'] ); - } - - if ( isset( $request['stock_status'] ) ) { - $variation->set_stock_status( $request['stock_status'] ); - } - - if ( isset( $request['backorders'] ) ) { - $variation->set_backorders( $request['backorders'] ); - } - - if ( $variation->get_manage_stock() ) { - if ( isset( $request['stock_quantity'] ) ) { - $variation->set_stock_quantity( $request['stock_quantity'] ); - } elseif ( isset( $request['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); - $variation->set_stock_quantity( $stock_quantity ); - } - } else { - $variation->set_backorders( 'no' ); - $variation->set_stock_quantity( '' ); - } - - // Regular Price. - if ( isset( $request['regular_price'] ) ) { - $variation->set_regular_price( $request['regular_price'] ); - } - - // Sale Price. - if ( isset( $request['sale_price'] ) ) { - $variation->set_sale_price( $request['sale_price'] ); - } - - if ( isset( $request['date_on_sale_from'] ) ) { - $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); - } - - if ( isset( $request['date_on_sale_from_gmt'] ) ) { - $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); - } - - if ( isset( $request['date_on_sale_to'] ) ) { - $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); - } - - if ( isset( $request['date_on_sale_to_gmt'] ) ) { - $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); - } - - // Tax class. - if ( isset( $request['tax_class'] ) ) { - $variation->set_tax_class( $request['tax_class'] ); - } - - // Description. - if ( isset( $request['description'] ) ) { - $variation->set_description( wp_kses_post( $request['description'] ) ); - } - - // Update taxonomies. - if ( isset( $request['attributes'] ) ) { - $attributes = array(); - $parent = wc_get_product( $variation->get_parent_id() ); - - if ( ! $parent ) { - return new WP_Error( - // Translators: %d parent ID. - "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $variation->get_parent_id() ), array( - 'status' => 404, - ) - ); - } - - $parent_attributes = $parent->get_attributes(); - - foreach ( $request['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { - continue; - } - - $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); - $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $attribute_value = $term->slug; - } else { - $attribute_value = sanitize_title( $attribute_value ); - } - } - - $attributes[ $attribute_key ] = $attribute_value; - } - - $variation->set_attributes( $attributes ); - } - - // Menu order. - if ( $request['menu_order'] ) { - $variation->set_menu_order( $request['menu_order'] ); - } - - // Meta data. - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $variation Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); - } - - /** - * Get the image for a product variation. - * - * @param WC_Product_Variation $variation Variation data. - * @return array - */ - protected function get_image( $variation ) { - if ( ! $variation->get_image_id() ) { - return; - } - - $attachment_id = $variation->get_image_id(); - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - return; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - return; - } - - if ( ! isset( $image ) ) { - return array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - } - - /** - * Set variation image. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product_Variation $variation Variation instance. - * @param array $image Image data. - * @return WC_Product_Variation - */ - protected function set_variation_image( $variation, $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $variation->get_id(), array( $image ) ) ) { - throw new WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $variation->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: attachment ID */ - throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); - } - - $variation->set_image_id( $attachment_id ); - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); - } - - return $variation; - } - - /** - * Get the Variation's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Variation status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_keys( get_post_statuses() ), - 'context' => array( 'view', 'edit' ), - ), - 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); - - // Set post_status. - $args['post_status'] = $request['status']; - - // Filter by sku. - if ( ! empty( $request['sku'] ) ) { - $skus = explode( ',', $request['sku'] ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $request['sku']; - } - - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', - ) - ); - } - - // Filter by tax class. - if ( ! empty( $request['tax_class'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_tax_class', - 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', - ) - ); - } - - // Price filter. - if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { - $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. - } - - // Filter product based on stock_status. - if ( ! empty( $request['stock_status'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_stock_status', - 'value' => $request['stock_status'], - ) - ); - } - - // Filter by on sale products. - if ( is_bool( $request['on_sale'] ) ) { - $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; - $on_sale_ids = wc_get_product_ids_on_sale(); - - // Use 0 when there's no on sale products to avoid return all products. - $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; - - $args[ $on_sale_key ] += $on_sale_ids; - } - - // Force the post_type argument, since it's not a user input variable. - if ( ! empty( $request['sku'] ) ) { - $args['post_type'] = array( 'product', 'product_variation' ); - } else { - $args['post_type'] = $this->post_type; - } - - $args['post_parent'] = $request['product_id']; - - return $args; - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - unset( - $params['in_stock'], - $params['type'], - $params['featured'], - $params['category'], - $params['tag'], - $params['shipping_class'], - $params['attribute'], - $params['attribute_term'] - ); - - $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/RestApi/Version4/class-wc-rest-setting-options-controller.php b/src/RestApi/Version4/class-wc-rest-setting-options-controller.php deleted file mode 100644 index 41ae7ae86f7..00000000000 --- a/src/RestApi/Version4/class-wc-rest-setting-options-controller.php +++ /dev/null @@ -1,250 +0,0 @@ - 404 ) ); - } - - $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores - - if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $filtered_settings = array(); - foreach ( $settings as $setting ) { - $option_key = $setting['option_key']; - $setting = $this->filter_setting( $setting ); - $default = isset( $setting['default'] ) ? $setting['default'] : ''; - // Get the option value. - if ( is_array( $option_key ) ) { - $option = get_option( $option_key[0] ); - $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; - } else { - $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); - $setting['value'] = $admin_setting_value; - } - - if ( 'multi_select_countries' === $setting['type'] ) { - $setting['options'] = WC()->countries->get_countries(); - $setting['type'] = 'multiselect'; - } elseif ( 'single_select_country' === $setting['type'] ) { - $setting['type'] = 'select'; - $setting['options'] = $this->get_countries_and_states(); - } elseif ( 'single_select_page' === $setting['type'] ) { - $pages = get_pages( - array( - 'sort_column' => 'menu_order', - 'sort_order' => 'ASC', - 'hierarchical' => 0, - ) - ); - $options = array(); - foreach ( $pages as $page ) { - $options[ $page->ID ] = ! empty( $page->post_title ) ? $page->post_title : '#' . $page->ID; - } - $setting['type'] = 'select'; - $setting['options'] = $options; - } - - $filtered_settings[] = $setting; - } - - return $filtered_settings; - } - - /** - * Returns a list of countries and states for use in the base location setting. - * - * @since 3.0.7 - * @return array Array of states and countries. - */ - private function get_countries_and_states() { - $countries = WC()->countries->get_countries(); - if ( ! $countries ) { - return array(); - } - $output = array(); - foreach ( $countries as $key => $value ) { - $states = WC()->countries->get_states( $key ); - - if ( $states ) { - foreach ( $states as $state_key => $state_value ) { - $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; - } - } else { - $output[ $key ] = $value; - } - } - return $output; - } - - /** - * Get the settings schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'setting', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'group_id' => array( - 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} From d630418f26175ad179cb05e08c826bca06f5e40a Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 17:23:10 +0100 Subject: [PATCH 046/440] Fix class calls due to namespaces --- src/RestApi.php | 18 +-- .../Controllers/AbstractController.php | 24 ++-- .../Controllers/AbstractObjectsController.php | 76 +++++------ .../Controllers/AbstractPostsController.php | 72 +++++----- .../AbstractShippingZonesController.php | 32 ++--- .../Controllers/AbstractTermsContoller.php | 78 ++++++----- src/RestApi/Version4/Controllers/Coupons.php | 54 ++++---- .../Controllers/CustomerDownloads.php | 8 +- .../Version4/Controllers/Customers.php | 96 ++++++------- src/RestApi/Version4/Controllers/Data.php | 12 +- .../Version4/Controllers/Data/Continents.php | 10 +- .../Version4/Controllers/Data/Countries.php | 10 +- .../Version4/Controllers/Data/Currencies.php | 14 +- .../Version4/Controllers/Data/DownloadIPs.php | 6 +- .../Version4/Controllers/Leaderboards.php | 20 +-- .../Version4/Controllers/NetworkOrders.php | 2 +- .../Controllers/Onboarding/Levels.php | 4 +- .../Controllers/Onboarding/Plugins.php | 24 ++-- .../Controllers/Onboarding/Profile.php | 20 +-- .../Version4/Controllers/OrderNotes.php | 54 ++++---- .../Version4/Controllers/OrderRefunds.php | 50 +++---- src/RestApi/Version4/Controllers/Orders.php | 56 ++++---- .../Version4/Controllers/PaymentGateways.php | 32 ++--- .../Controllers/ProductAttributeTerms.php | 20 +-- .../Controllers/ProductAttributes.php | 76 +++++------ .../Controllers/ProductCategories.php | 2 +- .../Version4/Controllers/ProductReviews.php | 98 ++++++------- .../Controllers/ProductVariations.php | 52 +++---- src/RestApi/Version4/Controllers/Products.php | 105 +++++++++----- src/RestApi/Version4/Controllers/Reports.php | 129 +++++++++--------- .../Controllers/Reports/Categories.php | 6 +- .../Controllers/Reports/CouponStats.php | 6 +- .../Version4/Controllers/Reports/Coupons.php | 4 +- .../Controllers/Reports/CustomerStats.php | 8 +- .../Controllers/Reports/Customers.php | 8 +- .../Controllers/Reports/DownloadStats.php | 4 +- .../Controllers/Reports/Downloads.php | 6 +- .../Version4/Controllers/Reports/Import.php | 34 ++--- .../Controllers/Reports/OrderStats.php | 6 +- .../Version4/Controllers/Reports/Orders.php | 4 +- .../Reports/PerformanceIndicators.php | 14 +- .../Controllers/Reports/ProductStats.php | 10 +- .../Version4/Controllers/Reports/Products.php | 4 +- .../Controllers/Reports/RevenueStats.php | 6 +- .../Version4/Controllers/Reports/Stock.php | 6 +- .../Controllers/Reports/StockStats.php | 4 +- .../Version4/Controllers/Reports/TaxStats.php | 8 +- .../Version4/Controllers/Reports/Taxes.php | 4 +- .../Controllers/Reports/Variations.php | 4 +- src/RestApi/Version4/Controllers/Settings.php | 20 +-- .../Version4/Controllers/SettingsOptions.php | 46 +++---- .../Version4/Controllers/ShippingMethods.php | 22 +-- .../Controllers/ShippingZoneLocations.php | 12 +- .../Controllers/ShippingZoneMethods.php | 36 ++--- .../Version4/Controllers/ShippingZones.php | 34 ++--- .../Version4/Controllers/SystemStatus.php | 20 +-- .../Controllers/SystemStatusTools.php | 42 +++--- .../Version4/Controllers/TaxClasses.php | 36 ++--- src/RestApi/Version4/Controllers/Taxes.php | 86 ++++++------ src/RestApi/Version4/Controllers/Webhooks.php | 84 ++++++------ src/RestApi/Version4/Main.php | 93 +++++++++++++ vendor/composer/autoload_classmap.php | 62 +++++++++ vendor/composer/autoload_static.php | 62 +++++++++ version.php | 2 +- 64 files changed, 1158 insertions(+), 899 deletions(-) create mode 100644 src/RestApi/Version4/Main.php diff --git a/src/RestApi.php b/src/RestApi.php index ec73a0d2bdf..1ef51a91e66 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -39,12 +39,12 @@ class RestApi { * Register REST API routes. */ public function register_rest_routes() { - foreach ( $this->get_rest_namespaces() as $namespace ) { - $this->endpoints[ $namespace ] = []; + foreach ( $this->get_rest_namespaces() as $namespace => $namespace_class ) { + $controllers = $namespace_class::instance()->get_controllers(); - foreach ( $this->get_rest_controllers( $namespace ) as $name => $class ) { - $this->endpoints[ $namespace ][ $class ] = new $class(); - $this->endpoints[ $namespace ][ $class ]->register_routes(); + foreach ( $controllers as $controller_name => $controller_class ) { + $this->endpoints[ $namespace ][ $controller_name ] = new $controller_class(); + $this->endpoints[ $namespace ][ $controller_name ]->register_routes(); } } } @@ -56,10 +56,10 @@ class RestApi { */ protected function get_rest_namespaces() { return [ - 'wc/v1', - 'wc/v2', - 'wc/v3', - 'wc-blocks/v1', + //'wc/v1', + //'wc/v2', + 'wc/v3' => '\WooCommerce\RestApi\Version4\Main', + //'wc-blocks/v1', ]; } diff --git a/src/RestApi/Version4/Controllers/AbstractController.php b/src/RestApi/Version4/Controllers/AbstractController.php index 883f6d96b3e..ac37601b3b8 100644 --- a/src/RestApi/Version4/Controllers/AbstractController.php +++ b/src/RestApi/Version4/Controllers/AbstractController.php @@ -89,7 +89,7 @@ abstract class AbstractController extends WP_REST_Controller { * Check batch limit. * * @param array $items Request items. - * @return bool|WP_Error + * @return bool|\WP_Error */ protected function check_batch_limit( $items ) { $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); @@ -109,7 +109,7 @@ abstract class AbstractController extends WP_REST_Controller { if ( $total > $limit ) { /* translators: %s: items limit */ - return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); + return new \WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); } return true; @@ -119,7 +119,7 @@ abstract class AbstractController extends WP_REST_Controller { * Bulk create, update and delete items. * * @param WP_REST_Request $request Full details about the request. - * @return array Of WP_Error or WP_REST_Response. + * @return array Of \WP_Error or WP_REST_Response. */ public function batch_items( $request ) { /** @@ -247,13 +247,13 @@ abstract class AbstractController extends WP_REST_Controller { * @since 3.0.0 * @param string $value Value. * @param array $setting Setting. - * @return string|WP_Error + * @return string|\WP_Error */ public function validate_setting_select_field( $value, $setting ) { if ( array_key_exists( $value, $setting['options'] ) ) { return $value; } else { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -263,7 +263,7 @@ abstract class AbstractController extends WP_REST_Controller { * @since 3.0.0 * @param array $values Values. * @param array $setting Setting. - * @return array|WP_Error + * @return array|\WP_Error */ public function validate_setting_multiselect_field( $values, $setting ) { if ( empty( $values ) ) { @@ -271,7 +271,7 @@ abstract class AbstractController extends WP_REST_Controller { } if ( ! is_array( $values ) ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } $final_values = array(); @@ -290,11 +290,11 @@ abstract class AbstractController extends WP_REST_Controller { * @since 3.0.0 * @param array $values Values. * @param array $setting Setting. - * @return string|WP_Error + * @return string|\WP_Error */ public function validate_setting_image_width_field( $values, $setting ) { if ( ! is_array( $values ) ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } $current = $setting['value']; @@ -316,7 +316,7 @@ abstract class AbstractController extends WP_REST_Controller { * @since 3.0.0 * @param string $value Value. * @param array $setting Setting. - * @return string|WP_Error + * @return string|\WP_Error */ public function validate_setting_radio_field( $value, $setting ) { return $this->validate_setting_select_field( $value, $setting ); @@ -328,7 +328,7 @@ abstract class AbstractController extends WP_REST_Controller { * @since 3.0.0 * @param string $value Value. * @param array $setting Setting. - * @return string|WP_Error + * @return string|\WP_Error */ public function validate_setting_checkbox_field( $value, $setting ) { if ( in_array( $value, array( 'yes', 'no' ) ) ) { @@ -337,7 +337,7 @@ abstract class AbstractController extends WP_REST_Controller { $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; return $value; } else { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } } diff --git a/src/RestApi/Version4/Controllers/AbstractObjectsController.php b/src/RestApi/Version4/Controllers/AbstractObjectsController.php index 6373502db3b..62f0120de36 100644 --- a/src/RestApi/Version4/Controllers/AbstractObjectsController.php +++ b/src/RestApi/Version4/Controllers/AbstractObjectsController.php @@ -5,12 +5,10 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4; +namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use AbstractPostsController; - /** * CRUD Object Controller. */ @@ -27,24 +25,24 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Get object. * * @param int $id Object ID. - * @return object WC_Data object or WP_Error object. + * @return object WC_Data object or \WP_Error object. */ protected function get_object( $id ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Check if a given request has access to read an item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -54,13 +52,13 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Check if a given request has access to update an item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -70,13 +68,13 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Check if a given request has access to delete an item. * * @param WP_REST_Request $request Full details about the request. - * @return bool|WP_Error + * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -98,11 +96,11 @@ abstract class AbstractObjectsController extends AbstractPostsController { * @since 3.0.0 * @param WC_Data $object Object data. * @param WP_REST_Request $request Request object. - * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. + * @return \WP_Error|WP_REST_Response Response object on success, or \WP_Error object on failure. */ protected function prepare_object_for_response( $object, $request ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); } /** @@ -111,24 +109,24 @@ abstract class AbstractObjectsController extends AbstractPostsController { * @since 3.0.0 * @param WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + * @return \WP_Error|WC_Data The prepared item, or \WP_Error object on failure. */ protected function prepare_object_for_database( $request, $creating = false ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Get a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_object_for_response( $object, $request ); @@ -147,7 +145,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * @since 3.0.0 * @param WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. - * @return WC_Data|WP_Error + * @return WC_Data|\WP_Error */ protected function save_object( $request, $creating = false ) { try { @@ -161,9 +159,9 @@ abstract class AbstractObjectsController extends AbstractPostsController { return $this->get_object( $object->get_id() ); } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } @@ -171,12 +169,12 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Create a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $object = $this->save_object( $request, true ); @@ -189,10 +187,10 @@ abstract class AbstractObjectsController extends AbstractPostsController { $this->update_additional_fields_for_object( $object, $request ); } catch ( WC_Data_Exception $e ) { $object->delete(); - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); } catch ( WC_REST_Exception $e ) { $object->delete(); - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } /** @@ -217,13 +215,13 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Update a single post. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 400 ) ); } $object = $this->save_object( $request, false ); @@ -235,9 +233,9 @@ abstract class AbstractObjectsController extends AbstractPostsController { try { $this->update_additional_fields_for_object( $object, $request ); } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } /** @@ -315,14 +313,14 @@ abstract class AbstractObjectsController extends AbstractPostsController { * @return array */ protected function get_objects( $query_args ) { - $query = new WP_Query(); + $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 = new \WP_Query(); $count_query->query( $query_args ); $total_posts = $count_query->found_posts; } @@ -338,7 +336,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Get a collection of posts. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $query_args = $this->prepare_objects_query( $request ); @@ -398,7 +396,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Delete a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $force = (bool) $request['force']; @@ -406,7 +404,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { $result = false; if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); @@ -423,7 +421,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -437,14 +435,14 @@ abstract class AbstractObjectsController extends AbstractPostsController { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( is_callable( array( $object, 'get_status' ) ) ) { if ( 'trash' === $object->get_status() ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + return new \WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); } $object->delete(); @@ -454,7 +452,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -607,8 +605,8 @@ abstract class AbstractObjectsController extends AbstractPostsController { * type slug for the controller. * * This filter registers the collection parameter, but does not map the - * collection parameter to an internal WP_Query parameter. Use the - * `rest_{$this->post_type}_query` filter to set WP_Query parameters. + * collection parameter to an internal \WP_Query parameter. Use the + * `rest_{$this->post_type}_query` filter to set \WP_Query parameters. * * @param array $query_params JSON Schema-formatted collection parameters. * @param WP_Post_Type $post_type Post type object. diff --git a/src/RestApi/Version4/Controllers/AbstractPostsController.php b/src/RestApi/Version4/Controllers/AbstractPostsController.php index 931aa9a82a1..71249fa684b 100644 --- a/src/RestApi/Version4/Controllers/AbstractPostsController.php +++ b/src/RestApi/Version4/Controllers/AbstractPostsController.php @@ -5,12 +5,10 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4; +namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use AbstractController; - /** * POSTS Controller. * @@ -43,11 +41,11 @@ abstract class AbstractPostsController extends AbstractController { * Check if a given request has access to read items. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -57,11 +55,11 @@ abstract class AbstractPostsController extends AbstractController { * Check if a given request has access to create an item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -71,13 +69,13 @@ abstract class AbstractPostsController extends AbstractController { * Check if a given request has access to read an item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -87,13 +85,13 @@ abstract class AbstractPostsController extends AbstractController { * Check if a given request has access to update an item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -103,13 +101,13 @@ abstract class AbstractPostsController extends AbstractController { * Check if a given request has access to delete an item. * * @param WP_REST_Request $request Full details about the request. - * @return bool|WP_Error + * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -120,11 +118,11 @@ abstract class AbstractPostsController extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return boolean|WP_Error + * @return boolean|\WP_Error */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -134,16 +132,16 @@ abstract class AbstractPostsController extends AbstractController { * Get a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; $post = get_post( $id ); if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $post, $request ); @@ -160,12 +158,12 @@ abstract class AbstractPostsController extends AbstractController { * Create a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -222,7 +220,7 @@ abstract class AbstractPostsController extends AbstractController { * * @param WP_Post $post Post Object. * @param WP_REST_Request $request WP_REST_Request Object. - * @return bool|WP_Error + * @return bool|\WP_Error */ protected function add_post_meta_fields( $post, $request ) { return true; @@ -241,16 +239,16 @@ abstract class AbstractPostsController extends AbstractController { * Update a single post. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { $id = (int) $request['id']; $post = get_post( $id ); if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -295,7 +293,7 @@ abstract class AbstractPostsController extends AbstractController { * Get a collection of posts. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $args = array(); @@ -344,7 +342,7 @@ abstract class AbstractPostsController extends AbstractController { $args = apply_filters( "woocommerce_rest_{$this->post_type}_query", $args, $request ); $query_args = $this->prepare_items_query( $args, $request ); - $posts_query = new WP_Query(); + $posts_query = new \WP_Query(); $query_result = $posts_query->query( $query_args ); $posts = array(); @@ -363,7 +361,7 @@ abstract class AbstractPostsController extends AbstractController { 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 = new \WP_Query(); $count_query->query( $query_args ); $total_posts = $count_query->found_posts; } @@ -403,7 +401,7 @@ abstract class AbstractPostsController extends AbstractController { * Delete a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -411,7 +409,7 @@ abstract class AbstractPostsController extends AbstractController { $post = get_post( $id ); if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0; @@ -428,7 +426,7 @@ abstract class AbstractPostsController extends AbstractController { if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -441,13 +439,13 @@ abstract class AbstractPostsController extends AbstractController { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( 'trash' === $post->post_status ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + return new \WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); } // (Note that internally this falls through to `wp_delete_post` if @@ -457,7 +455,7 @@ abstract class AbstractPostsController extends AbstractController { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -494,7 +492,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Determine the allowed query_vars for a get_items() response and - * prepare for WP_Query. + * prepare for \WP_Query. * * @param array $prepared_args Prepared arguments. * @param WP_REST_Request $request Request object. @@ -543,7 +541,7 @@ abstract class AbstractPostsController extends AbstractController { * * Allows adjusting of the default query vars that are made public. * - * @param array Array of allowed WP_Query query vars. + * @param array Array of allowed \WP_Query query vars. */ $valid_vars = apply_filters( 'query_vars', $wp->public_query_vars ); @@ -593,7 +591,7 @@ abstract class AbstractPostsController extends AbstractController { * vars for editors only. * * @param array { - * Array of allowed WP_Query query vars. + * Array of allowed \WP_Query query vars. * * @param string $allowed_query_var The query var to allow. * } @@ -708,7 +706,7 @@ abstract class AbstractPostsController extends AbstractController { * * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. - * @return bool|WP_Error + * @return bool|\WP_Error */ protected function update_post_meta_fields( $post, $request ) { return true; diff --git a/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php b/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php index f99a3cc547c..df9ad4684c4 100644 --- a/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php +++ b/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php @@ -12,8 +12,6 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use AbstractController; - /** * REST API Shipping Zones base class. * @@ -33,13 +31,13 @@ abstract class AbstractShippingZonesController extends AbstractController { * Retrieve a Shipping Zone by it's ID. * * @param int $zone_id Shipping Zone ID. - * @return WC_Shipping_Zone|WP_Error + * @return WC_Shipping_Zone|\WP_Error */ protected function get_zone( $zone_id ) { - $zone = WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id ); + $zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id ); if ( false === $zone ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } return $zone; @@ -49,15 +47,15 @@ abstract class AbstractShippingZonesController extends AbstractController { * Check whether a given request has permission to read Shipping Zones. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -67,15 +65,15 @@ abstract class AbstractShippingZonesController extends AbstractController { * Check if a given request has access to create Shipping Zones. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -85,15 +83,15 @@ abstract class AbstractShippingZonesController extends AbstractController { * Check whether a given request has permission to edit Shipping Zones. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -103,15 +101,15 @@ abstract class AbstractShippingZonesController extends AbstractController { * Check whether a given request has permission to delete Shipping Zones. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function delete_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; diff --git a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php index 7363fa98781..858cd68ef3f 100644 --- a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php +++ b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php @@ -9,8 +9,6 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; -use AbstractController; - /** * Terms controller class. */ @@ -39,17 +37,17 @@ abstract class AbstractTermsContoller extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'name' => array( 'type' => 'string', @@ -74,7 +72,7 @@ abstract class AbstractTermsContoller extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -82,13 +80,13 @@ abstract class AbstractTermsContoller extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -108,10 +106,10 @@ abstract class AbstractTermsContoller extends AbstractController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -122,7 +120,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Check if a given request has access to read the terms. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { $permissions = $this->check_permissions( $request, 'read' ); @@ -131,7 +129,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -141,7 +139,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Check if a given request has access to create a term. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { $permissions = $this->check_permissions( $request, 'create' ); @@ -150,7 +148,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -160,7 +158,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Check if a given request has access to read a term. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { $permissions = $this->check_permissions( $request, 'read' ); @@ -169,7 +167,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -179,7 +177,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Check if a given request has access to update a term. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { $permissions = $this->check_permissions( $request, 'edit' ); @@ -188,7 +186,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -198,7 +196,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Check if a given request has access to delete a term. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function delete_item_permissions_check( $request ) { $permissions = $this->check_permissions( $request, 'delete' ); @@ -207,7 +205,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -217,7 +215,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Check if a given request has access batch create, update and delete items. * * @param WP_REST_Request $request Full details about the request. - * @return boolean|WP_Error + * @return boolean|\WP_Error */ public function batch_items_permissions_check( $request ) { $permissions = $this->check_permissions( $request, 'batch' ); @@ -226,7 +224,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -237,13 +235,13 @@ abstract class AbstractTermsContoller extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * @param string $context Request context. - * @return bool|WP_Error + * @return bool|\WP_Error */ protected function check_permissions( $request, $context = 'read' ) { // Get taxonomy. $taxonomy = $this->get_taxonomy( $request ); if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } // Check permissions for a single term. @@ -252,7 +250,7 @@ abstract class AbstractTermsContoller extends AbstractController { $term = get_term( $id, $taxonomy ); if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { - return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id ); @@ -265,7 +263,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Get terms associated with a taxonomy. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function get_items( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -375,7 +373,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Create a single term for a taxonomy. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function create_item( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -391,7 +389,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); } $args['parent'] = $request['parent']; } @@ -407,7 +405,7 @@ abstract class AbstractTermsContoller extends AbstractController { $error_data['resource_id'] = $term_id; } - return new WP_Error( $term->get_error_code(), $term->get_error_message(), $error_data ); + return new \WP_Error( $term->get_error_code(), $term->get_error_message(), $error_data ); } $term = get_term( $term['term_id'], $taxonomy ); @@ -450,7 +448,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Get a single term from a taxonomy. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function get_item( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -469,7 +467,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Update a single term from a taxonomy. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function update_item( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -488,7 +486,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); } $prepared_args['parent'] = $request['parent']; } @@ -529,7 +527,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Delete a single term from a taxonomy. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -537,7 +535,7 @@ abstract class AbstractTermsContoller extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $term = get_term( (int) $request['id'], $taxonomy ); @@ -546,7 +544,7 @@ abstract class AbstractTermsContoller extends AbstractController { // Prevent deleting the default product category. if ( $default_category_id === (int) $request['id'] ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } $request->set_param( 'context', 'edit' ); @@ -554,7 +552,7 @@ abstract class AbstractTermsContoller extends AbstractController { $retval = wp_delete_term( $term->term_id, $term->taxonomy ); if ( ! $retval ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -609,7 +607,7 @@ abstract class AbstractTermsContoller extends AbstractController { * * @param WP_Term $term Term object. * @param WP_REST_Request $request Full details about the request. - * @return bool|WP_Error + * @return bool|\WP_Error */ protected function update_term_meta_fields( $term, $request ) { return true; @@ -695,7 +693,7 @@ abstract class AbstractTermsContoller extends AbstractController { if ( '' !== $this->taxonomy && taxonomy_exists( $this->taxonomy ) ) { $taxonomy = get_taxonomy( $this->taxonomy ); } else { - $taxonomy = new stdClass(); + $taxonomy = new \stdClass(); $taxonomy->hierarchical = true; } @@ -787,7 +785,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Get taxonomy. * * @param WP_REST_Request $request Full details about the request. - * @return int|WP_Error + * @return int|\WP_Error */ protected function get_taxonomy( $request ) { // Check if taxonomy is defined. diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/RestApi/Version4/Controllers/Coupons.php index a1ef7cfb71c..f7b1d71c429 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -46,17 +46,17 @@ class Coupons extends AbstractPostsController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'code' => array( 'description' => __( 'Coupon code.', 'woocommerce' ), @@ -81,7 +81,7 @@ class Coupons extends AbstractPostsController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -89,13 +89,13 @@ class Coupons extends AbstractPostsController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -115,10 +115,10 @@ class Coupons extends AbstractPostsController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -133,7 +133,7 @@ class Coupons extends AbstractPostsController { * @return WC_Data */ protected function get_object( $id ) { - return new WC_Coupon( $id ); + return new \WC_Coupon( $id ); } /** @@ -258,17 +258,17 @@ class Coupons extends AbstractPostsController { * * @param WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data + * @return \WP_Error|WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $coupon = new WC_Coupon( $id ); + $coupon = new \WC_Coupon( $id ); $schema = $this->get_item_schema(); $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); // Validate required POST fields. if ( $creating && empty( $request['code'] ) ) { - return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); } // Handle all writable props. @@ -283,7 +283,7 @@ class Coupons extends AbstractPostsController { $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); if ( $id_from_code ) { - return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); } $coupon->set_code( $coupon_code ); @@ -570,7 +570,7 @@ class Coupons extends AbstractPostsController { * @return WP_REST_Response $data */ public function prepare_item_for_response( $post, $request ) { - $coupon = new WC_Coupon( (int) $post->ID ); + $coupon = new \WC_Coupon( (int) $post->ID ); $_data = $coupon->get_data(); $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); @@ -655,11 +655,11 @@ class Coupons extends AbstractPostsController { * Prepare a single coupon for create or update. * * @param WP_REST_Request $request Request object. - * @return WP_Error|stdClass $data Post object. + * @return \WP_Error|stdClass $data Post object. */ protected function prepare_item_for_database( $request ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $coupon = new WC_Coupon( $id ); + $coupon = new \WC_Coupon( $id ); $schema = $this->get_item_schema(); $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); @@ -674,7 +674,7 @@ class Coupons extends AbstractPostsController { // Validate required POST fields. if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { if ( empty( $request['code'] ) ) { - return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); } } @@ -690,7 +690,7 @@ class Coupons extends AbstractPostsController { $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); if ( $id_from_code ) { - return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); } $coupon->set_code( $coupon_code ); @@ -726,12 +726,12 @@ class Coupons extends AbstractPostsController { * Create a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $coupon_id = $this->save_coupon( $request ); @@ -765,14 +765,14 @@ class Coupons extends AbstractPostsController { * Update a single coupon. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { try { $post_id = (int) $request['id']; if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } $coupon_id = $this->save_coupon( $request ); @@ -796,15 +796,15 @@ class Coupons extends AbstractPostsController { return rest_ensure_response( $response ); } catch ( Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } /** - * Get a collection of posts and add the code search option to WP_Query. + * Get a collection of posts and add the code search option to \WP_Query. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10, 2 ); @@ -817,7 +817,7 @@ class Coupons extends AbstractPostsController { * Add code searching to the WP Query * * @param string $where Where clause used to search posts. - * @param object $wp_query WP_Query object. + * @param object $wp_query \WP_Query object. * @return string */ public static function add_wp_query_search_code_filter( $where, $wp_query ) { diff --git a/src/RestApi/Version4/Controllers/CustomerDownloads.php b/src/RestApi/Version4/Controllers/CustomerDownloads.php index e29e1e7867f..475bb1e900f 100644 --- a/src/RestApi/Version4/Controllers/CustomerDownloads.php +++ b/src/RestApi/Version4/Controllers/CustomerDownloads.php @@ -38,7 +38,7 @@ class CustomerDownloads extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -52,17 +52,17 @@ class CustomerDownloads extends AbstractController { * Check whether a given request has permission to read customers. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { $customer = get_user_by( 'id', (int) $request['customer_id'] ); if ( ! $customer ) { - return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_user_permissions( 'read', $customer->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/RestApi/Version4/Controllers/Customers.php index 34e0d1d373f..d46d261b5b7 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Version4\Controllers; defined( 'ABSPATH' ) || exit; +use \WP_REST_Server; + /** * REST API Customers controller class. */ @@ -32,17 +34,17 @@ class Customers extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'email' => array( 'required' => true, @@ -77,7 +79,7 @@ class Customers extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -85,13 +87,13 @@ class Customers extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -116,10 +118,10 @@ class Customers extends AbstractController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -130,11 +132,11 @@ class Customers extends AbstractController { * Check whether a given request has permission to read customers. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -145,11 +147,11 @@ class Customers extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -159,13 +161,13 @@ class Customers extends AbstractController { * Check if a given request has access to read a customer. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'read', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -176,13 +178,13 @@ class Customers extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function update_item_permissions_check( $request ) { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'edit', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -193,13 +195,13 @@ class Customers extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'delete', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -210,11 +212,11 @@ class Customers extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -263,7 +265,7 @@ class Customers extends AbstractController { * Get all customers. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $prepared_args = array(); @@ -301,16 +303,16 @@ class Customers extends AbstractController { } /** - * Filter arguments, before passing to WP_User_Query, when querying users via the REST API. + * Filter arguments, before passing to \ WP_User_Query, when querying users via the REST API. * - * @see https://developer.wordpress.org/reference/classes/wp_user_query/ + * @see https://developer.wordpress.org/reference/classes/\ WP_User_Query/ * - * @param array $prepared_args Array of arguments for WP_User_Query. + * @param array $prepared_args Array of arguments for \ WP_User_Query. * @param WP_REST_Request $request The current request. */ $prepared_args = apply_filters( 'woocommerce_rest_customer_query', $prepared_args, $request ); - $query = new WP_User_Query( $prepared_args ); + $query = new \ WP_User_Query( $prepared_args ); $users = array(); foreach ( $query->results as $user ) { @@ -331,7 +333,7 @@ class Customers extends AbstractController { // Out-of-bounds, run the query again without LIMIT for total count. unset( $prepared_args['number'] ); unset( $prepared_args['offset'] ); - $count_query = new WP_User_Query( $prepared_args ); + $count_query = new \ WP_User_Query( $prepared_args ); $total_users = $count_query->get_total(); } $response->header( 'X-WP-Total', (int) $total_users ); @@ -361,12 +363,12 @@ class Customers extends AbstractController { * * @throws WC_REST_Exception On invalid params. * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { try { if ( ! empty( $request['id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); } // Sets the username. @@ -376,7 +378,7 @@ class Customers extends AbstractController { $request['password'] = ! empty( $request['password'] ) ? $request['password'] : ''; // Create customer. - $customer = new WC_Customer(); + $customer = new \WC_Customer(); $customer->set_username( $request['username'] ); $customer->set_password( $request['password'] ); $customer->set_email( $request['email'] ); @@ -384,7 +386,7 @@ class Customers extends AbstractController { $customer->save(); if ( ! $customer->get_id() ) { - throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); } $user_data = get_userdata( $customer->get_id() ); @@ -407,7 +409,7 @@ class Customers extends AbstractController { return $response; } catch ( Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } @@ -415,14 +417,14 @@ class Customers extends AbstractController { * Get a single customer. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; $user_data = get_userdata( $id ); if ( empty( $id ) || empty( $user_data->ID ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $customer = $this->prepare_item_for_response( $user_data, $request ); @@ -436,23 +438,23 @@ class Customers extends AbstractController { * * @throws WC_REST_Exception On invalid params. * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { try { $id = (int) $request['id']; - $customer = new WC_Customer( $id ); + $customer = new \WC_Customer( $id ); if ( ! $customer->get_id() ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); } if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->get_email() ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); } if ( ! empty( $request['username'] ) && $request['username'] !== $customer->get_username() ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); } // Customer email. @@ -489,7 +491,7 @@ class Customers extends AbstractController { $response = rest_ensure_response( $response ); return $response; } catch ( Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } @@ -497,7 +499,7 @@ class Customers extends AbstractController { * Delete a single customer. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -506,17 +508,17 @@ class Customers extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $user_data = get_userdata( $id ); if ( ! $user_data ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); } if ( ! empty( $reassign ) ) { if ( $reassign === $id || ! get_userdata( $reassign ) ) { - return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -526,7 +528,7 @@ class Customers extends AbstractController { /** Include admin customer functions to get access to wp_delete_user() */ require_once ABSPATH . 'wp-admin/includes/user.php'; - $customer = new WC_Customer( $id ); + $customer = new \WC_Customer( $id ); if ( ! is_null( $reassign ) ) { $result = $customer->delete_and_reassign( $reassign ); @@ -535,7 +537,7 @@ class Customers extends AbstractController { } if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -558,7 +560,7 @@ class Customers extends AbstractController { * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $user_data, $request ) { - $customer = new WC_Customer( $user_data->ID ); + $customer = new \WC_Customer( $user_data->ID ); $data = $this->get_formatted_item_data( $customer ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); diff --git a/src/RestApi/Version4/Controllers/Data.php b/src/RestApi/Version4/Controllers/Data.php index 767183e26d5..c57b4febf2e 100644 --- a/src/RestApi/Version4/Controllers/Data.php +++ b/src/RestApi/Version4/Controllers/Data.php @@ -34,7 +34,7 @@ class Data extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -47,11 +47,11 @@ class Data extends AbstractController { * Check whether a given request has permission to read site data. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -61,11 +61,11 @@ class Data extends AbstractController { * Check whether a given request has permission to read site settings. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -76,7 +76,7 @@ class Data extends AbstractController { * * @since 3.5.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $data = array(); diff --git a/src/RestApi/Version4/Controllers/Data/Continents.php b/src/RestApi/Version4/Controllers/Data/Continents.php index d8d05249b60..7e2afd69dae 100644 --- a/src/RestApi/Version4/Controllers/Data/Continents.php +++ b/src/RestApi/Version4/Controllers/Data/Continents.php @@ -36,7 +36,7 @@ class Continents extends DataController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -48,7 +48,7 @@ class Continents extends DataController { '/' . $this->rest_base . '/(?P[\w-]+)', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( @@ -155,7 +155,7 @@ class Continents extends DataController { * * @since 3.5.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $continents = WC()->countries->get_continents(); @@ -175,12 +175,12 @@ class Continents extends DataController { * * @since 3.5.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $data = $this->get_continent( strtoupper( $request['location'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } diff --git a/src/RestApi/Version4/Controllers/Data/Countries.php b/src/RestApi/Version4/Controllers/Data/Countries.php index 2f95f9ca0ba..c8b248b18ac 100644 --- a/src/RestApi/Version4/Controllers/Data/Countries.php +++ b/src/RestApi/Version4/Controllers/Data/Countries.php @@ -36,7 +36,7 @@ class Countries extends DataController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -48,7 +48,7 @@ class Countries extends DataController { '/' . $this->rest_base . '/(?P[\w-]+)', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( @@ -102,7 +102,7 @@ class Countries extends DataController { * * @since 3.5.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $countries = WC()->countries->get_countries(); @@ -122,12 +122,12 @@ class Countries extends DataController { * * @since 3.5.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $data = $this->get_country( strtoupper( $request['location'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } diff --git a/src/RestApi/Version4/Controllers/Data/Currencies.php b/src/RestApi/Version4/Controllers/Data/Currencies.php index ab6149e8604..d6a892f6b3b 100644 --- a/src/RestApi/Version4/Controllers/Data/Currencies.php +++ b/src/RestApi/Version4/Controllers/Data/Currencies.php @@ -34,7 +34,7 @@ class Currencies extends DataController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -46,7 +46,7 @@ class Currencies extends DataController { '/' . $this->rest_base . '/current', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_current_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), @@ -58,7 +58,7 @@ class Currencies extends DataController { '/' . $this->rest_base . '/(?P[\w-]{3})', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -101,7 +101,7 @@ class Currencies extends DataController { * Return the list of currencies. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $currencies = get_woocommerce_currencies(); @@ -118,12 +118,12 @@ class Currencies extends DataController { * Return information for a specific currency. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -132,7 +132,7 @@ class Currencies extends DataController { * Return information for the current site currency. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_current_item( $request ) { $currency = get_option( 'woocommerce_currency' ); diff --git a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php index 127b19b0642..d20177270be 100644 --- a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php +++ b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php @@ -36,7 +36,7 @@ class DownloadIPs extends DataController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -50,7 +50,7 @@ class DownloadIPs extends DataController { * * @since 3.5.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { global $wpdb; @@ -65,7 +65,7 @@ class DownloadIPs extends DataController { ) ); } else { - return new WP_Error( 'woocommerce_rest_data_download_ips_invalid_request', __( 'Invalid request. Please pass the match parameter.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_data_download_ips_invalid_request', __( 'Invalid request. Please pass the match parameter.', 'woocommerce' ), array( 'status' => 400 ) ); } $data = array(); diff --git a/src/RestApi/Version4/Controllers/Leaderboards.php b/src/RestApi/Version4/Controllers/Leaderboards.php index 6e22b5ddbf5..d01cd5f7db2 100644 --- a/src/RestApi/Version4/Controllers/Leaderboards.php +++ b/src/RestApi/Version4/Controllers/Leaderboards.php @@ -27,12 +27,16 @@ class Leaderboards extends AbstractController { * Register routes. */ public function register_routes() { + if ( ! class_exists( 'WC_Admin_Reports_Coupons_Data_Store' ) ) { + return; + } + register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -46,7 +50,7 @@ class Leaderboards extends AbstractController { '/' . $this->rest_base . '/allowed', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_allowed_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -64,7 +68,7 @@ class Leaderboards extends AbstractController { * @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_store = new \WC_Admin_Reports_Coupons_Data_Store(); $coupons_data = $per_page > 0 ? $coupons_data_store->get_data( array( 'orderby' => 'orders_count', @@ -130,7 +134,7 @@ class Leaderboards extends AbstractController { * @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_store = new \WC_Admin_Reports_Categories_Data_Store(); $categories_data = $per_page > 0 ? $categories_data_store->get_data( array( 'orderby' => 'items_sold', @@ -196,7 +200,7 @@ class Leaderboards extends AbstractController { * @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_store = new \WC_Admin_Reports_Customers_Data_Store(); $customers_data = $per_page > 0 ? $customers_data_store->get_data( array( 'orderby' => 'total_spend', @@ -260,7 +264,7 @@ class Leaderboards extends AbstractController { * @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_store = new \WC_Admin_Reports_Products_Data_Store(); $products_data = $per_page > 0 ? $products_data_store->get_data( array( 'orderby' => 'items_sold', @@ -341,7 +345,7 @@ class Leaderboards extends AbstractController { * Return all leaderboards. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $persisted_query = json_decode( $request['persisted_query'], true ); @@ -362,7 +366,7 @@ class Leaderboards extends AbstractController { * Returns a list of allowed leaderboards. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_allowed_items( $request ) { $leaderboards = $this->get_leaderboards( 0, null, null, null ); diff --git a/src/RestApi/Version4/Controllers/NetworkOrders.php b/src/RestApi/Version4/Controllers/NetworkOrders.php index ff3481e1b21..f2465afdbbb 100644 --- a/src/RestApi/Version4/Controllers/NetworkOrders.php +++ b/src/RestApi/Version4/Controllers/NetworkOrders.php @@ -26,7 +26,7 @@ class NetworkOrders extends Orders { '/' . $this->rest_base . '/network', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'network_orders' ), 'permission_callback' => array( $this, 'network_orders_permissions_check' ), 'args' => $this->get_collection_params(), diff --git a/src/RestApi/Version4/Controllers/Onboarding/Levels.php b/src/RestApi/Version4/Controllers/Onboarding/Levels.php index 4ac4f6e7411..ff6bacdc0d9 100644 --- a/src/RestApi/Version4/Controllers/Onboarding/Levels.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Levels.php @@ -44,7 +44,7 @@ class Levels extends WC_REST_Data_Controller { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -124,7 +124,7 @@ class Levels extends WC_REST_Data_Controller { * Return all level items and child tasks. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { global $wpdb; diff --git a/src/RestApi/Version4/Controllers/Onboarding/Plugins.php b/src/RestApi/Version4/Controllers/Onboarding/Plugins.php index e7e602c0266..60b1b8dd403 100644 --- a/src/RestApi/Version4/Controllers/Onboarding/Plugins.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Plugins.php @@ -43,7 +43,7 @@ class Plugins extends WC_REST_Data_Controller { '/' . $this->rest_base . '/install', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'install_plugin' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), ), @@ -56,7 +56,7 @@ class Plugins extends WC_REST_Data_Controller { '/' . $this->rest_base . '/activate', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'activate_plugin' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), ), @@ -69,7 +69,7 @@ class Plugins extends WC_REST_Data_Controller { '/' . $this->rest_base . '/connect-jetpack', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'connect_jetpack' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), ), @@ -82,11 +82,11 @@ class Plugins extends WC_REST_Data_Controller { * Check if a given request has access to manage plugins. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { if ( ! current_user_can( 'install_plugins' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot manage plugins.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot manage plugins.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -114,7 +114,7 @@ class Plugins extends WC_REST_Data_Controller { $allowed_plugins = $this->get_allowed_plugins(); $plugin = sanitize_title_with_dashes( $request['plugin'] ); if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) { - return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); } require_once ABSPATH . 'wp-admin/includes/plugin.php'; @@ -148,14 +148,14 @@ class Plugins extends WC_REST_Data_Controller { ); if ( is_wp_error( $api ) ) { - return new WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce' ), 500 ); + return new \WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce' ), 500 ); } $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); $result = $upgrader->install( $api->download_link ); if ( is_wp_error( $result ) || is_null( $result ) ) { - return new WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce' ), 500 ); + return new \WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce' ), 500 ); } return array( @@ -175,7 +175,7 @@ class Plugins extends WC_REST_Data_Controller { $allowed_plugins = $this->get_allowed_plugins(); $plugin = sanitize_title_with_dashes( $request['plugin'] ); if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) { - return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); } require_once ABSPATH . 'wp-admin/includes/plugin.php'; @@ -185,12 +185,12 @@ class Plugins extends WC_REST_Data_Controller { $installed_plugins = get_plugins(); if ( ! in_array( $path, array_keys( $installed_plugins ), true ) ) { - return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); } $result = activate_plugin( $path ); if ( ! is_null( $result ) ) { - return new WP_Error( 'woocommerce_rest_invalid_plugin', __( 'The requested plugin could not be activated.', 'woocommerce' ), 500 ); + return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'The requested plugin could not be activated.', 'woocommerce' ), 500 ); } return( array( @@ -207,7 +207,7 @@ class Plugins extends WC_REST_Data_Controller { */ public function connect_jetpack() { if ( ! class_exists( 'Jetpack' ) ) { - return new WP_Error( 'woocommerce_rest_jetpack_not_active', __( 'Jetpack is not installed or active.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_jetpack_not_active', __( 'Jetpack is not installed or active.', 'woocommerce' ), 404 ); } $next_step_slug = apply_filters( 'woocommerce_onboarding_after_jetpack_step', 'store-details' ); diff --git a/src/RestApi/Version4/Controllers/Onboarding/Profile.php b/src/RestApi/Version4/Controllers/Onboarding/Profile.php index 36baa65c460..bdbb2babc62 100644 --- a/src/RestApi/Version4/Controllers/Onboarding/Profile.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Profile.php @@ -44,7 +44,7 @@ class Profile extends WC_REST_Data_Controller { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -56,7 +56,7 @@ class Profile extends WC_REST_Data_Controller { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_items' ), 'permission_callback' => array( $this, 'update_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -70,11 +70,11 @@ class Profile extends WC_REST_Data_Controller { * Check whether a given request has permission to read onboarding profile data. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -84,11 +84,11 @@ class Profile extends WC_REST_Data_Controller { * Check whether a given request has permission to edit onboarding profile data. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -98,7 +98,7 @@ class Profile extends WC_REST_Data_Controller { * Return all onboarding profile data. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $onboarding_data = get_option( 'wc_onboarding_profile', array() ); @@ -119,7 +119,7 @@ class Profile extends WC_REST_Data_Controller { * Update onboarding profile data. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_items( $request ) { $params = $request->get_json_params(); @@ -232,7 +232,7 @@ class Profile extends WC_REST_Data_Controller { 'sanitize_callback' => 'wp_parse_slug_list', 'validate_callback' => 'rest_validate_request_arg', 'items' => array( - 'enum' => array_keys( WC_Admin_Onboarding::get_allowed_industries() ), + 'enum' => array_keys( \WC_Admin_Onboarding::get_allowed_industries() ), 'type' => 'string', ), ), @@ -244,7 +244,7 @@ class Profile extends WC_REST_Data_Controller { 'sanitize_callback' => 'wp_parse_slug_list', 'validate_callback' => 'rest_validate_request_arg', 'items' => array( - 'enum' => array_keys( WC_Admin_Onboarding::get_allowed_product_types() ), + 'enum' => array_keys( \WC_Admin_Onboarding::get_allowed_product_types() ), 'type' => 'string', ), ), diff --git a/src/RestApi/Version4/Controllers/OrderNotes.php b/src/RestApi/Version4/Controllers/OrderNotes.php index 496da144226..507d82bb5c5 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -42,16 +42,16 @@ class OrderNotes extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'note' => array( 'type' => 'string', 'description' => __( 'Order note content.', 'woocommerce' ), @@ -74,7 +74,7 @@ class OrderNotes extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -82,7 +82,7 @@ class OrderNotes extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -101,11 +101,11 @@ class OrderNotes extends AbstractController { * Check whether a given request has permission to read order notes. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -116,11 +116,11 @@ class OrderNotes extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -130,13 +130,13 @@ class OrderNotes extends AbstractController { * Check if a given request has access to read a order note. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { $order = wc_get_order( (int) $request['order_id'] ); if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -147,13 +147,13 @@ class OrderNotes extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { $order = wc_get_order( (int) $request['order_id'] ); if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -164,13 +164,13 @@ class OrderNotes extends AbstractController { * * @param WP_REST_Request $request Request data. * - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $args = array( @@ -217,25 +217,25 @@ class OrderNotes extends AbstractController { * Create a single order note. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } // Create the note. $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); if ( ! $note_id ) { - return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); } $note = get_comment( $note_id ); @@ -263,20 +263,20 @@ class OrderNotes extends AbstractController { * Get a single order note. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $order_note = $this->prepare_item_for_response( $note, $request ); @@ -289,7 +289,7 @@ class OrderNotes extends AbstractController { * Delete a single order note. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -297,19 +297,19 @@ class OrderNotes extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); @@ -318,7 +318,7 @@ class OrderNotes extends AbstractController { $result = wc_delete_order_note( $note->comment_ID ); if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); } /** diff --git a/src/RestApi/Version4/Controllers/OrderRefunds.php b/src/RestApi/Version4/Controllers/OrderRefunds.php index 8f060695af5..583f2e4f731 100644 --- a/src/RestApi/Version4/Controllers/OrderRefunds.php +++ b/src/RestApi/Version4/Controllers/OrderRefunds.php @@ -59,16 +59,16 @@ class OrderRefunds extends Orders { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -89,7 +89,7 @@ class OrderRefunds extends Orders { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -97,7 +97,7 @@ class OrderRefunds extends Orders { ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -175,7 +175,7 @@ class OrderRefunds extends Orders { * @param WC_Data $object Object data. * @param WP_REST_Request $request Request object. * - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { $this->request = $request; @@ -183,11 +183,11 @@ class OrderRefunds extends Orders { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); } if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); } $data = $this->get_formatted_item_data( $object ); @@ -219,19 +219,19 @@ class OrderRefunds extends Orders { * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. * - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function prepare_item_for_response( $post, $request ) { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); } $refund = wc_get_order( $post ); if ( ! $refund || $refund->get_parent_id() !== $order->get_id() ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); } $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); @@ -375,22 +375,22 @@ class OrderRefunds extends Orders { * Create a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $order_data = get_post( (int) $request['order_id'] ); if ( empty( $order_data ) ) { - return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); + return new \WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); } if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); } // Create the refund. @@ -405,11 +405,11 @@ class OrderRefunds extends Orders { ); if ( is_wp_error( $refund ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); } if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); } $post = get_post( $refund->get_id() ); @@ -439,17 +439,17 @@ class OrderRefunds extends Orders { * @since 3.0.0 * @param WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + * @return \WP_Error|WC_Data The prepared item, or \WP_Error object on failure. */ protected function prepare_object_for_database( $request, $creating = false ) { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); } if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); } // Create the refund. @@ -465,11 +465,11 @@ class OrderRefunds extends Orders { ); if ( is_wp_error( $refund ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); } if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); } if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { @@ -498,7 +498,7 @@ class OrderRefunds extends Orders { * @since 3.0.0 * @param WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. - * @return WC_Data|WP_Error + * @return WC_Data|\WP_Error */ protected function save_object( $request, $creating = false ) { try { @@ -510,9 +510,9 @@ class OrderRefunds extends Orders { return $this->get_object( $object->get_id() ); } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index 3d96ac4d35b..a0b6a7bf253 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -53,16 +53,16 @@ class Orders extends AbstractObjectsController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -79,7 +79,7 @@ class Orders extends AbstractObjectsController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -87,13 +87,13 @@ class Orders extends AbstractObjectsController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -113,10 +113,10 @@ class Orders extends AbstractObjectsController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -352,7 +352,7 @@ class Orders extends AbstractObjectsController { protected function prepare_objects_query( $request ) { global $wpdb; - // This is needed to get around an array to string notice in WC_REST_Orders_V2_Controller::prepare_objects_query. + // This is needed to get around an array to string notice in \WC_REST_Orders_V2_Controller::prepare_objects_query. $statuses = $request['status']; unset( $request['status'] ); $args = parent::prepare_objects_query( $request ); @@ -389,7 +389,7 @@ class Orders extends AbstractObjectsController { ) ); - // Force WP_Query return empty if don't found any order. + // Force \WP_Query return empty if don't found any order. $order_ids = empty( $order_ids ) ? array( 0 ) : $order_ids; $args['post__in'] = $order_ids; } @@ -414,11 +414,11 @@ class Orders extends AbstractObjectsController { * @throws WC_REST_Exception When fails to set any item. * @param WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data + * @return \WP_Error|WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $order = new WC_Order( $id ); + $order = new \WC_Order( $id ); $schema = $this->get_item_schema(); $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); @@ -487,7 +487,7 @@ class Orders extends AbstractObjectsController { * @throws WC_REST_Exception But all errors are validated before returning any data. * @param WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. - * @return WC_Data|WP_Error + * @return WC_Data|\WP_Error */ protected function save_object( $request, $creating = false ) { try { @@ -503,7 +503,7 @@ class Orders extends AbstractObjectsController { if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { // Make sure customer exists. if ( false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); } // Make sure customer is part of blog. @@ -542,9 +542,9 @@ class Orders extends AbstractObjectsController { return $this->get_object( $object->get_id() ); } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } @@ -578,7 +578,7 @@ class Orders extends AbstractObjectsController { } elseif ( ! empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['variation_id']; } else { - throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); } return $product_id; } @@ -636,7 +636,7 @@ class Orders extends AbstractObjectsController { * @throws WC_REST_Exception Invalid data, server error. */ protected function prepare_line_items( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + $item = is_null( $item ) ? new \WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; $product = wc_get_product( $this->get_product_id( $posted ) ); if ( $product !== $item->get_product() ) { @@ -666,11 +666,11 @@ class Orders extends AbstractObjectsController { * @throws WC_REST_Exception Invalid data, server error. */ protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + $item = is_null( $item ) ? new \WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; if ( 'create' === $action ) { if ( empty( $posted['method_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); } } @@ -690,11 +690,11 @@ class Orders extends AbstractObjectsController { * @throws WC_REST_Exception Invalid data, server error. */ protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + $item = is_null( $item ) ? new \WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; if ( 'create' === $action ) { if ( empty( $posted['name'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); } } @@ -714,11 +714,11 @@ class Orders extends AbstractObjectsController { * @throws WC_REST_Exception Invalid data, server error. */ protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + $item = is_null( $item ) ? new \WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; if ( 'create' === $action ) { if ( empty( $posted['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); } } @@ -755,7 +755,7 @@ class Orders extends AbstractObjectsController { $item = $order->get_item( absint( $posted['id'] ), false ); if ( ! $item ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); } } @@ -1714,13 +1714,13 @@ class Orders extends AbstractObjectsController { if ( is_array( $item ) ) { if ( empty( $item['id'] ) ) { if ( empty( $item['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); } $results = $order->apply_coupon( wc_clean( $item['code'] ) ); if ( is_wp_error( $results ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); } } } diff --git a/src/RestApi/Version4/Controllers/PaymentGateways.php b/src/RestApi/Version4/Controllers/PaymentGateways.php index e5c511de844..be8e0aaf69e 100644 --- a/src/RestApi/Version4/Controllers/PaymentGateways.php +++ b/src/RestApi/Version4/Controllers/PaymentGateways.php @@ -32,7 +32,7 @@ class PaymentGateways extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -51,7 +51,7 @@ class PaymentGateways extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -59,10 +59,10 @@ class PaymentGateways extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -73,11 +73,11 @@ class PaymentGateways extends AbstractController { * Check whether a given request has permission to view payment gateways. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -86,11 +86,11 @@ class PaymentGateways extends AbstractController { * Check if a given request has access to read a payment gateway. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -99,11 +99,11 @@ class PaymentGateways extends AbstractController { * Check whether a given request has permission to edit payment gateways. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -112,7 +112,7 @@ class PaymentGateways extends AbstractController { * Get payment gateways. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $payment_gateways = WC()->payment_gateways->payment_gateways(); @@ -130,13 +130,13 @@ class PaymentGateways extends AbstractController { * Get a single payment gateway. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function get_item( $request ) { $gateway = $this->get_gateway( $request ); if ( is_null( $gateway ) ) { - return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $gateway = $this->prepare_item_for_response( $gateway, $request ); @@ -147,13 +147,13 @@ class PaymentGateways extends AbstractController { * Update A Single Payment Method. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function update_item( $request ) { $gateway = $this->get_gateway( $request ); if ( is_null( $gateway ) ) { - return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } // Get settings. @@ -179,7 +179,7 @@ class PaymentGateways extends AbstractController { } if ( $errors_found ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } } diff --git a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php index 06caad9a04f..98e06768bf7 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php +++ b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php @@ -38,17 +38,17 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'name' => array( 'type' => 'string', @@ -77,7 +77,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -85,13 +85,13 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -117,10 +117,10 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -172,7 +172,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { * * @param WP_Term $term Term object. * @param WP_REST_Request $request Request params. - * @return bool|WP_Error + * @return bool|\WP_Error */ protected function update_term_meta_fields( $term, $request ) { $id = (int) $term->term_id; diff --git a/src/RestApi/Version4/Controllers/ProductAttributes.php b/src/RestApi/Version4/Controllers/ProductAttributes.php index 7a5031dad33..cfe69d770dd 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributes.php +++ b/src/RestApi/Version4/Controllers/ProductAttributes.php @@ -39,17 +39,17 @@ class ProductAttributes extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'name' => array( 'description' => __( 'Name for the resource.', 'woocommerce' ), @@ -74,7 +74,7 @@ class ProductAttributes extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -82,13 +82,13 @@ class ProductAttributes extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -108,10 +108,10 @@ class ProductAttributes extends AbstractController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -122,11 +122,11 @@ class ProductAttributes extends AbstractController { * Check if a given request has access to read the attributes. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -136,11 +136,11 @@ class ProductAttributes extends AbstractController { * Check if a given request has access to create a attribute. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -150,15 +150,15 @@ class ProductAttributes extends AbstractController { * Check if a given request has access to read a attribute. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -168,15 +168,15 @@ class ProductAttributes extends AbstractController { * Check if a given request has access to update a attribute. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -186,15 +186,15 @@ class ProductAttributes extends AbstractController { * Check if a given request has access to delete a attribute. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function delete_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -205,11 +205,11 @@ class ProductAttributes extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -237,7 +237,7 @@ class ProductAttributes extends AbstractController { * Create a single attribute. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function create_item( $request ) { global $wpdb; @@ -254,7 +254,7 @@ class ProductAttributes extends AbstractController { // Checks for errors. if ( is_wp_error( $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', $id->get_error_message(), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', $id->get_error_message(), array( 'status' => 400 ) ); } $attribute = $this->get_attribute( $id ); @@ -287,7 +287,7 @@ class ProductAttributes extends AbstractController { * Get a single attribute. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function get_item( $request ) { $attribute = $this->get_attribute( (int) $request['id'] ); @@ -305,7 +305,7 @@ class ProductAttributes extends AbstractController { * Update a single term from a taxonomy. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function update_item( $request ) { global $wpdb; @@ -324,7 +324,7 @@ class ProductAttributes extends AbstractController { // Checks for errors. if ( is_wp_error( $edited ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', $edited->get_error_message(), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', $edited->get_error_message(), array( 'status' => 400 ) ); } $attribute = $this->get_attribute( $id ); @@ -354,14 +354,14 @@ class ProductAttributes extends AbstractController { * Delete a single attribute. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $force = isset( $request['force'] ) ? (bool) $request['force'] : false; // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $attribute = $this->get_attribute( (int) $request['id'] ); @@ -376,7 +376,7 @@ class ProductAttributes extends AbstractController { $deleted = wc_delete_attribute( $attribute->attribute_id ); if ( false === $deleted ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -543,7 +543,7 @@ class ProductAttributes extends AbstractController { * Get attribute data. * * @param int $id Attribute ID. - * @return stdClass|WP_Error + * @return stdClass|\WP_Error */ protected function get_attribute( $id ) { global $wpdb; @@ -560,7 +560,7 @@ class ProductAttributes extends AbstractController { ); if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { - return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } return $attribute; @@ -572,18 +572,18 @@ class ProductAttributes extends AbstractController { * @deprecated 3.2.0 * @param string $slug Slug being set. * @param bool $new_data Is the data new or old. - * @return bool|WP_Error + * @return bool|\WP_Error */ protected function validate_attribute_slug( $slug, $new_data = true ) { if ( strlen( $slug ) >= 28 ) { /* Translators: %s slug. */ - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { /* Translators: %s slug. */ - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { /* Translators: %s slug. */ - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } return true; diff --git a/src/RestApi/Version4/Controllers/ProductCategories.php b/src/RestApi/Version4/Controllers/ProductCategories.php index d708ebb39f2..e45eb39e32a 100644 --- a/src/RestApi/Version4/Controllers/ProductCategories.php +++ b/src/RestApi/Version4/Controllers/ProductCategories.php @@ -98,7 +98,7 @@ class ProductCategories extends AbstractTermsContoller { * * @param WP_Term $term Term object. * @param WP_REST_Request $request Request instance. - * @return bool|WP_Error + * @return bool|\WP_Error * * @since 3.5.5 */ diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/RestApi/Version4/Controllers/ProductReviews.php index 432b4c77316..0085c145cd2 100644 --- a/src/RestApi/Version4/Controllers/ProductReviews.php +++ b/src/RestApi/Version4/Controllers/ProductReviews.php @@ -32,17 +32,17 @@ class ProductReviews extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'product_id' => array( 'required' => true, @@ -82,7 +82,7 @@ class ProductReviews extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -90,13 +90,13 @@ class ProductReviews extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -116,10 +116,10 @@ class ProductReviews extends AbstractController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -130,11 +130,11 @@ class ProductReviews extends AbstractController { * Check whether a given request has permission to read webhook deliveries. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -144,14 +144,14 @@ class ProductReviews extends AbstractController { * Check if a given request has access to read a product review. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { $id = (int) $request['id']; $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -161,11 +161,11 @@ class ProductReviews extends AbstractController { * Check if a given request has access to create a new product review. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -175,14 +175,14 @@ class ProductReviews extends AbstractController { * Check if a given request has access to update a product review. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { $id = (int) $request['id']; $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'edit', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -192,14 +192,14 @@ class ProductReviews extends AbstractController { * Check if a given request has access to delete a product review. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function delete_item_permissions_check( $request ) { $id = (int) $request['id']; $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'delete', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -209,11 +209,11 @@ class ProductReviews extends AbstractController { * Check if a given request has access batch create, update and delete items. * * @param WP_REST_Request $request Full details about the request. - * @return boolean|WP_Error + * @return boolean|\WP_Error */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -223,7 +223,7 @@ class ProductReviews extends AbstractController { * Get all reviews. * * @param WP_REST_Request $request Full details about the request. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { // Retrieve the list of registered collection query parameters. @@ -231,7 +231,7 @@ class ProductReviews extends AbstractController { /* * This array defines mappings between public API query parameters whose - * values are accepted as-passed, and their internal WP_Query parameter + * values are accepted as-passed, and their internal \WP_Query parameter * name equivalents (some are the same). Only values which are also * present in $registered will be set. */ @@ -365,17 +365,17 @@ class ProductReviews extends AbstractController { * Create a single review. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce' ), array( 'status' => 400 ) ); } $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $prepared_review = $this->prepare_item_for_database( $request ); @@ -389,7 +389,7 @@ class ProductReviews extends AbstractController { * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). */ if ( empty( $prepared_review['comment_content'] ) ) { - return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); } // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). @@ -414,7 +414,7 @@ class ProductReviews extends AbstractController { $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); } $prepared_review['comment_parent'] = 0; @@ -426,11 +426,11 @@ class ProductReviews extends AbstractController { $error_message = $prepared_review['comment_approved']->get_error_message(); if ( 'comment_duplicate' === $error_code ) { - return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 409 ) ); + return new \WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 409 ) ); } if ( 'comment_flood' === $error_code ) { - return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 400 ) ); } return $prepared_review['comment_approved']; @@ -440,11 +440,11 @@ class ProductReviews extends AbstractController { * Filters a review before it is inserted via the REST API. * * Allows modification of the review right before it is inserted via wp_insert_comment(). - * Returning a WP_Error value from the filter will shortcircuit insertion and allow + * Returning a \WP_Error value from the filter will shortcircuit insertion and allow * skipping further processing. * * @since 3.5.0 - * @param array|WP_Error $prepared_review The prepared review data for wp_insert_comment(). + * @param array|\WP_Error $prepared_review The prepared review data for wp_insert_comment(). * @param WP_REST_Request $request Request used to insert the review. */ $prepared_review = apply_filters( 'woocommerce_rest_pre_insert_product_review', $prepared_review, $request ); @@ -455,7 +455,7 @@ class ProductReviews extends AbstractController { $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); if ( ! $review_id ) { - return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { @@ -496,7 +496,7 @@ class ProductReviews extends AbstractController { * Get a single product review. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $review = $this->get_review( $request['id'] ); @@ -514,7 +514,7 @@ class ProductReviews extends AbstractController { * Updates a review. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. + * @return \WP_Error|WP_REST_Response Response object on success, or error object on failure. */ public function update_item( $request ) { $review = $this->get_review( $request['id'] ); @@ -525,7 +525,7 @@ class ProductReviews extends AbstractController { $id = (int) $review->comment_ID; if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { - return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce' ), array( 'status' => 404 ) ); } $prepared_args = $this->prepare_item_for_database( $request ); @@ -535,7 +535,7 @@ class ProductReviews extends AbstractController { if ( ! empty( $prepared_args['comment_post_ID'] ) ) { if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } } @@ -544,7 +544,7 @@ class ProductReviews extends AbstractController { $change = $this->handle_status_param( $request['status'], $id ); if ( ! $change ) { - return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce' ), array( 'status' => 500 ) ); } } elseif ( ! empty( $prepared_args ) ) { if ( is_wp_error( $prepared_args ) ) { @@ -552,7 +552,7 @@ class ProductReviews extends AbstractController { } if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { - return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); } $prepared_args['comment_ID'] = $id; @@ -560,13 +560,13 @@ class ProductReviews extends AbstractController { $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); } $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); if ( false === $updated ) { - return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { @@ -600,7 +600,7 @@ class ProductReviews extends AbstractController { * Deletes a review. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. + * @return \WP_Error|WP_REST_Response Response object on success, or error object on failure. */ public function delete_item( $request ) { $review = $this->get_review( $request['id'] ); @@ -637,11 +637,11 @@ class ProductReviews extends AbstractController { // If this type doesn't support trashing, error out. if ( ! $supports_trash ) { /* translators: %s: force=true */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce' ), 'force=true' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce' ), 'force=true' ), array( 'status' => 501 ) ); } if ( 'trash' === $review->comment_approved ) { - return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + return new \WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); } $result = wp_trash_comment( $review->comment_ID ); @@ -650,7 +650,7 @@ class ProductReviews extends AbstractController { } if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -733,7 +733,7 @@ class ProductReviews extends AbstractController { * Prepare a single product review to be inserted into the database. * * @param WP_REST_Request $request Request object. - * @return array|WP_Error $prepared_review + * @return array|\WP_Error $prepared_review */ protected function prepare_item_for_database( $request ) { if ( isset( $request['id'] ) ) { @@ -1032,11 +1032,11 @@ class ProductReviews extends AbstractController { * * @since 3.5.0 * @param int $id Supplied ID. - * @return WP_Comment|WP_Error Comment object if ID is valid, WP_Error otherwise. + * @return WP_Comment|\WP_Error Comment object if ID is valid, \WP_Error otherwise. */ protected function get_review( $id ) { $id = (int) $id; - $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + $error = new \WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce' ), array( 'status' => 404 ) ); if ( 0 >= $id ) { return $error; @@ -1051,7 +1051,7 @@ class ProductReviews extends AbstractController { $post = get_post( (int) $review->comment_post_ID ); if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } } diff --git a/src/RestApi/Version4/Controllers/ProductVariations.php b/src/RestApi/Version4/Controllers/ProductVariations.php index 5df9f81eb1a..66aa74e884a 100644 --- a/src/RestApi/Version4/Controllers/ProductVariations.php +++ b/src/RestApi/Version4/Controllers/ProductVariations.php @@ -53,16 +53,16 @@ class ProductVariations extends Products { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -82,7 +82,7 @@ class ProductVariations extends Products { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -94,13 +94,13 @@ class ProductVariations extends Products { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -124,10 +124,10 @@ class ProductVariations extends Products { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -149,18 +149,18 @@ class ProductVariations extends Products { * Check if a given request has access to update an item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } // Check if variation belongs to the correct parent product. if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -294,7 +294,7 @@ class ProductVariations extends Products { if ( is_wp_error( $upload ) ) { if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $variation->get_id(), array( $image ) ) ) { - throw new WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); + throw new \WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); } } @@ -303,7 +303,7 @@ class ProductVariations extends Products { if ( ! wp_attachment_is_image( $attachment_id ) ) { /* translators: %s: attachment ID */ - throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); } $variation->set_image_id( $attachment_id ); @@ -417,13 +417,13 @@ class ProductVariations extends Products { * * @param WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data + * @return \WP_Error|WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { if ( isset( $request['id'] ) ) { $variation = wc_get_product( absint( $request['id'] ) ); } else { - $variation = new WC_Product_Variation(); + $variation = new \WC_Product_Variation(); } $variation->set_parent_id( absint( $request['product_id'] ) ); @@ -546,7 +546,7 @@ class ProductVariations extends Products { $parent = wc_get_product( $variation->get_parent_id() ); if ( ! $parent ) { - return new WP_Error( + return new \WP_Error( // Translators: %d parent ID. "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $variation->get_parent_id() ), array( 'status' => 404, @@ -636,7 +636,7 @@ class ProductVariations extends Products { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error|WP_REST_Response + * @return bool|\WP_Error|WP_REST_Response */ public function delete_item( $request ) { $force = (bool) $request['force']; @@ -644,7 +644,7 @@ class ProductVariations extends Products { $result = false; if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404, ) @@ -664,7 +664,7 @@ class ProductVariations extends Products { $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - return new WP_Error( + return new \WP_Error( /* translators: %s: post type */ "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code(), @@ -682,7 +682,7 @@ class ProductVariations extends Products { } else { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { - return new WP_Error( + return new \WP_Error( /* translators: %s: post type */ 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501, @@ -693,7 +693,7 @@ class ProductVariations extends Products { // Otherwise, only trash if we haven't already. if ( is_callable( array( $object, 'get_status' ) ) ) { if ( 'trash' === $object->get_status() ) { - return new WP_Error( + return new \WP_Error( /* translators: %s: post type */ 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410, @@ -707,7 +707,7 @@ class ProductVariations extends Products { } if ( ! $result ) { - return new WP_Error( + return new \WP_Error( /* translators: %s: post type */ 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500, @@ -737,7 +737,7 @@ class ProductVariations extends Products { * * @since 3.0.0 * @param WP_REST_Request $request Full details about the request. - * @return array Of WP_Error or WP_REST_Response. + * @return array Of \WP_Error or WP_REST_Response. */ public function batch_items( $request ) { $items = array_filter( $request->get_params() ); @@ -1198,10 +1198,10 @@ class ProductVariations extends Products { } /** - * Get a collection of posts and add the post title filter option to WP_Query. + * Get a collection of posts and add the post title filter option to \WP_Query. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10, 2 ); diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/RestApi/Version4/Controllers/Products.php index df2c7e7fd56..f5ee4bf5167 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -53,16 +53,16 @@ class Products extends AbstractObjectsController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -79,7 +79,7 @@ class Products extends AbstractObjectsController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -91,13 +91,13 @@ class Products extends AbstractObjectsController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -117,10 +117,10 @@ class Products extends AbstractObjectsController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -139,19 +139,60 @@ class Products extends AbstractObjectsController { return wc_get_product( $id ); } + /** + * Prepare a single product output for response. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @since 3.0.0 + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->get_product_data( $object, $context ); + + // Add variations to variable products. + if ( $object->is_type( 'variable' ) && $object->has_child() ) { + $data['variations'] = $object->get_children(); + } + + // Add grouped products data. + if ( $object->is_type( 'grouped' ) && $object->has_child() ) { + $data['grouped_products'] = $object->get_children(); + } + + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + /** * Prepare a single product for create or update. * * @param WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data + * @return \WP_Error|WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; // Type is the most important part here because we need to be using the correct class and methods. if ( isset( $request['type'] ) ) { - $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + $classname = \WC_Product_Factory::get_classname_from_product_type( $request['type'] ); if ( ! class_exists( $classname ) ) { $classname = 'WC_Product_Simple'; @@ -161,11 +202,11 @@ class Products extends AbstractObjectsController { } elseif ( isset( $request['id'] ) ) { $product = wc_get_product( $id ); } else { - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); } if ( 'variation' === $product->get_type() ) { - return new WP_Error( + return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( @@ -285,7 +326,7 @@ class Products extends AbstractObjectsController { if ( ! empty( $values ) ) { // Add attribute to array, but don't set values. - $attribute_object = new WC_Product_Attribute(); + $attribute_object = new \WC_Product_Attribute(); $attribute_object->set_id( $attribute_id ); $attribute_object->set_name( $attribute_name ); $attribute_object->set_options( $values ); @@ -301,7 +342,7 @@ class Products extends AbstractObjectsController { } else { $values = explode( WC_DELIMITER, $attribute['options'] ); } - $attribute_object = new WC_Product_Attribute(); + $attribute_object = new \WC_Product_Attribute(); $attribute_object->set_name( $attribute_name ); $attribute_object->set_options( $values ); $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); @@ -550,10 +591,10 @@ class Products extends AbstractObjectsController { } /** - * Get a collection of posts and add the post title filter option to WP_Query. + * Get a collection of posts and add the post title filter option to \WP_Query. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); @@ -570,7 +611,7 @@ class Products extends AbstractObjectsController { * Add in conditional search filters for products. * * @param string $where Where clause used to search posts. - * @param object $wp_query WP_Query object. + * @param object $wp_query \WP_Query object. * @return string */ public static function add_wp_query_filter( $where, $wp_query ) { @@ -606,7 +647,7 @@ class Products extends AbstractObjectsController { * Join posts meta tables when product search or low stock query is present. * * @param string $join Join clause used to search posts. - * @param object $wp_query WP_Query object. + * @param object $wp_query \WP_Query object. * @return string */ public static function add_wp_query_join( $join, $wp_query ) { @@ -630,7 +671,7 @@ class Products extends AbstractObjectsController { * Group by post ID to prevent duplicates. * * @param string $groupby Group by clause used to organize posts. - * @param object $wp_query WP_Query object. + * @param object $wp_query \WP_Query object. * @return string */ public static function add_wp_query_group_by( $groupby, $wp_query ) { @@ -652,7 +693,7 @@ class Products extends AbstractObjectsController { * @return array */ protected function prepare_objects_query( $request ) { - $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); + $args = parent::prepare_objects_query( $request ); // Set post_status. $args['post_status'] = $request['status']; @@ -1175,7 +1216,7 @@ class Products extends AbstractObjectsController { if ( is_wp_error( $upload ) ) { if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { - throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); } else { continue; } @@ -1186,7 +1227,7 @@ class Products extends AbstractObjectsController { if ( ! wp_attachment_is_image( $attachment_id ) ) { /* translators: %s: image ID */ - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); } $featured_image = $product->get_image_id(); @@ -1288,7 +1329,7 @@ class Products extends AbstractObjectsController { continue; } - $download = new WC_Product_Download(); + $download = new \WC_Product_Download(); $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); @@ -1396,7 +1437,7 @@ class Products extends AbstractObjectsController { * * @param WP_REST_Request $request Full details about the request. * - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -1405,7 +1446,7 @@ class Products extends AbstractObjectsController { $result = false; if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( @@ -1415,7 +1456,7 @@ class Products extends AbstractObjectsController { } if ( 'variation' === $object->get_type() ) { - return new WP_Error( + return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( @@ -1437,7 +1478,7 @@ class Products extends AbstractObjectsController { $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - return new WP_Error( + return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", /* translators: %s: post type */ sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), @@ -1475,7 +1516,7 @@ class Products extends AbstractObjectsController { } else { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { - return new WP_Error( + return new \WP_Error( 'woocommerce_rest_trash_not_supported', /* translators: %s: post type */ sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), @@ -1488,7 +1529,7 @@ class Products extends AbstractObjectsController { // Otherwise, only trash if we haven't already. if ( is_callable( array( $object, 'get_status' ) ) ) { if ( 'trash' === $object->get_status() ) { - return new WP_Error( + return new \WP_Error( 'woocommerce_rest_already_trashed', /* translators: %s: post type */ sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), @@ -1504,7 +1545,7 @@ class Products extends AbstractObjectsController { } if ( ! $result ) { - return new WP_Error( + return new \WP_Error( 'woocommerce_rest_cannot_delete', /* translators: %s: post type */ sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), @@ -2221,7 +2262,7 @@ class Products extends AbstractObjectsController { $params['tax_class'] = array( 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), 'type' => 'string', - 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php index 5ca2d516e75..8893ce02e67 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -32,7 +32,7 @@ class Reports extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -46,11 +46,11 @@ class Reports extends AbstractController { * Check whether a given request has permission to read reports. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -61,68 +61,71 @@ class Reports extends AbstractController { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { - $data = array(); - $reports = array( - array( - 'slug' => 'performance-indicators', - 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce' ), - ), - array( - 'slug' => 'revenue/stats', - 'description' => __( 'Stats about revenue.', 'woocommerce' ), - ), - array( - 'slug' => 'orders/stats', - 'description' => __( 'Stats about orders.', 'woocommerce' ), - ), - array( - 'slug' => 'products', - 'description' => __( 'Products detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'products/stats', - 'description' => __( 'Stats about products.', 'woocommerce' ), - ), - array( - 'slug' => 'categories', - 'description' => __( 'Product categories detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'categories/stats', - 'description' => __( 'Stats about product categories.', 'woocommerce' ), - ), - array( - 'slug' => 'coupons', - 'description' => __( 'Coupons detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'coupons/stats', - 'description' => __( 'Stats about coupons.', 'woocommerce' ), - ), - array( - 'slug' => 'taxes', - 'description' => __( 'Taxes detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'taxes/stats', - 'description' => __( 'Stats about taxes.', 'woocommerce' ), - ), - array( - 'slug' => 'downloads', - 'description' => __( 'Product downloads detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'downloads/stats', - 'description' => __( 'Stats about product downloads.', 'woocommerce' ), - ), - array( - 'slug' => 'customers', - 'description' => __( 'Customers detailed reports.', 'woocommerce' ), - ), - ); + $data = []; + $reports = []; + if ( class_exists( 'WC_Admin_Reports_Sync' ) ) { + $reports = array( + array( + 'slug' => 'performance-indicators', + 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce' ), + ), + array( + 'slug' => 'revenue/stats', + 'description' => __( 'Stats about revenue.', 'woocommerce' ), + ), + array( + 'slug' => 'orders/stats', + 'description' => __( 'Stats about orders.', 'woocommerce' ), + ), + array( + 'slug' => 'products', + 'description' => __( 'Products detailed reports.', 'woocommerce' ), + ), + array( + 'slug' => 'products/stats', + 'description' => __( 'Stats about products.', 'woocommerce' ), + ), + array( + 'slug' => 'categories', + 'description' => __( 'Product categories detailed reports.', 'woocommerce' ), + ), + array( + 'slug' => 'categories/stats', + 'description' => __( 'Stats about product categories.', 'woocommerce' ), + ), + array( + 'slug' => 'coupons', + 'description' => __( 'Coupons detailed reports.', 'woocommerce' ), + ), + array( + 'slug' => 'coupons/stats', + 'description' => __( 'Stats about coupons.', 'woocommerce' ), + ), + array( + 'slug' => 'taxes', + 'description' => __( 'Taxes detailed reports.', 'woocommerce' ), + ), + array( + 'slug' => 'taxes/stats', + 'description' => __( 'Stats about taxes.', 'woocommerce' ), + ), + array( + 'slug' => 'downloads', + 'description' => __( 'Product downloads detailed reports.', 'woocommerce' ), + ), + array( + 'slug' => 'downloads/stats', + 'description' => __( 'Stats about product downloads.', 'woocommerce' ), + ), + array( + 'slug' => 'customers', + 'description' => __( 'Customers detailed reports.', 'woocommerce' ), + ), + ); + } /** * Filter the list of allowed reports, so that data can be loaded from third party extensions in addition to WooCommerce core. diff --git a/src/RestApi/Version4/Controllers/Reports/Categories.php b/src/RestApi/Version4/Controllers/Reports/Categories.php index fa12c0b15f8..987e0a91249 100644 --- a/src/RestApi/Version4/Controllers/Reports/Categories.php +++ b/src/RestApi/Version4/Controllers/Reports/Categories.php @@ -52,11 +52,11 @@ class Categories extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $categories_query = new WC_Admin_Reports_Categories_Query( $query_args ); + $categories_query = new \WC_Admin_Reports_Categories_Query( $query_args ); $report_data = $categories_query->get_data(); if ( is_wp_error( $report_data ) ) { @@ -64,7 +64,7 @@ class Categories extends Reports { } 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 ) ); + return new \WP_Error( 'woocommerce_rest_reports_categories_invalid_response', __( 'Invalid response from data store.', 'woocommerce' ), array( 'status' => 500 ) ); } $out_data = array(); diff --git a/src/RestApi/Version4/Controllers/Reports/CouponStats.php b/src/RestApi/Version4/Controllers/Reports/CouponStats.php index c2fd328f86a..c4cd0ae6450 100644 --- a/src/RestApi/Version4/Controllers/Reports/CouponStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CouponStats.php @@ -50,15 +50,15 @@ class CouponStats extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $coupons_query = new WC_Admin_Reports_Coupons_Stats_Query( $query_args ); + $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() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } $out_data = array( diff --git a/src/RestApi/Version4/Controllers/Reports/Coupons.php b/src/RestApi/Version4/Controllers/Reports/Coupons.php index 73872d44d34..154378ad514 100644 --- a/src/RestApi/Version4/Controllers/Reports/Coupons.php +++ b/src/RestApi/Version4/Controllers/Reports/Coupons.php @@ -48,11 +48,11 @@ class Coupons extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $coupons_query = new WC_Admin_Reports_Coupons_Query( $query_args ); + $coupons_query = new \WC_Admin_Reports_Coupons_Query( $query_args ); $report_data = $coupons_query->get_data(); $data = array(); diff --git a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php index 3ae9ef010e2..5f7d3d28fd1 100644 --- a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php @@ -58,9 +58,9 @@ class CustomerStats extends Reports { $args['customers'] = $request['customers']; $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $normalized_params_numeric = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); + $normalized_params_numeric = \WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); $between_params_date = array( 'last_active', 'registered' ); - $normalized_params_date = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); + $normalized_params_date = \WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); $args = array_merge( $args, $normalized_params_numeric, $normalized_params_date ); return $args; @@ -70,11 +70,11 @@ class CustomerStats extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $customers_query = new WC_Admin_Reports_Customers_Stats_Query( $query_args ); + $customers_query = new \WC_Admin_Reports_Customers_Stats_Query( $query_args ); $report_data = $customers_query->get_data(); $out_data = array( 'totals' => $report_data, diff --git a/src/RestApi/Version4/Controllers/Reports/Customers.php b/src/RestApi/Version4/Controllers/Reports/Customers.php index b732c37dc5c..90f490ccd5c 100644 --- a/src/RestApi/Version4/Controllers/Reports/Customers.php +++ b/src/RestApi/Version4/Controllers/Reports/Customers.php @@ -65,9 +65,9 @@ class Customers extends Reports { $args['customers'] = $request['customers']; $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $normalized_params_numeric = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); + $normalized_params_numeric = \WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); $between_params_date = array( 'last_active', 'registered' ); - $normalized_params_date = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); + $normalized_params_date = \WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); $args = array_merge( $args, $normalized_params_numeric, $normalized_params_date ); return $args; @@ -77,11 +77,11 @@ class Customers extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $customers_query = new WC_Admin_Reports_Customers_Query( $query_args ); + $customers_query = new \WC_Admin_Reports_Customers_Query( $query_args ); $report_data = $customers_query->get_data(); $data = array(); diff --git a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php index 26fbae46b83..0ceb11c5379 100644 --- a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php +++ b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php @@ -57,11 +57,11 @@ class DownloadStats extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $downloads_query = new WC_Admin_Reports_Downloads_Stats_Query( $query_args ); + $downloads_query = new \WC_Admin_Reports_Downloads_Stats_Query( $query_args ); $report_data = $downloads_query->get_data(); $out_data = array( diff --git a/src/RestApi/Version4/Controllers/Reports/Downloads.php b/src/RestApi/Version4/Controllers/Reports/Downloads.php index 9f0c6e56ca8..8b68663f6a0 100644 --- a/src/RestApi/Version4/Controllers/Reports/Downloads.php +++ b/src/RestApi/Version4/Controllers/Reports/Downloads.php @@ -29,7 +29,7 @@ class Downloads extends Reports { * Get items. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $args = array(); @@ -40,7 +40,7 @@ class Downloads extends Reports { } } - $reports = new WC_Admin_Reports_Downloads_Query( $args ); + $reports = new \WC_Admin_Reports_Downloads_Query( $args ); $downloads_data = $reports->get_data(); $data = array(); @@ -103,7 +103,7 @@ class Downloads extends Reports { $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'] ); + $customer = new \WC_Customer( $data['user_id'] ); $response->data['username'] = $customer->get_username(); $response->data['order_number'] = $this->get_order_number( $data['order_id'] ); diff --git a/src/RestApi/Version4/Controllers/Reports/Import.php b/src/RestApi/Version4/Controllers/Reports/Import.php index e6bd5e29f60..2d329136632 100644 --- a/src/RestApi/Version4/Controllers/Reports/Import.php +++ b/src/RestApi/Version4/Controllers/Reports/Import.php @@ -34,7 +34,7 @@ class Import extends Reports { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'import_items' ), 'permission_callback' => array( $this, 'import_permissions_check' ), 'args' => $this->get_import_collection_params(), @@ -47,7 +47,7 @@ class Import extends Reports { '/' . $this->rest_base . '/cancel', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'cancel_import' ), 'permission_callback' => array( $this, 'import_permissions_check' ), ), @@ -59,7 +59,7 @@ class Import extends Reports { '/' . $this->rest_base . '/delete', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'delete_imported_items' ), 'permission_callback' => array( $this, 'import_permissions_check' ), ), @@ -71,7 +71,7 @@ class Import extends Reports { '/' . $this->rest_base . '/status', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_import_status' ), 'permission_callback' => array( $this, 'import_permissions_check' ), ), @@ -83,7 +83,7 @@ class Import extends Reports { '/' . $this->rest_base . '/totals', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_import_totals' ), 'permission_callback' => array( $this, 'import_permissions_check' ), 'args' => $this->get_import_collection_params(), @@ -97,11 +97,11 @@ class Import extends Reports { * 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 + * @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 new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -110,11 +110,11 @@ class Import extends Reports { * Import data based on user request params. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @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'] ); + $import = \WC_Admin_Reports_Sync::regenerate_report_data( $query_args['days'], $query_args['skip_existing'] ); if ( is_wp_error( $import ) ) { $result = array( @@ -227,10 +227,10 @@ class Import extends Reports { * Cancel all queued import actions. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function cancel_import( $request ) { - WC_Admin_Reports_Sync::clear_queued_actions(); + \WC_Admin_Reports_Sync::clear_queued_actions(); $result = array( 'status' => 'success', @@ -247,10 +247,10 @@ class Import extends Reports { * Delete all imported items. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function delete_imported_items( $request ) { - $delete = WC_Admin_Reports_Sync::delete_report_data(); + $delete = \WC_Admin_Reports_Sync::delete_report_data(); if ( is_wp_error( $delete ) ) { $result = array( @@ -274,11 +274,11 @@ class Import extends Reports { * Get the status of the current import. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_import_status( $request ) { $result = array( - 'is_importing' => WC_Admin_Reports_Sync::is_importing(), + '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 ), @@ -296,11 +296,11 @@ class Import extends Reports { * Get the total orders and customers based on user supplied params. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @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'] ); + $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 ); diff --git a/src/RestApi/Version4/Controllers/Reports/OrderStats.php b/src/RestApi/Version4/Controllers/Reports/OrderStats.php index cbe04fff6ac..abd50fe495d 100644 --- a/src/RestApi/Version4/Controllers/Reports/OrderStats.php +++ b/src/RestApi/Version4/Controllers/Reports/OrderStats.php @@ -60,15 +60,15 @@ class OrderStats extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $orders_query = new WC_Admin_Reports_Orders_Stats_Query( $query_args ); + $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() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } $out_data = array( diff --git a/src/RestApi/Version4/Controllers/Reports/Orders.php b/src/RestApi/Version4/Controllers/Reports/Orders.php index 21addc6ce79..50a02acdb10 100644 --- a/src/RestApi/Version4/Controllers/Reports/Orders.php +++ b/src/RestApi/Version4/Controllers/Reports/Orders.php @@ -55,11 +55,11 @@ class Orders extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $orders_query = new WC_Admin_Reports_Orders_Query( $query_args ); + $orders_query = new \WC_Admin_Reports_Orders_Query( $query_args ); $report_data = $orders_query->get_data(); $data = array(); diff --git a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php index 9fd1becb564..ed85445c06c 100644 --- a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php +++ b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php @@ -62,7 +62,7 @@ class PerformanceIndicators extends Reports { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -76,7 +76,7 @@ class PerformanceIndicators extends Reports { '/' . $this->rest_base . '/allowed', array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_allowed_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -103,7 +103,7 @@ class PerformanceIndicators extends Reports { /** * Get information such as allowed stats, stat labels, and endpoint data from stats reports. * - * @return WP_Error|True + * @return \WP_Error|True */ private function get_indicator_data() { // Data already retrieved. @@ -116,7 +116,7 @@ class PerformanceIndicators extends Reports { $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' ) ); + return new \WP_Error( 'woocommerce_reports_performance_indicators_result_failed', __( 'Sorry, fetching performance indicators failed.', 'woocommerce' ) ); } foreach ( $endpoints as $endpoint ) { @@ -156,7 +156,7 @@ class PerformanceIndicators extends Reports { * Returns a list of allowed performance indicators. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_allowed_items( $request ) { $indicator_data = $this->get_indicator_data(); @@ -245,7 +245,7 @@ class PerformanceIndicators extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $indicator_data = $this->get_indicator_data(); @@ -255,7 +255,7 @@ class PerformanceIndicators extends Reports { $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 ); + return new \WP_Error( 'woocommerce_reports_performance_indicators_empty_query', __( 'A list of stats to query must be provided.', 'woocommerce' ), 400 ); } $stats = array(); diff --git a/src/RestApi/Version4/Controllers/Reports/ProductStats.php b/src/RestApi/Version4/Controllers/Reports/ProductStats.php index ec0b82eec0b..1539aa97ea0 100644 --- a/src/RestApi/Version4/Controllers/Reports/ProductStats.php +++ b/src/RestApi/Version4/Controllers/Reports/ProductStats.php @@ -45,7 +45,7 @@ class ProductStats extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = array( @@ -69,11 +69,11 @@ class ProductStats extends Reports { } } - $query = new WC_Admin_Reports_Products_Stats_Query( $query_args ); + $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() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } $out_data = array( @@ -279,9 +279,9 @@ class ProductStats extends Reports { */ public function set_default_report_data( $results ) { if ( empty( $results ) ) { - $results = new stdClass(); + $results = new \stdClass(); $results->total = 0; - $results->totals = new stdClass(); + $results->totals = new \stdClass(); $results->totals->items_sold = 0; $results->totals->net_revenue = 0; $results->totals->orders_count = 0; diff --git a/src/RestApi/Version4/Controllers/Reports/Products.php b/src/RestApi/Version4/Controllers/Reports/Products.php index e9c7622d262..56bc5e6edff 100644 --- a/src/RestApi/Version4/Controllers/Reports/Products.php +++ b/src/RestApi/Version4/Controllers/Reports/Products.php @@ -39,7 +39,7 @@ class Products extends Reports { * * @param WP_REST_Request $request Request data. * - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $args = array(); @@ -54,7 +54,7 @@ class Products extends Reports { } } - $reports = new WC_Admin_Reports_Products_Query( $args ); + $reports = new \WC_Admin_Reports_Products_Query( $args ); $products_data = $reports->get_data(); $data = array(); diff --git a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php index ac15f34cd0c..4e34d6e1fa7 100644 --- a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php +++ b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php @@ -49,15 +49,15 @@ class RevenueStats extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $reports_revenue = new WC_Admin_Reports_Revenue_Query( $query_args ); + $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() ) ); + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } $out_data = array( diff --git a/src/RestApi/Version4/Controllers/Reports/Stock.php b/src/RestApi/Version4/Controllers/Reports/Stock.php index e8e9757474f..df7f798906d 100644 --- a/src/RestApi/Version4/Controllers/Reports/Stock.php +++ b/src/RestApi/Version4/Controllers/Reports/Stock.php @@ -117,14 +117,14 @@ class Stock extends Reports { * @return array */ protected function get_products( $query_args ) { - $query = new WP_Query(); + $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 = new \WP_Query(); $count_query->query( $query_args ); $total_posts = $count_query->found_posts; } @@ -140,7 +140,7 @@ class Stock extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); diff --git a/src/RestApi/Version4/Controllers/Reports/StockStats.php b/src/RestApi/Version4/Controllers/Reports/StockStats.php index 83343e44abc..f9524fe115b 100644 --- a/src/RestApi/Version4/Controllers/Reports/StockStats.php +++ b/src/RestApi/Version4/Controllers/Reports/StockStats.php @@ -29,10 +29,10 @@ class StockStats extends Reports { * Get Stock Status Totals. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { - $stock_query = new WC_Admin_Reports_Stock_Stats_Query(); + $stock_query = new \WC_Admin_Reports_Stock_Stats_Query(); $report_data = $stock_query->get_data(); $out_data = array( 'totals' => $report_data, diff --git a/src/RestApi/Version4/Controllers/Reports/TaxStats.php b/src/RestApi/Version4/Controllers/Reports/TaxStats.php index b93e24fcc45..0d0aa5cc825 100644 --- a/src/RestApi/Version4/Controllers/Reports/TaxStats.php +++ b/src/RestApi/Version4/Controllers/Reports/TaxStats.php @@ -40,9 +40,9 @@ class TaxStats extends Reports { */ public function set_default_report_data( $results ) { if ( empty( $results ) ) { - $results = new stdClass(); + $results = new \stdClass(); $results->total = 0; - $results->totals = new stdClass(); + $results->totals = new \stdClass(); $results->totals->tax_codes = 0; $results->totals->total_tax = 0; $results->totals->order_tax = 0; @@ -80,11 +80,11 @@ class TaxStats extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @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 ); + $taxes_query = new \WC_Admin_Reports_Taxes_Stats_Query( $query_args ); $report_data = $taxes_query->get_data(); $out_data = array( diff --git a/src/RestApi/Version4/Controllers/Reports/Taxes.php b/src/RestApi/Version4/Controllers/Reports/Taxes.php index 49fdfea5b07..6ae0e6ed8fb 100644 --- a/src/RestApi/Version4/Controllers/Reports/Taxes.php +++ b/src/RestApi/Version4/Controllers/Reports/Taxes.php @@ -48,11 +48,11 @@ class Taxes extends Reports { * Get all reports. * * @param WP_REST_Request $request Request data. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $query_args = $this->prepare_reports_query( $request ); - $taxes_query = new WC_Admin_Reports_Taxes_Query( $query_args ); + $taxes_query = new \WC_Admin_Reports_Taxes_Query( $query_args ); $report_data = $taxes_query->get_data(); $data = array(); diff --git a/src/RestApi/Version4/Controllers/Reports/Variations.php b/src/RestApi/Version4/Controllers/Reports/Variations.php index 0b3599ceec8..206272ea1ee 100644 --- a/src/RestApi/Version4/Controllers/Reports/Variations.php +++ b/src/RestApi/Version4/Controllers/Reports/Variations.php @@ -39,7 +39,7 @@ class Variations extends Reports { * * @param WP_REST_Request $request Request data. * - * @return array|WP_Error + * @return array|\WP_Error */ public function get_items( $request ) { $args = array(); @@ -54,7 +54,7 @@ class Variations extends Reports { } } - $reports = new WC_Admin_Reports_Variations_Query( $args ); + $reports = new \WC_Admin_Reports_Variations_Query( $args ); $products_data = $reports->get_data(); $data = array(); diff --git a/src/RestApi/Version4/Controllers/Settings.php b/src/RestApi/Version4/Controllers/Settings.php index 38e59c3fe79..d5c748c2ea3 100644 --- a/src/RestApi/Version4/Controllers/Settings.php +++ b/src/RestApi/Version4/Controllers/Settings.php @@ -34,7 +34,7 @@ class Settings extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -46,7 +46,7 @@ class Settings extends AbstractController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'update_items_permissions_check' ), ), @@ -59,11 +59,11 @@ class Settings extends AbstractController { * 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 + * @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 new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -73,10 +73,10 @@ class Settings extends AbstractController { * Update a setting. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { - $options_controller = new WC_REST_Setting_Options_Controller(); + $options_controller = new \WC_REST_Setting_Options_Controller(); $response = $options_controller->update_item( $request ); return $response; @@ -87,12 +87,12 @@ class Settings extends AbstractController { * * @since 3.0.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); } $defaults = $this->group_defaults(); @@ -204,11 +204,11 @@ class Settings extends AbstractController { * * @since 3.0.0 * @param WP_REST_Request $request Full data about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; diff --git a/src/RestApi/Version4/Controllers/SettingsOptions.php b/src/RestApi/Version4/Controllers/SettingsOptions.php index 6d3437b5e58..d0cd3105ce6 100644 --- a/src/RestApi/Version4/Controllers/SettingsOptions.php +++ b/src/RestApi/Version4/Controllers/SettingsOptions.php @@ -40,7 +40,7 @@ class SettingsOptions extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), @@ -59,10 +59,10 @@ class SettingsOptions extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -83,15 +83,15 @@ class SettingsOptions extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -103,7 +103,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $setting = $this->get_setting( $request['group_id'], $request['id'] ); @@ -122,7 +122,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $settings = $this->get_group_settings( $request['group_id'] ); @@ -148,17 +148,17 @@ class SettingsOptions extends AbstractController { * Get all settings in a group. * * @param string $group_id Group ID. - * @return array|WP_Error + * @return array|\WP_Error */ public function get_group_settings( $group_id ) { if ( empty( $group_id ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $filtered_settings = array(); @@ -171,7 +171,7 @@ class SettingsOptions extends AbstractController { $option = get_option( $option_key[0] ); $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; } else { - $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); + $admin_setting_value = \WC_Admin_Settings::get_option( $option_key, $default ); $setting['value'] = $admin_setting_value; } @@ -235,11 +235,11 @@ class SettingsOptions extends AbstractController { * @since 3.0.0 * @param string $group_id Group ID. * @param string $setting_id Setting ID. - * @return stdClass|WP_Error + * @return stdClass|\WP_Error */ public function get_setting( $group_id, $setting_id ) { if ( empty( $setting_id ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = $this->get_group_settings( $group_id ); @@ -251,13 +251,13 @@ class SettingsOptions extends AbstractController { $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); if ( empty( $array_key ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } $setting = $settings[ $array_key[0] ]; if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( is_wp_error( $setting ) ) { @@ -274,7 +274,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param WP_REST_Request $request Full details about the request. - * @return array Of WP_Error or WP_REST_Response. + * @return array Of \WP_Error or WP_REST_Response. */ public function batch_items( $request ) { // Get the request params. @@ -301,7 +301,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { $setting = $this->get_setting( $request['group_id'], $request['id'] ); @@ -330,7 +330,7 @@ class SettingsOptions extends AbstractController { $update_data = array(); $update_data[ $setting['option_key'] ] = $value; $setting['value'] = $value; - WC_Admin_Settings::save_fields( array( $setting ), $update_data ); + \WC_Admin_Settings::save_fields( array( $setting ), $update_data ); } $response = $this->prepare_item_for_response( $setting, $request ); @@ -383,11 +383,11 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param WP_REST_Request $request Full data about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -398,11 +398,11 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param WP_REST_Request $request Full data about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ 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 new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; diff --git a/src/RestApi/Version4/Controllers/ShippingMethods.php b/src/RestApi/Version4/Controllers/ShippingMethods.php index 01154d3433d..68b30fa2a9e 100644 --- a/src/RestApi/Version4/Controllers/ShippingMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingMethods.php @@ -32,7 +32,7 @@ class ShippingMethods extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -51,7 +51,7 @@ class ShippingMethods extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -67,11 +67,11 @@ class ShippingMethods extends AbstractController { * Check whether a given request has permission to view shipping methods. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -80,11 +80,11 @@ class ShippingMethods extends AbstractController { * Check if a given request has access to read a shipping method. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -93,10 +93,10 @@ class ShippingMethods extends AbstractController { * Get shipping methods. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { - $wc_shipping = WC_Shipping::instance(); + $wc_shipping = \WC_Shipping::instance(); $response = array(); foreach ( $wc_shipping->get_shipping_methods() as $id => $shipping_method ) { $method = $this->prepare_item_for_response( $shipping_method, $request ); @@ -110,13 +110,13 @@ class ShippingMethods extends AbstractController { * Get a single Shipping Method. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function get_item( $request ) { - $wc_shipping = WC_Shipping::instance(); + $wc_shipping = \WC_Shipping::instance(); $methods = $wc_shipping->get_shipping_methods(); if ( empty( $methods[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $method = $methods[ $request['id'] ]; diff --git a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php index 19a9d5c29b3..3f4bf6ac116 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php @@ -31,15 +31,15 @@ class ShippingZoneLocations extends AbstractShippingZonesController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_items' ), 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -50,7 +50,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { * Get all Shipping Zone Locations. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function get_items( $request ) { $zone = $this->get_zone( (int) $request['id'] ); @@ -75,7 +75,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { * Update all Shipping Zone Locations. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function update_items( $request ) { $zone = $this->get_zone( (int) $request['id'] ); @@ -85,7 +85,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { } if ( 0 === $zone->get_id() ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); } $raw_locations = $request->get_json_params(); diff --git a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php index 979026f0948..b90b5aea41e 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php @@ -31,16 +31,16 @@ class ShippingZoneMethods extends AbstractShippingZonesController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'method_id' => array( 'required' => true, @@ -69,18 +69,18 @@ class ShippingZoneMethods extends AbstractShippingZonesController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_items_permissions_check' ), 'args' => array( @@ -100,7 +100,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Get a single Shipping Zone Method. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function get_item( $request ) { $zone = $this->get_zone( $request['zone_id'] ); @@ -121,7 +121,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $method, $request ); @@ -133,7 +133,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Get all Shipping Zone Methods. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function get_items( $request ) { $zone = $this->get_zone( $request['zone_id'] ); @@ -157,7 +157,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Create a new shipping zone method instance. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function create_item( $request ) { $method_id = $request['method_id']; @@ -177,7 +177,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -193,7 +193,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Delete a shipping method instance. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function delete_item( $request ) { $zone = $this->get_zone( $request['zone_id'] ); @@ -215,7 +215,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -230,7 +230,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { if ( $force ) { $zone->delete_shipping_method( $instance_id ); } else { - return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } /** @@ -249,7 +249,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Update A Single Shipping Zone Method. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function update_item( $request ) { $zone = $this->get_zone( $request['zone_id'] ); @@ -269,7 +269,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -314,7 +314,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( $errors_found ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); diff --git a/src/RestApi/Version4/Controllers/ShippingZones.php b/src/RestApi/Version4/Controllers/ShippingZones.php index 5b689046078..c58aa6dd792 100644 --- a/src/RestApi/Version4/Controllers/ShippingZones.php +++ b/src/RestApi/Version4/Controllers/ShippingZones.php @@ -25,16 +25,16 @@ class ShippingZones extends AbstractShippingZonesController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'name' => array( 'required' => true, @@ -59,18 +59,18 @@ class ShippingZones extends AbstractShippingZonesController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_items_permissions_check' ), 'args' => array( @@ -90,7 +90,7 @@ class ShippingZones extends AbstractShippingZonesController { * Get a single Shipping Zone. * * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function get_item( $request ) { $zone = $this->get_zone( $request->get_param( 'id' ) ); @@ -113,9 +113,9 @@ class ShippingZones extends AbstractShippingZonesController { * @return WP_REST_Response */ public function get_items( $request ) { - $rest_of_the_world = WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); + $rest_of_the_world = \WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); - $zones = WC_Shipping_Zones::get_zones(); + $zones = \WC_Shipping_Zones::get_zones(); array_unshift( $zones, $rest_of_the_world->get_data() ); $data = array(); @@ -132,10 +132,10 @@ class ShippingZones extends AbstractShippingZonesController { * Create a single Shipping Zone. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function create_item( $request ) { - $zone = new WC_Shipping_Zone( null ); + $zone = new \WC_Shipping_Zone( null ); if ( ! is_null( $request->get_param( 'name' ) ) ) { $zone->set_zone_name( $request->get_param( 'name' ) ); @@ -154,7 +154,7 @@ class ShippingZones extends AbstractShippingZonesController { $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); return $response; } else { - return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); } } @@ -162,7 +162,7 @@ class ShippingZones extends AbstractShippingZonesController { * Update a single Shipping Zone. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function update_item( $request ) { $zone = $this->get_zone( $request->get_param( 'id' ) ); @@ -172,7 +172,7 @@ class ShippingZones extends AbstractShippingZonesController { } if ( 0 === $zone->get_id() ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); } $zone_changed = false; @@ -198,7 +198,7 @@ class ShippingZones extends AbstractShippingZonesController { * Delete a single Shipping Zone. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error + * @return WP_REST_Request|\WP_Error */ public function delete_item( $request ) { $zone = $this->get_zone( $request->get_param( 'id' ) ); @@ -214,7 +214,7 @@ class ShippingZones extends AbstractShippingZonesController { if ( $force ) { $zone->delete(); } else { - return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } return $response; diff --git a/src/RestApi/Version4/Controllers/SystemStatus.php b/src/RestApi/Version4/Controllers/SystemStatus.php index de3298cd846..569f7814d31 100644 --- a/src/RestApi/Version4/Controllers/SystemStatus.php +++ b/src/RestApi/Version4/Controllers/SystemStatus.php @@ -32,7 +32,7 @@ class SystemStatus extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -46,11 +46,11 @@ class SystemStatus extends AbstractController { * Check whether a given request has permission to view system status. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @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 new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -59,7 +59,7 @@ class SystemStatus extends AbstractController { * Get a system status info, by section. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $schema = $this->get_item_schema(); @@ -767,7 +767,7 @@ class SystemStatus extends AbstractController { return array( 'wc_database_version' => get_option( 'woocommerce_db_version' ), 'database_prefix' => $wpdb->prefix, - 'maxmind_geoip_database' => WC_Geolocation::get_local_database_path(), + 'maxmind_geoip_database' => \WC_Geolocation::get_local_database_path(), 'database_tables' => $tables, 'database_size' => $database_size, ); @@ -934,7 +934,7 @@ class SystemStatus extends AbstractController { $parent_theme_info = array( 'parent_name' => $parent_theme->name, 'parent_version' => $parent_theme->version, - 'parent_version_latest' => WC_Admin_Status::get_latest_theme_version( $parent_theme ), + 'parent_version_latest' => \WC_Admin_Status::get_latest_theme_version( $parent_theme ), 'parent_author_url' => $parent_theme->{'Author URI'}, ); } else { @@ -952,7 +952,7 @@ class SystemStatus extends AbstractController { */ $override_files = array(); $outdated_templates = false; - $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); + $scan_files = \WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); foreach ( $scan_files as $file ) { $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' ); @@ -971,8 +971,8 @@ class SystemStatus extends AbstractController { } if ( ! empty( $theme_file ) ) { - $core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); - $theme_version = WC_Admin_Status::get_file_version( $theme_file ); + $core_version = \WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); + $theme_version = \WC_Admin_Status::get_file_version( $theme_file ); if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { if ( ! $outdated_templates ) { $outdated_templates = true; @@ -989,7 +989,7 @@ class SystemStatus extends AbstractController { $active_theme_info = array( 'name' => $active_theme->name, 'version' => $active_theme->version, - 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ), + 'version_latest' => \WC_Admin_Status::get_latest_theme_version( $active_theme ), 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), 'is_child_theme' => is_child_theme(), 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), diff --git a/src/RestApi/Version4/Controllers/SystemStatusTools.php b/src/RestApi/Version4/Controllers/SystemStatusTools.php index d60944a7ef1..e2cb1017058 100644 --- a/src/RestApi/Version4/Controllers/SystemStatusTools.php +++ b/src/RestApi/Version4/Controllers/SystemStatusTools.php @@ -32,7 +32,7 @@ class SystemStatusTools extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), @@ -52,15 +52,15 @@ class SystemStatusTools extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -71,11 +71,11 @@ class SystemStatusTools extends AbstractController { * Check whether a given request has permission to view system status tools. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @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 new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -84,11 +84,11 @@ class SystemStatusTools extends AbstractController { * Check whether a given request has permission to view a specific system status tool. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @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 view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -97,11 +97,11 @@ class SystemStatusTools extends AbstractController { * Check whether a given request has permission to execute a specific system status tool. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -204,7 +204,7 @@ class SystemStatusTools extends AbstractController { * Get a list of system status tools. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $tools = array(); @@ -230,12 +230,12 @@ class SystemStatusTools extends AbstractController { * Return a single tool. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $tools = $this->get_tools(); if ( empty( $tools[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tool = $tools[ $request['id'] ]; return rest_ensure_response( @@ -255,12 +255,12 @@ class SystemStatusTools extends AbstractController { * Update (execute) a tool. * * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { $tools = $this->get_tools(); if ( empty( $tools[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tool = $tools[ $request['id'] ]; @@ -420,7 +420,7 @@ class SystemStatusTools extends AbstractController { } } - WC_Cache_Helper::get_transient_version( 'shipping', true ); + \WC_Cache_Helper::get_transient_version( 'shipping', true ); $message = __( 'Product transients cleared', 'woocommerce' ); break; @@ -466,8 +466,8 @@ class SystemStatusTools extends AbstractController { break; case 'reset_roles': // Remove then re-add caps and roles. - WC_Install::remove_roles(); - WC_Install::create_roles(); + \WC_Install::remove_roles(); + \WC_Install::create_roles(); $message = __( 'Roles successfully reset', 'woocommerce' ); break; @@ -500,19 +500,19 @@ class SystemStatusTools extends AbstractController { break; case 'install_pages': - WC_Install::create_pages(); + \WC_Install::create_pages(); $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); break; case 'delete_taxes': $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); - WC_Cache_Helper::incr_cache_prefix( 'taxes' ); + \WC_Cache_Helper::incr_cache_prefix( 'taxes' ); $message = __( 'Tax rates successfully deleted', 'woocommerce' ); break; case 'regenerate_thumbnails': - WC_Regenerate_Images::queue_image_regeneration(); + \WC_Regenerate_Images::queue_image_regeneration(); $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); break; diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/RestApi/Version4/Controllers/TaxClasses.php index fd31c64b14c..408bc2e3e74 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -32,16 +32,16 @@ class TaxClasses extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -58,7 +58,7 @@ class TaxClasses extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -78,11 +78,11 @@ class TaxClasses extends AbstractController { * Check whether a given request has permission to read tax classes. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -93,11 +93,11 @@ class TaxClasses extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -108,11 +108,11 @@ class TaxClasses extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -133,7 +133,7 @@ class TaxClasses extends AbstractController { 'name' => __( 'Standard rate', 'woocommerce' ), ); - $classes = WC_Tax::get_tax_classes(); + $classes = \WC_Tax::get_tax_classes(); foreach ( $classes as $class ) { $tax_classes[] = array( @@ -156,11 +156,11 @@ class TaxClasses extends AbstractController { * Create a single tax. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { $exists = false; - $classes = WC_Tax::get_tax_classes(); + $classes = \WC_Tax::get_tax_classes(); $tax_class = array( 'slug' => sanitize_title( $request['name'] ), 'name' => $request['name'], @@ -176,7 +176,7 @@ class TaxClasses extends AbstractController { // Return error if tax class already exists. if ( $exists ) { - return new WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); } // Add the new class. @@ -208,7 +208,7 @@ class TaxClasses extends AbstractController { * Delete a single tax class. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function delete_item( $request ) { global $wpdb; @@ -217,14 +217,14 @@ class TaxClasses extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $tax_class = array( 'slug' => sanitize_title( $request['slug'] ), 'name' => '', ); - $classes = WC_Tax::get_tax_classes(); + $classes = \WC_Tax::get_tax_classes(); $deleted = false; foreach ( $classes as $key => $class ) { @@ -237,7 +237,7 @@ class TaxClasses extends AbstractController { } if ( ! $deleted ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); } update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); diff --git a/src/RestApi/Version4/Controllers/Taxes.php b/src/RestApi/Version4/Controllers/Taxes.php index a0d0387bd1a..3617d63129a 100644 --- a/src/RestApi/Version4/Controllers/Taxes.php +++ b/src/RestApi/Version4/Controllers/Taxes.php @@ -32,16 +32,16 @@ class Taxes extends AbstractController { '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) @@ -58,7 +58,7 @@ class Taxes extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -66,13 +66,13 @@ class Taxes extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -92,10 +92,10 @@ class Taxes extends AbstractController { '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) @@ -106,11 +106,11 @@ class Taxes extends AbstractController { * Check whether a given request has permission to read taxes. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -121,11 +121,11 @@ class Taxes extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -135,11 +135,11 @@ class Taxes extends AbstractController { * Check if a given request has access to read a tax. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -150,11 +150,11 @@ class Taxes extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -165,11 +165,11 @@ class Taxes extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -180,11 +180,11 @@ class Taxes extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -194,7 +194,7 @@ class Taxes extends AbstractController { * Get all taxes and allow filtering by tax code. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { global $wpdb; @@ -353,31 +353,31 @@ class Taxes extends AbstractController { } if ( $id ) { - WC_Tax::_update_tax_rate( $id, $data ); + \WC_Tax::_update_tax_rate( $id, $data ); } else { - $id = WC_Tax::_insert_tax_rate( $data ); + $id = \WC_Tax::_insert_tax_rate( $data ); } // Add locales. if ( ! empty( $request['postcode'] ) ) { - WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) ); + \WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) ); } if ( ! empty( $request['city'] ) ) { - WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) ); + \WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) ); } - return WC_Tax::_get_tax_rate( $id, OBJECT ); + return \WC_Tax::_get_tax_rate( $id, OBJECT ); } /** * Create a single tax. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); } $tax = $this->create_or_update_tax( $request ); @@ -406,14 +406,14 @@ class Taxes extends AbstractController { * Get a single tax. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; - $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); + $tax_obj = \WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tax = $this->prepare_item_for_response( $tax_obj, $request ); @@ -426,14 +426,14 @@ class Taxes extends AbstractController { * Update a single tax. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { $id = (int) $request['id']; - $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); + $tax_obj = \WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tax = $this->create_or_update_tax( $request, $tax_obj ); @@ -460,7 +460,7 @@ class Taxes extends AbstractController { * Delete a single tax. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function delete_item( $request ) { global $wpdb; @@ -470,22 +470,22 @@ class Taxes extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } - $tax = WC_Tax::_get_tax_rate( $id, OBJECT ); + $tax = \WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); } $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $tax, $request ); - WC_Tax::_delete_tax_rate( $id ); + \WC_Tax::_delete_tax_rate( $id ); if ( 0 === $wpdb->rows_affected ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -656,7 +656,7 @@ class Taxes extends AbstractController { 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'default' => 'standard', - 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), 'context' => array( 'view', 'edit' ), ), ), @@ -719,7 +719,7 @@ class Taxes extends AbstractController { ); $params['class'] = array( 'description' => __( 'Sort by tax class.', 'woocommerce' ), - 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), 'sanitize_callback' => 'sanitize_title', 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/RestApi/Version4/Controllers/Webhooks.php b/src/RestApi/Version4/Controllers/Webhooks.php index 3a8989654ba..27c41c09a0b 100644 --- a/src/RestApi/Version4/Controllers/Webhooks.php +++ b/src/RestApi/Version4/Controllers/Webhooks.php @@ -36,16 +36,16 @@ class Webhooks extends AbstractController { public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( - 'methods' => WP_REST_Server::CREATABLE, + 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'topic' => array( 'required' => true, 'type' => 'string', @@ -69,7 +69,7 @@ class Webhooks extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::READABLE, + 'methods' => \WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( @@ -77,13 +77,13 @@ class Webhooks extends AbstractController { ), ), array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( - 'methods' => WP_REST_Server::DELETABLE, + 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( @@ -99,10 +99,10 @@ class Webhooks extends AbstractController { register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( array( - 'methods' => WP_REST_Server::EDITABLE, + 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), ) ); @@ -112,11 +112,11 @@ class Webhooks extends AbstractController { * Check whether a given request has permission to read webhooks. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -127,11 +127,11 @@ class Webhooks extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -141,11 +141,11 @@ class Webhooks extends AbstractController { * Check if a given request has access to read a webhook. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean + * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -156,11 +156,11 @@ class Webhooks extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -171,11 +171,11 @@ class Webhooks extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -186,11 +186,11 @@ class Webhooks extends AbstractController { * * @param WP_REST_Request $request Full details about the request. * - * @return bool|WP_Error + * @return bool|\WP_Error */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -210,7 +210,7 @@ class Webhooks extends AbstractController { * Get all webhooks. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { $args = array(); @@ -240,7 +240,7 @@ class Webhooks extends AbstractController { // Get the webhooks. $webhooks = array(); - $data_store = WC_Data_Store::load( 'webhook' ); + $data_store = \WC_Data_Store::load( 'webhook' ); $results = $data_store->search_webhooks( $prepared_args ); $webhook_ids = $results->webhooks; @@ -280,13 +280,13 @@ class Webhooks extends AbstractController { * Get a single item. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; if ( empty( $id ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $id, $request ); @@ -299,22 +299,22 @@ class Webhooks extends AbstractController { * Create a single webhook. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } // Validate topic. if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); } // Validate delivery URL. if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -322,7 +322,7 @@ class Webhooks extends AbstractController { return $post; } - $webhook = new WC_Webhook(); + $webhook = new \WC_Webhook(); $webhook->set_name( $post->post_title ); $webhook->set_user_id( $post->post_author ); $webhook->set_status( 'publish' === $post->post_status ? 'active' : 'disabled' ); @@ -359,14 +359,14 @@ class Webhooks extends AbstractController { * Update a single webhook. * * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response + * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { $id = (int) $request['id']; $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } // Update topic. @@ -374,7 +374,7 @@ class Webhooks extends AbstractController { if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { $webhook->set_topic( $request['topic'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -383,7 +383,7 @@ class Webhooks extends AbstractController { if ( wc_is_valid_url( $request['delivery_url'] ) ) { $webhook->set_delivery_url( $request['delivery_url'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -397,7 +397,7 @@ class Webhooks extends AbstractController { if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { $webhook->set_status( $request['status'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -433,7 +433,7 @@ class Webhooks extends AbstractController { * Delete a single webhook. * * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error + * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -441,13 +441,13 @@ class Webhooks extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); @@ -456,7 +456,7 @@ class Webhooks extends AbstractController { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -475,10 +475,10 @@ class Webhooks extends AbstractController { * Prepare a single webhook for create or update. * * @param WP_REST_Request $request Request object. - * @return WP_Error|stdClass $data Post object. + * @return \WP_Error|stdClass $data Post object. */ protected function prepare_item_for_database( $request ) { - $data = new stdClass; + $data = new \stdClass; // Post ID. if ( isset( $request['id'] ) ) { @@ -535,7 +535,7 @@ class Webhooks extends AbstractController { $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } $data = array( diff --git a/src/RestApi/Version4/Main.php b/src/RestApi/Version4/Main.php new file mode 100644 index 00000000000..05ef9993fe4 --- /dev/null +++ b/src/RestApi/Version4/Main.php @@ -0,0 +1,93 @@ + __NAMESPACE__ . '\Controllers\Coupons', + 'customer-downloads' => __NAMESPACE__ . '\Controllers\CustomerDownloads', + 'customers' => __NAMESPACE__ . '\Controllers\Customers', + 'data' => __NAMESPACE__ . '\Controllers\Data', + 'data-continents' => __NAMESPACE__ . '\Controllers\Data\Continents', + 'data-countries' => __NAMESPACE__ . '\Controllers\Data\Countries', + 'data-currencies' => __NAMESPACE__ . '\Controllers\Data\Currencies', + 'data-download-ips' => __NAMESPACE__ . '\Controllers\Data\DownloadIPs', + 'leaderboards' => __NAMESPACE__ . '\Controllers\Leaderboards', + 'network-orders' => __NAMESPACE__ . '\Controllers\NetworkOrders', + 'order-notes' => __NAMESPACE__ . '\Controllers\OrderNotes', + 'order-refunds' => __NAMESPACE__ . '\Controllers\OrderRefunds', + 'orders' => __NAMESPACE__ . '\Controllers\Orders', + 'payment-gateways' => __NAMESPACE__ . '\Controllers\PaymentGateways', + 'product-attributes' => __NAMESPACE__ . '\Controllers\ProductAttributes', + 'product-attribute-terms' => __NAMESPACE__ . '\Controllers\ProductAttributeTerms', + 'product-categories' => __NAMESPACE__ . '\Controllers\ProductCategories', + 'product-reviews' => __NAMESPACE__ . '\Controllers\ProductReviews', + 'products' => __NAMESPACE__ . '\Controllers\Products', + 'product-shipping-classes' => __NAMESPACE__ . '\Controllers\ProductShippingClasses', + 'product-tags' => __NAMESPACE__ . '\Controllers\ProductTags', + 'product-variations' => __NAMESPACE__ . '\Controllers\ProductVariations', + 'reports' => __NAMESPACE__ . '\Controllers\Reports', + 'settings' => __NAMESPACE__ . '\Controllers\Settings', + 'settings-options' => __NAMESPACE__ . '\Controllers\SettingsOptions', + 'shipping-methods' => __NAMESPACE__ . '\Controllers\ShippingMethods', + 'shipping-zone-locations' => __NAMESPACE__ . '\Controllers\ShippingZoneLocations', + 'shipping-zone-methods' => __NAMESPACE__ . '\Controllers\ShippingZoneMethods', + 'shipping-zones' => __NAMESPACE__ . '\Controllers\ShippingZones', + 'system-status' => __NAMESPACE__ . '\Controllers\SystemStatus', + 'system-status-tools' => __NAMESPACE__ . '\Controllers\SystemStatusTools', + 'tax-classes' => __NAMESPACE__ . '\Controllers\TaxClasses', + 'taxes' => __NAMESPACE__ . '\Controllers\Taxes', + 'webhooks' => __NAMESPACE__ . '\Controllers\Webhooks', + ]; + + if ( class_exists( 'WC_Admin_Onboarding' ) ) { + $controllers['onboarding-levels'] = __NAMESPACE__ . '\Controllers\Onboarding\Levels'; + $controllers['onboarding-plugins'] = __NAMESPACE__ . '\Controllers\Onboarding\Plugins'; + $controllers['onboarding-profile'] = __NAMESPACE__ . '\Controllers\Onboarding\Profile'; + } + + if ( class_exists( 'WC_Admin_Reports_Sync' ) ) { + $controllers['reports-categories'] = __NAMESPACE__ . '\Controllers\Reports\Categories'; + $controllers['reports-coupons'] = __NAMESPACE__ . '\Controllers\Reports\Coupons'; + $controllers['reports-coupon-stats'] = __NAMESPACE__ . '\Controllers\Reports\CouponStats'; + $controllers['reports-customers'] = __NAMESPACE__ . '\Controllers\Reports\Customers'; + $controllers['reports-customer-stats'] = __NAMESPACE__ . '\Controllers\Reports\CustomerStats'; + $controllers['reports-downloads'] = __NAMESPACE__ . '\Controllers\Reports\Downloads'; + $controllers['reports-download-stats'] = __NAMESPACE__ . '\Controllers\Reports\DownloadStats'; + $controllers['reports-import'] = __NAMESPACE__ . '\Controllers\Reports\Import'; + $controllers['reports-orders'] = __NAMESPACE__ . '\Controllers\Reports\Orders'; + $controllers['reports-order-stats'] = __NAMESPACE__ . '\Controllers\Reports\OrderStats'; + $controllers['reports-performance-indicators'] = __NAMESPACE__ . '\Controllers\Reports\PerformanceIndicators'; + $controllers['reports-products'] = __NAMESPACE__ . '\Controllers\Reports\Products'; + $controllers['reports-product-stats'] = __NAMESPACE__ . '\Controllers\Reports\ProductStats'; + $controllers['reports-revenue-stats'] = __NAMESPACE__ . '\Controllers\Reports\RevenueStats'; + $controllers['reports-stock'] = __NAMESPACE__ . '\Controllers\Reports\Stock'; + $controllers['reports-stock-stats'] = __NAMESPACE__ . '\Controllers\Reports\StockStats'; + $controllers['reports-taxes'] = __NAMESPACE__ . '\Controllers\Reports\Taxes'; + $controllers['reports-tax-stats'] = __NAMESPACE__ . '\Controllers\Reports\TaxStats'; + $controllers['reports-variations'] = __NAMESPACE__ . '\Controllers\Reports\Variations'; + } + + return $controllers; + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index cc30854ff9e..e83246ceec3 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -106,5 +106,67 @@ return array( 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php', 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php', 'WooCommerce\\RestApi' => $baseDir . '/src/RestApi.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractController.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractObjectsController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractObjectsController.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractPostsController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractPostsController.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractShippingZonesController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractTermsContoller' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractTermsContoller.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Coupons' => $baseDir . '/src/RestApi/Version4/Controllers/Coupons.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\CustomerDownloads' => $baseDir . '/src/RestApi/Version4/Controllers/CustomerDownloads.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Customers' => $baseDir . '/src/RestApi/Version4/Controllers/Customers.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data' => $baseDir . '/src/RestApi/Version4/Controllers/Data.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Continents' => $baseDir . '/src/RestApi/Version4/Controllers/Data/Continents.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Countries' => $baseDir . '/src/RestApi/Version4/Controllers/Data/Countries.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Currencies' => $baseDir . '/src/RestApi/Version4/Controllers/Data/Currencies.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\DownloadIPs' => $baseDir . '/src/RestApi/Version4/Controllers/Data/DownloadIPs.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Leaderboards' => $baseDir . '/src/RestApi/Version4/Controllers/Leaderboards.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\NetworkOrders' => $baseDir . '/src/RestApi/Version4/Controllers/NetworkOrders.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Levels' => $baseDir . '/src/RestApi/Version4/Controllers/Onboarding/Levels.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Plugins' => $baseDir . '/src/RestApi/Version4/Controllers/Onboarding/Plugins.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Profile' => $baseDir . '/src/RestApi/Version4/Controllers/Onboarding/Profile.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\OrderNotes' => $baseDir . '/src/RestApi/Version4/Controllers/OrderNotes.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\OrderRefunds' => $baseDir . '/src/RestApi/Version4/Controllers/OrderRefunds.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Orders' => $baseDir . '/src/RestApi/Version4/Controllers/Orders.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\PaymentGateways' => $baseDir . '/src/RestApi/Version4/Controllers/PaymentGateways.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductAttributeTerms' => $baseDir . '/src/RestApi/Version4/Controllers/ProductAttributeTerms.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductAttributes' => $baseDir . '/src/RestApi/Version4/Controllers/ProductAttributes.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductCategories' => $baseDir . '/src/RestApi/Version4/Controllers/ProductCategories.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductReviews' => $baseDir . '/src/RestApi/Version4/Controllers/ProductReviews.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductShippingClasses' => $baseDir . '/src/RestApi/Version4/Controllers/ProductShippingClasses.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductTags' => $baseDir . '/src/RestApi/Version4/Controllers/ProductTags.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductVariations' => $baseDir . '/src/RestApi/Version4/Controllers/ProductVariations.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Products' => $baseDir . '/src/RestApi/Version4/Controllers/Products.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports' => $baseDir . '/src/RestApi/Version4/Controllers/Reports.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Categories' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Categories.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\CouponStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/CouponStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Coupons' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Coupons.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\CustomerStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/CustomerStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Customers' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Customers.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\DownloadStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/DownloadStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Downloads' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Downloads.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Import' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Import.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\OrderStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/OrderStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Orders' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Orders.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\PerformanceIndicators' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\ProductStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/ProductStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Products' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Products.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\RevenueStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/RevenueStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Stock' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Stock.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\StockStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/StockStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\TaxStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/TaxStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Taxes' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Taxes.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Variations' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Variations.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Settings' => $baseDir . '/src/RestApi/Version4/Controllers/Settings.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\SettingsOptions' => $baseDir . '/src/RestApi/Version4/Controllers/SettingsOptions.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingMethods' => $baseDir . '/src/RestApi/Version4/Controllers/ShippingMethods.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZoneLocations' => $baseDir . '/src/RestApi/Version4/Controllers/ShippingZoneLocations.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZoneMethods' => $baseDir . '/src/RestApi/Version4/Controllers/ShippingZoneMethods.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZones' => $baseDir . '/src/RestApi/Version4/Controllers/ShippingZones.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\SystemStatus' => $baseDir . '/src/RestApi/Version4/Controllers/SystemStatus.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\SystemStatusTools' => $baseDir . '/src/RestApi/Version4/Controllers/SystemStatusTools.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\TaxClasses' => $baseDir . '/src/RestApi/Version4/Controllers/TaxClasses.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Taxes' => $baseDir . '/src/RestApi/Version4/Controllers/Taxes.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Webhooks' => $baseDir . '/src/RestApi/Version4/Controllers/Webhooks.php', + 'WooCommerce\\RestApi\\Version4\\Main' => $baseDir . '/src/RestApi/Version4/Main.php', 'WooCommerce\\Utilities\\SingletonTrait' => $baseDir . '/src/Utilities/SingletonTrait.php', ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index d9c3939a6fa..06084faceb3 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -107,6 +107,68 @@ class ComposerStaticInitf71e7bc9895f702f48d84a180f514421 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php', 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php', 'WooCommerce\\RestApi' => __DIR__ . '/../..' . '/src/RestApi.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractController.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractObjectsController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractObjectsController.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractPostsController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractPostsController.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractShippingZonesController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractTermsContoller' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractTermsContoller.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Coupons' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Coupons.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\CustomerDownloads' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/CustomerDownloads.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Customers' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Customers.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Continents' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data/Continents.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Countries' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data/Countries.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Currencies' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data/Currencies.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\DownloadIPs' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data/DownloadIPs.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Leaderboards' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Leaderboards.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\NetworkOrders' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/NetworkOrders.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Levels' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Onboarding/Levels.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Plugins' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Onboarding/Plugins.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Profile' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Onboarding/Profile.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\OrderNotes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/OrderNotes.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\OrderRefunds' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/OrderRefunds.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Orders' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Orders.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\PaymentGateways' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/PaymentGateways.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductAttributeTerms' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductAttributeTerms.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductAttributes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductAttributes.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductCategories' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductCategories.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductReviews' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductReviews.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductShippingClasses' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductShippingClasses.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductTags' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductTags.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductVariations' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductVariations.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Products' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Products.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Categories' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Categories.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\CouponStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/CouponStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Coupons' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Coupons.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\CustomerStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/CustomerStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Customers' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Customers.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\DownloadStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/DownloadStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Downloads' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Downloads.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Import' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Import.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\OrderStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/OrderStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Orders' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Orders.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\PerformanceIndicators' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\ProductStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/ProductStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Products' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Products.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\RevenueStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/RevenueStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Stock' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Stock.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\StockStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/StockStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\TaxStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/TaxStats.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Taxes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Taxes.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Variations' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Variations.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Settings' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Settings.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\SettingsOptions' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/SettingsOptions.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingMethods' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ShippingMethods.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZoneLocations' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ShippingZoneLocations.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZoneMethods' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ShippingZoneMethods.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZones' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ShippingZones.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\SystemStatus' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/SystemStatus.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\SystemStatusTools' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/SystemStatusTools.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\TaxClasses' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/TaxClasses.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Taxes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Taxes.php', + 'WooCommerce\\RestApi\\Version4\\Controllers\\Webhooks' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Webhooks.php', + 'WooCommerce\\RestApi\\Version4\\Main' => __DIR__ . '/../..' . '/src/RestApi/Version4/Main.php', 'WooCommerce\\Utilities\\SingletonTrait' => __DIR__ . '/../..' . '/src/Utilities/SingletonTrait.php', ); diff --git a/version.php b/version.php index bd963c406c1..7299ee74106 100644 --- a/version.php +++ b/version.php @@ -5,4 +5,4 @@ * @package WooCommerce/RestApi */ -return '1.1.0'; +return '1.1.1'; From 13b18a421114c864f9f7c68445dadfcb3ff3c0d8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 30 May 2019 18:23:39 +0100 Subject: [PATCH 047/440] Update all other namespaces --- src/RestApi.php | 140 +++--------------- .../class-wc-rest-blocks-controllers.php | 27 ++++ .../Version1/class-wc-rest-controllers-v1.php | 43 ++++++ .../Version2/class-wc-rest-controllers-v2.php | 54 +++++++ .../Version3/class-wc-rest-controllers-v3.php | 62 ++++++++ .../Version4/{Main.php => Controllers.php} | 10 +- vendor/composer/autoload_classmap.php | 6 +- vendor/composer/autoload_static.php | 6 +- 8 files changed, 221 insertions(+), 127 deletions(-) create mode 100644 src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php create mode 100644 src/RestApi/Version1/class-wc-rest-controllers-v1.php create mode 100644 src/RestApi/Version2/class-wc-rest-controllers-v2.php create mode 100644 src/RestApi/Version3/class-wc-rest-controllers-v3.php rename src/RestApi/Version4/{Main.php => Controllers.php} (97%) diff --git a/src/RestApi.php b/src/RestApi.php index 1ef51a91e66..d2d23678d84 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -40,7 +40,7 @@ class RestApi { */ public function register_rest_routes() { foreach ( $this->get_rest_namespaces() as $namespace => $namespace_class ) { - $controllers = $namespace_class::instance()->get_controllers(); + $controllers = $namespace_class::get_controllers(); foreach ( $controllers as $controller_name => $controller_class ) { $this->endpoints[ $namespace ][ $controller_name ] = new $controller_class(); @@ -52,132 +52,36 @@ class RestApi { /** * Get API namespaces - new namespaces should be registered here. * - * @return array + * @return array List of Namespaces and Main controller classes. */ protected function get_rest_namespaces() { return [ - //'wc/v1', - //'wc/v2', - 'wc/v3' => '\WooCommerce\RestApi\Version4\Main', - //'wc-blocks/v1', + 'wc/v1' => 'WC_REST_Controllers_V1', + 'wc/v2' => 'WC_REST_Controllers_V2', + 'wc/v3' => 'WC_REST_Controllers_V3', + 'wc/v4' => '\WooCommerce\RestApi\Version4\Controllers', + 'wc-blocks/v1' => 'WC_REST_Blocks_Controllers', ]; } /** - * Get API controllers - new controllers/endpoints should be registered here. + * Get data from a WooCommerce API endpoint. * - * @param string $namespace Namespace to get controllers for. - * @return array + * @param string $endpoint Endpoint. + * @param array $params Params to passwith request. + * @return array|WP_Error */ - protected function get_rest_controllers( $namespace ) { - switch ( $namespace ) { - case 'wc/v1': - return [ - 'WC_REST_Coupons_V1_Controller', - 'WC_REST_Customer_Downloads_V1_Controller', - 'WC_REST_Customers_V1_Controller', - 'WC_REST_Order_Notes_V1_Controller', - 'WC_REST_Order_Refunds_V1_Controller', - 'WC_REST_Orders_V1_Controller', - 'WC_REST_Product_Attribute_Terms_V1_Controller', - 'WC_REST_Product_Attributes_V1_Controller', - 'WC_REST_Product_Categories_V1_Controller', - 'WC_REST_Product_Reviews_V1_Controller', - 'WC_REST_Product_Shipping_Classes_V1_Controller', - 'WC_REST_Product_Tags_V1_Controller', - 'WC_REST_Products_V1_Controller', - 'WC_REST_Report_Sales_V1_Controller', - 'WC_REST_Report_Top_Sellers_V1_Controller', - 'WC_REST_Reports_V1_Controller', - 'WC_REST_Tax_Classes_V1_Controller', - 'WC_REST_Taxes_V1_Controller', - 'WC_REST_Webhook_Deliveries_V1_Controller', - 'WC_REST_Webhooks_V1_Controller', - ]; - case 'wc/v2': - return [ - 'WC_REST_Coupons_V2_Controller', - 'WC_REST_Customer_Downloads_V2_Controller', - 'WC_REST_Customers_V2_Controller', - 'WC_REST_Network_Orders_V2_Controller', - 'WC_REST_Order_Notes_V2_Controller', - 'WC_REST_Order_Refunds_V2_Controller', - 'WC_REST_Orders_V2_Controller', - 'WC_REST_Product_Attribute_Terms_V2_Controller', - 'WC_REST_Product_Attributes_V2_Controller', - 'WC_REST_Product_Categories_V2_Controller', - 'WC_REST_Product_Reviews_V2_Controller', - 'WC_REST_Product_Shipping_Classes_V2_Controller', - 'WC_REST_Product_Tags_V2_Controller', - 'WC_REST_Products_V2_Controller', - 'WC_REST_Product_Variations_V2_Controller', - 'WC_REST_Report_Sales_V2_Controller', - 'WC_REST_Report_Top_Sellers_V2_Controller', - 'WC_REST_Reports_V2_Controller', - 'WC_REST_Settings_V2_Controller', - 'WC_REST_Setting_Options_V2_Controller', - 'WC_REST_Shipping_Zones_V2_Controller', - 'WC_REST_Shipping_Zone_Locations_V2_Controller', - 'WC_REST_Shipping_Zone_Methods_V2_Controller', - 'WC_REST_Tax_Classes_V2_Controller', - 'WC_REST_Taxes_V2_Controller', - 'WC_REST_Webhook_Deliveries_V2_Controller', - 'WC_REST_Webhooks_V2_Controller', - 'WC_REST_System_Status_V2_Controller', - 'WC_REST_System_Status_Tools_V2_Controller', - 'WC_REST_Shipping_Methods_V2_Controller', - 'WC_REST_Payment_Gateways_V2_Controller', - ]; - case 'wc/v3': - return [ - 'WC_REST_Coupons_Controller', - 'WC_REST_Customer_Downloads_Controller', - 'WC_REST_Customers_Controller', - 'WC_REST_Network_Orders_Controller', - 'WC_REST_Order_Notes_Controller', - 'WC_REST_Order_Refunds_Controller', - 'WC_REST_Orders_Controller', - 'WC_REST_Product_Attribute_Terms_Controller', - 'WC_REST_Product_Attributes_Controller', - 'WC_REST_Product_Categories_Controller', - 'WC_REST_Product_Reviews_Controller', - 'WC_REST_Product_Shipping_Classes_Controller', - 'WC_REST_Product_Tags_Controller', - 'WC_REST_Products_Controller', - 'WC_REST_Product_Variations_Controller', - 'WC_REST_Report_Sales_Controller', - 'WC_REST_Report_Top_Sellers_Controller', - 'WC_REST_Report_Orders_Totals_Controller', - 'WC_REST_Report_Products_Totals_Controller', - 'WC_REST_Report_Customers_Totals_Controller', - 'WC_REST_Report_Coupons_Totals_Controller', - 'WC_REST_Report_Reviews_Totals_Controller', - 'WC_REST_Reports_Controller', - 'WC_REST_Settings_Controller', - 'WC_REST_Setting_Options_Controller', - 'WC_REST_Shipping_Zones_Controller', - 'WC_REST_Shipping_Zone_Locations_Controller', - 'WC_REST_Shipping_Zone_Methods_Controller', - 'WC_REST_Tax_Classes_Controller', - 'WC_REST_Taxes_Controller', - 'WC_REST_Webhooks_Controller', - 'WC_REST_System_Status_Controller', - 'WC_REST_System_Status_Tools_Controller', - 'WC_REST_Shipping_Methods_Controller', - 'WC_REST_Payment_Gateways_Controller', - 'WC_REST_Data_Controller', - 'WC_REST_Data_Continents_Controller', - 'WC_REST_Data_Countries_Controller', - 'WC_REST_Data_Currencies_Controller', - ]; - case 'wc-blocks/v1': - return [ - 'WC_REST_Blocks_Product_Attributes_Controller', - 'WC_REST_Blocks_Product_Attribute_Terms_Controller', - 'WC_REST_Blocks_Product_Categories_Controller', - 'WC_REST_Blocks_Products_Controller', - ]; + public function get_endpoint_data( $endpoint, $params = array() ) { + $request = new \WP_REST_Request( 'GET', $endpoint ); + + if ( $params ) { + $request->set_query_params( $params ); } - return []; + + $response = \rest_do_request( $request ); + $server = \rest_get_server(); + $json = wp_json_encode( $server->response_to_data( $response, false ) ); + + return json_decode( $json, true ); } } diff --git a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php new file mode 100644 index 00000000000..3d59789c143 --- /dev/null +++ b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php @@ -0,0 +1,27 @@ + 'WC_REST_Blocks_Product_Attributes_Controller', + 'product-attribute-terms' => 'WC_REST_Blocks_Product_Attribute_Terms_Controller', + 'product-categories' => 'WC_REST_Blocks_Product_Categories_Controller', + 'products' => 'WC_REST_Blocks_Products_Controller', + ]; + } +} diff --git a/src/RestApi/Version1/class-wc-rest-controllers-v1.php b/src/RestApi/Version1/class-wc-rest-controllers-v1.php new file mode 100644 index 00000000000..e4f468d4c25 --- /dev/null +++ b/src/RestApi/Version1/class-wc-rest-controllers-v1.php @@ -0,0 +1,43 @@ + 'WC_REST_Coupons_V1_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_V1_Controller', + 'customers' => 'WC_REST_Customers_V1_Controller', + 'order-notes' => 'WC_REST_Order_Notes_V1_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_V1_Controller', + 'orders' => 'WC_REST_Orders_V1_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V1_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_V1_Controller', + 'product-categories' => 'WC_REST_Product_Categories_V1_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_V1_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V1_Controller', + 'product-tags' => 'WC_REST_Product_Tags_V1_Controller', + 'products' => 'WC_REST_Products_V1_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_V1_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V1_Controller', + 'reports' => 'WC_REST_Reports_V1_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_V1_Controller', + 'taxes' => 'WC_REST_Taxes_V1_Controller', + 'webhooks' => 'WC_REST_Webhooks_V1_Controller', + 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V1_Controller', + ]; + } +} diff --git a/src/RestApi/Version2/class-wc-rest-controllers-v2.php b/src/RestApi/Version2/class-wc-rest-controllers-v2.php new file mode 100644 index 00000000000..6a1d6a9de63 --- /dev/null +++ b/src/RestApi/Version2/class-wc-rest-controllers-v2.php @@ -0,0 +1,54 @@ + 'WC_REST_Coupons_V2_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_V2_Controller', + 'customers' => 'WC_REST_Customers_V2_Controller', + 'network-orders' => 'WC_REST_Network_Orders_V2_Controller', + 'order-notes' => 'WC_REST_Order_Notes_V2_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_V2_Controller', + 'orders' => 'WC_REST_Orders_V2_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V2_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_V2_Controller', + 'product-categories' => 'WC_REST_Product_Categories_V2_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_V2_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V2_Controller', + 'product-tags' => 'WC_REST_Product_Tags_V2_Controller', + 'products' => 'WC_REST_Products_V2_Controller', + 'product-variations' => 'WC_REST_Product_Variations_V2_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_V2_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V2_Controller', + 'reports' => 'WC_REST_Reports_V2_Controller', + 'settings' => 'WC_REST_Settings_V2_Controller', + 'settings-options' => 'WC_REST_Setting_Options_V2_Controller', + 'shipping-zones' => 'WC_REST_Shipping_Zones_V2_Controller', + 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_V2_Controller', + 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_V2_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_V2_Controller', + 'taxes' => 'WC_REST_Taxes_V2_Controller', + 'webhooks' => 'WC_REST_Webhooks_V2_Controller', + 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V2_Controller', + 'system-status' => 'WC_REST_System_Status_V2_Controller', + 'system-status-tools' => 'WC_REST_System_Status_Tools_V2_Controller', + 'shipping-methods' => 'WC_REST_Shipping_Methods_V2_Controller', + 'payment-gateways' => 'WC_REST_Payment_Gateways_V2_Controller', + ]; + } +} diff --git a/src/RestApi/Version3/class-wc-rest-controllers-v3.php b/src/RestApi/Version3/class-wc-rest-controllers-v3.php new file mode 100644 index 00000000000..50f968afa22 --- /dev/null +++ b/src/RestApi/Version3/class-wc-rest-controllers-v3.php @@ -0,0 +1,62 @@ + 'WC_REST_Coupons_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_Controller', + 'customers' => 'WC_REST_Customers_Controller', + 'network-orders' => 'WC_REST_Network_Orders_Controller', + 'order-notes' => 'WC_REST_Order_Notes_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_Controller', + 'orders' => 'WC_REST_Orders_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_Controller', + 'product-categories' => 'WC_REST_Product_Categories_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_Controller', + 'product-tags' => 'WC_REST_Product_Tags_Controller', + 'products' => 'WC_REST_Products_Controller', + 'product-variations' => 'WC_REST_Product_Variations_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_Controller', + 'reports-orders-totals' => 'WC_REST_Report_Orders_Totals_Controller', + 'reports-products-totals' => 'WC_REST_Report_Products_Totals_Controller', + 'reports-customers-totals' => 'WC_REST_Report_Customers_Totals_Controller', + 'reports-coupons-totals' => 'WC_REST_Report_Coupons_Totals_Controller', + 'reports-reviews-totals' => 'WC_REST_Report_Reviews_Totals_Controller', + 'reports' => 'WC_REST_Reports_Controller', + 'settings' => 'WC_REST_Settings_Controller', + 'settings-options' => 'WC_REST_Setting_Options_Controller', + 'shipping-zones' => 'WC_REST_Shipping_Zones_Controller', + 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_Controller', + 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_Controller', + 'taxes' => 'WC_REST_Taxes_Controller', + 'webhooks' => 'WC_REST_Webhooks_Controller', + 'system-status' => 'WC_REST_System_Status_Controller', + 'system-status-tools' => 'WC_REST_System_Status_Tools_Controller', + 'shipping-methods' => 'WC_REST_Shipping_Methods_Controller', + 'payment-gateways' => 'WC_REST_Payment_Gateways_Controller', + 'data' => 'WC_REST_Data_Controller', + 'data-continents' => 'WC_REST_Data_Continents_Controller', + 'data-countries' => 'WC_REST_Data_Countries_Controller', + 'data-currencies' => 'WC_REST_Data_Currencies_Controller', + ]; + } +} diff --git a/src/RestApi/Version4/Main.php b/src/RestApi/Version4/Controllers.php similarity index 97% rename from src/RestApi/Version4/Main.php rename to src/RestApi/Version4/Controllers.php index 05ef9993fe4..3372afec08b 100644 --- a/src/RestApi/Version4/Main.php +++ b/src/RestApi/Version4/Controllers.php @@ -9,20 +9,16 @@ namespace WooCommerce\RestApi\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\Utilities\SingletonTrait; - /** - * Main V4 namespace class. + * Controllers class. */ -class Main { - use SingletonTrait; - +class Controllers { /** * Return a list of controller classes for this REST API namespace. * * @return array */ - public function get_controllers() { + public static function get_controllers() { $controllers = [ 'coupons' => __NAMESPACE__ . '\Controllers\Coupons', 'customer-downloads' => __NAMESPACE__ . '\Controllers\CustomerDownloads', diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index e83246ceec3..e258f444b5b 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,12 +6,16 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'WC_REST_Blocks_Controllers' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php', 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php', 'WC_REST_Blocks_Product_Attributes_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php', 'WC_REST_Blocks_Product_Categories_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php', 'WC_REST_Blocks_Products_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php', 'WC_REST_CRUD_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-crud-controller.php', 'WC_REST_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-controller.php', + 'WC_REST_Controllers_V1' => $baseDir . '/src/RestApi/Version1/class-wc-rest-controllers-v1.php', + 'WC_REST_Controllers_V2' => $baseDir . '/src/RestApi/Version2/class-wc-rest-controllers-v2.php', + 'WC_REST_Controllers_V3' => $baseDir . '/src/RestApi/Version3/class-wc-rest-controllers-v3.php', 'WC_REST_Coupons_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-coupons-controller.php', 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php', 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php', @@ -106,6 +110,7 @@ return array( 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php', 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php', 'WooCommerce\\RestApi' => $baseDir . '/src/RestApi.php', + 'WooCommerce\\RestApi\\Version4\\Controllers' => $baseDir . '/src/RestApi/Version4/Controllers.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractController.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractObjectsController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractObjectsController.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractPostsController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractPostsController.php', @@ -167,6 +172,5 @@ return array( 'WooCommerce\\RestApi\\Version4\\Controllers\\TaxClasses' => $baseDir . '/src/RestApi/Version4/Controllers/TaxClasses.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\Taxes' => $baseDir . '/src/RestApi/Version4/Controllers/Taxes.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\Webhooks' => $baseDir . '/src/RestApi/Version4/Controllers/Webhooks.php', - 'WooCommerce\\RestApi\\Version4\\Main' => $baseDir . '/src/RestApi/Version4/Main.php', 'WooCommerce\\Utilities\\SingletonTrait' => $baseDir . '/src/Utilities/SingletonTrait.php', ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 06084faceb3..47c1be3cacb 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -7,12 +7,16 @@ namespace Composer\Autoload; class ComposerStaticInitf71e7bc9895f702f48d84a180f514421 { public static $classMap = array ( + 'WC_REST_Blocks_Controllers' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php', 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php', 'WC_REST_Blocks_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php', 'WC_REST_Blocks_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php', 'WC_REST_Blocks_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php', 'WC_REST_CRUD_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-crud-controller.php', 'WC_REST_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-controller.php', + 'WC_REST_Controllers_V1' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-controllers-v1.php', + 'WC_REST_Controllers_V2' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-controllers-v2.php', + 'WC_REST_Controllers_V3' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-controllers-v3.php', 'WC_REST_Coupons_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-coupons-controller.php', 'WC_REST_Coupons_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php', 'WC_REST_Coupons_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php', @@ -107,6 +111,7 @@ class ComposerStaticInitf71e7bc9895f702f48d84a180f514421 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php', 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php', 'WooCommerce\\RestApi' => __DIR__ . '/../..' . '/src/RestApi.php', + 'WooCommerce\\RestApi\\Version4\\Controllers' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractController.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractObjectsController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractObjectsController.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractPostsController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractPostsController.php', @@ -168,7 +173,6 @@ class ComposerStaticInitf71e7bc9895f702f48d84a180f514421 'WooCommerce\\RestApi\\Version4\\Controllers\\TaxClasses' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/TaxClasses.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\Taxes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Taxes.php', 'WooCommerce\\RestApi\\Version4\\Controllers\\Webhooks' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Webhooks.php', - 'WooCommerce\\RestApi\\Version4\\Main' => __DIR__ . '/../..' . '/src/RestApi/Version4/Main.php', 'WooCommerce\\Utilities\\SingletonTrait' => __DIR__ . '/../..' . '/src/Utilities/SingletonTrait.php', ); From 51d8cefcf8ec7545d2084761318de2de40492b51 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 11:44:59 +0100 Subject: [PATCH 048/440] WP_REST_Request --- .../Controllers/AbstractController.php | 10 ++-- .../Controllers/AbstractObjectsController.php | 34 +++++++------- .../Controllers/AbstractPostsController.php | 38 +++++++-------- .../AbstractShippingZonesController.php | 8 ++-- .../Controllers/AbstractTermsContoller.php | 46 +++++++++---------- src/RestApi/Version4/Controllers/Coupons.php | 30 ++++++------ .../Controllers/CustomerDownloads.php | 10 ++-- .../Version4/Controllers/Customers.php | 36 +++++++-------- src/RestApi/Version4/Controllers/Data.php | 8 ++-- .../Version4/Controllers/Data/Continents.php | 10 ++-- .../Version4/Controllers/Data/Countries.php | 10 ++-- .../Version4/Controllers/Data/Currencies.php | 12 ++--- .../Version4/Controllers/Data/DownloadIPs.php | 6 +-- .../Version4/Controllers/Leaderboards.php | 8 ++-- .../Version4/Controllers/NetworkOrders.php | 4 +- .../Controllers/Onboarding/Levels.php | 6 +-- .../Controllers/Onboarding/Plugins.php | 6 +-- .../Controllers/Onboarding/Profile.php | 12 ++--- .../Version4/Controllers/OrderNotes.php | 24 +++++----- .../Version4/Controllers/OrderRefunds.php | 22 ++++----- src/RestApi/Version4/Controllers/Orders.php | 16 +++---- .../Version4/Controllers/PaymentGateways.php | 20 ++++---- .../Controllers/ProductAttributeTerms.php | 6 +-- .../Controllers/ProductAttributes.php | 40 ++++++++-------- .../Controllers/ProductCategories.php | 6 +-- .../Version4/Controllers/ProductReviews.php | 38 +++++++-------- .../Controllers/ProductShippingClasses.php | 4 +- .../Version4/Controllers/ProductTags.php | 4 +- .../Controllers/ProductVariations.php | 24 +++++----- src/RestApi/Version4/Controllers/Products.php | 20 ++++---- src/RestApi/Version4/Controllers/Reports.php | 8 ++-- .../Controllers/Reports/Categories.php | 6 +-- .../Controllers/Reports/CouponStats.php | 6 +-- .../Version4/Controllers/Reports/Coupons.php | 6 +-- .../Controllers/Reports/CustomerStats.php | 6 +-- .../Controllers/Reports/Customers.php | 6 +-- .../Controllers/Reports/DownloadStats.php | 6 +-- .../Controllers/Reports/Downloads.php | 6 +-- .../Version4/Controllers/Reports/Import.php | 18 ++++---- .../Controllers/Reports/OrderStats.php | 6 +-- .../Version4/Controllers/Reports/Orders.php | 6 +-- .../Reports/PerformanceIndicators.php | 14 +++--- .../Controllers/Reports/ProductStats.php | 6 +-- .../Version4/Controllers/Reports/Products.php | 6 +-- .../Controllers/Reports/RevenueStats.php | 6 +-- .../Version4/Controllers/Reports/Stock.php | 8 ++-- .../Controllers/Reports/StockStats.php | 6 +-- .../Version4/Controllers/Reports/TaxStats.php | 6 +-- .../Version4/Controllers/Reports/Taxes.php | 6 +-- .../Controllers/Reports/Variations.php | 6 +-- src/RestApi/Version4/Controllers/Settings.php | 10 ++-- .../Version4/Controllers/SettingsOptions.php | 16 +++---- .../Version4/Controllers/ShippingMethods.php | 14 +++--- .../Controllers/ShippingZoneLocations.php | 6 +-- .../Controllers/ShippingZoneMethods.php | 18 ++++---- .../Version4/Controllers/ShippingZones.php | 18 ++++---- .../Version4/Controllers/SystemStatus.php | 8 ++-- .../Controllers/SystemStatusTools.php | 16 +++---- .../Version4/Controllers/TaxClasses.php | 20 ++++---- src/RestApi/Version4/Controllers/Taxes.php | 36 +++++++-------- src/RestApi/Version4/Controllers/Webhooks.php | 38 +++++++-------- 61 files changed, 431 insertions(+), 431 deletions(-) diff --git a/src/RestApi/Version4/Controllers/AbstractController.php b/src/RestApi/Version4/Controllers/AbstractController.php index ac37601b3b8..e08694599ae 100644 --- a/src/RestApi/Version4/Controllers/AbstractController.php +++ b/src/RestApi/Version4/Controllers/AbstractController.php @@ -118,7 +118,7 @@ abstract class AbstractController extends WP_REST_Controller { /** * Bulk create, update and delete items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array Of \WP_Error or WP_REST_Response. */ public function batch_items( $request ) { @@ -141,7 +141,7 @@ abstract class AbstractController extends WP_REST_Controller { if ( ! empty( $items['create'] ) ) { foreach ( $items['create'] as $item ) { - $_item = new WP_REST_Request( 'POST' ); + $_item = new \WP_REST_Request( 'POST' ); // Default parameters. $defaults = array(); @@ -174,7 +174,7 @@ abstract class AbstractController extends WP_REST_Controller { if ( ! empty( $items['update'] ) ) { foreach ( $items['update'] as $item ) { - $_item = new WP_REST_Request( 'PUT' ); + $_item = new \WP_REST_Request( 'PUT' ); $_item->set_body_params( $item ); $_response = $this->update_item( $_item ); @@ -201,7 +201,7 @@ abstract class AbstractController extends WP_REST_Controller { continue; } - $_item = new WP_REST_Request( 'DELETE' ); + $_item = new \WP_REST_Request( 'DELETE' ); $_item->set_query_params( array( 'id' => $id, @@ -432,7 +432,7 @@ abstract class AbstractController extends WP_REST_Controller { * Introduced to support WordPress 4.9.6 changes. * * @since 3.5.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array Fields to be included in the response. */ public function get_fields_for_response( $request ) { diff --git a/src/RestApi/Version4/Controllers/AbstractObjectsController.php b/src/RestApi/Version4/Controllers/AbstractObjectsController.php index 62f0120de36..ce0f5fe2725 100644 --- a/src/RestApi/Version4/Controllers/AbstractObjectsController.php +++ b/src/RestApi/Version4/Controllers/AbstractObjectsController.php @@ -35,7 +35,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Check if a given request has access to read an item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -51,7 +51,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Check if a given request has access to update an item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { @@ -67,7 +67,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Check if a given request has access to delete an item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { @@ -95,7 +95,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * * @since 3.0.0 * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return \WP_Error|WP_REST_Response Response object on success, or \WP_Error object on failure. */ protected function prepare_object_for_response( $object, $request ) { @@ -107,7 +107,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Prepares one object for create or update operation. * * @since 3.0.0 - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data The prepared item, or \WP_Error object on failure. */ @@ -119,7 +119,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Get a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -143,7 +143,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Save an object data. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. * @return WC_Data|\WP_Error */ @@ -168,7 +168,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Create a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -197,7 +197,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Fires after a single object is created or updated via the REST API. * * @param WC_Data $object Inserted object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating object, false when updating. */ do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); @@ -214,7 +214,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Update a single post. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -242,7 +242,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Fires after a single object is created or updated via the REST API. * * @param WC_Data $object Inserted object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating object, false when updating. */ do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); @@ -256,7 +256,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Prepare objects query. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array */ protected function prepare_objects_query( $request ) { @@ -298,7 +298,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * collection request. * * @param array $args Key value array of query var to query value. - * @param WP_REST_Request $request The request used. + * @param \WP_REST_Request $request The request used. */ $args = apply_filters( "woocommerce_rest_{$this->post_type}_object_query", $args, $request ); @@ -335,7 +335,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Get a collection of posts. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -395,7 +395,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Delete a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { @@ -460,7 +460,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * * @param WC_Data $object The deleted or trashed object. * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); @@ -471,7 +471,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Prepare links for the request. * * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ protected function prepare_links( $object, $request ) { diff --git a/src/RestApi/Version4/Controllers/AbstractPostsController.php b/src/RestApi/Version4/Controllers/AbstractPostsController.php index 71249fa684b..d6943abf056 100644 --- a/src/RestApi/Version4/Controllers/AbstractPostsController.php +++ b/src/RestApi/Version4/Controllers/AbstractPostsController.php @@ -40,7 +40,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Check if a given request has access to read items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -54,7 +54,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Check if a given request has access to create an item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { @@ -68,7 +68,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Check if a given request has access to read an item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -84,7 +84,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Check if a given request has access to update an item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { @@ -100,7 +100,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Check if a given request has access to delete an item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { @@ -116,7 +116,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Check if a given request has access batch create, update and delete items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return boolean|\WP_Error */ @@ -131,7 +131,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Get a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -157,7 +157,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Create a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -201,7 +201,7 @@ abstract class AbstractPostsController extends AbstractController { * Fires after a single item is created or updated via the REST API. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); @@ -219,7 +219,7 @@ abstract class AbstractPostsController extends AbstractController { * Add post meta fields. * * @param WP_Post $post Post Object. - * @param WP_REST_Request $request WP_REST_Request Object. + * @param \WP_REST_Request $request \WP_REST_Request Object. * @return bool|\WP_Error */ protected function add_post_meta_fields( $post, $request ) { @@ -238,7 +238,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Update a single post. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -279,7 +279,7 @@ abstract class AbstractPostsController extends AbstractController { * Fires after a single item is created or updated via the REST API. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); @@ -292,7 +292,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Get a collection of posts. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -337,7 +337,7 @@ abstract class AbstractPostsController extends AbstractController { * collection request. * * @param array $args Key value array of query var to query value. - * @param WP_REST_Request $request The request used. + * @param \WP_REST_Request $request The request used. */ $args = apply_filters( "woocommerce_rest_{$this->post_type}_query", $args, $request ); $query_args = $this->prepare_items_query( $args, $request ); @@ -400,7 +400,7 @@ abstract class AbstractPostsController extends AbstractController { /** * Delete a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { @@ -463,7 +463,7 @@ abstract class AbstractPostsController extends AbstractController { * * @param object $post The deleted or trashed item. * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); @@ -474,7 +474,7 @@ abstract class AbstractPostsController extends AbstractController { * Prepare links for the request. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ protected function prepare_links( $post, $request ) { @@ -495,7 +495,7 @@ abstract class AbstractPostsController extends AbstractController { * prepare for \WP_Query. * * @param array $prepared_args Prepared arguments. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array $query_args */ protected function prepare_items_query( $prepared_args = array(), $request = null ) { @@ -705,7 +705,7 @@ abstract class AbstractPostsController extends AbstractController { * Update post meta fields. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return bool|\WP_Error */ protected function update_post_meta_fields( $post, $request ) { diff --git a/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php b/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php index df9ad4684c4..348d4a8a4f6 100644 --- a/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php +++ b/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php @@ -46,7 +46,7 @@ abstract class AbstractShippingZonesController extends AbstractController { /** * Check whether a given request has permission to read Shipping Zones. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -64,7 +64,7 @@ abstract class AbstractShippingZonesController extends AbstractController { /** * Check if a given request has access to create Shipping Zones. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { @@ -82,7 +82,7 @@ abstract class AbstractShippingZonesController extends AbstractController { /** * Check whether a given request has permission to edit Shipping Zones. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_items_permissions_check( $request ) { @@ -100,7 +100,7 @@ abstract class AbstractShippingZonesController extends AbstractController { /** * Check whether a given request has permission to delete Shipping Zones. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function delete_items_permissions_check( $request ) { diff --git a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php index 858cd68ef3f..cc443fa594b 100644 --- a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php +++ b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php @@ -119,7 +119,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Check if a given request has access to read the terms. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -138,7 +138,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Check if a given request has access to create a term. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { @@ -157,7 +157,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Check if a given request has access to read a term. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -176,7 +176,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Check if a given request has access to update a term. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { @@ -195,7 +195,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Check if a given request has access to delete a term. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function delete_item_permissions_check( $request ) { @@ -214,7 +214,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Check if a given request has access batch create, update and delete items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return boolean|\WP_Error */ public function batch_items_permissions_check( $request ) { @@ -233,7 +233,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Check permissions. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @param string $context Request context. * @return bool|\WP_Error */ @@ -262,7 +262,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Get terms associated with a taxonomy. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return WP_REST_Response|\WP_Error */ public function get_items( $request ) { @@ -308,7 +308,7 @@ abstract class AbstractTermsContoller extends AbstractController { * * @param array $prepared_args Array of arguments to be * passed to get_terms. - * @param WP_REST_Request $request The current request. + * @param \WP_REST_Request $request The current request. */ $prepared_args = apply_filters( "woocommerce_rest_{$taxonomy}_query", $prepared_args, $request ); @@ -372,8 +372,8 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Create a single term for a taxonomy. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function create_item( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -424,7 +424,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Fires after a single term is created or updated via the REST API. * * @param WP_Term $term Inserted Term object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating term, false when updating. */ do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, true ); @@ -447,8 +447,8 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Get a single term from a taxonomy. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function get_item( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -466,8 +466,8 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Update a single term from a taxonomy. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function update_item( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -513,7 +513,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Fires after a single term is created or updated via the REST API. * * @param WP_Term $term Inserted Term object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating term, false when updating. */ do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, false ); @@ -526,7 +526,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Delete a single term from a taxonomy. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { @@ -560,7 +560,7 @@ abstract class AbstractTermsContoller extends AbstractController { * * @param WP_Term $term The deleted term. * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$taxonomy}", $term, $response, $request ); @@ -571,7 +571,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Prepare links for the request. * * @param object $term Term object. - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array Links for the given term. */ protected function prepare_links( $term, $request ) { @@ -606,7 +606,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Update term meta fields. * * @param WP_Term $term Term object. - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return bool|\WP_Error */ protected function update_term_meta_fields( $term, $request ) { @@ -622,7 +622,7 @@ abstract class AbstractTermsContoller extends AbstractController { * are instead treated as a full query. * * @param array $prepared_args Arguments for `get_terms()`. - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array List of term objects. (Total count in `$this->total_terms`). */ protected function get_terms_for_product( $prepared_args, $request ) { @@ -784,7 +784,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Get taxonomy. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return int|\WP_Error */ protected function get_taxonomy( $request ) { diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/RestApi/Version4/Controllers/Coupons.php index f7b1d71c429..35818399f99 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -203,7 +203,7 @@ class Coupons extends AbstractPostsController { * * @since 3.0.0 * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { @@ -222,7 +222,7 @@ class Coupons extends AbstractPostsController { * * @param WP_REST_Response $response The response object. * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } @@ -231,7 +231,7 @@ class Coupons extends AbstractPostsController { * Prepare objects query. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array */ protected function prepare_objects_query( $request ) { @@ -256,7 +256,7 @@ class Coupons extends AbstractPostsController { /** * Prepare a single coupon for create or update. * - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data */ @@ -314,7 +314,7 @@ class Coupons extends AbstractPostsController { * refers to the object type slug. * * @param WC_Data $coupon Object object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $coupon, $request, $creating ); @@ -550,7 +550,7 @@ class Coupons extends AbstractPostsController { * Query args. * * @param array $args Query args. - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array */ public function query_args( $args, $request ) { @@ -566,7 +566,7 @@ class Coupons extends AbstractPostsController { * Prepare a single coupon output for response. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $data */ public function prepare_item_for_response( $post, $request ) { @@ -636,7 +636,7 @@ class Coupons extends AbstractPostsController { * * @param WP_REST_Response $response The response object. * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); } @@ -654,7 +654,7 @@ class Coupons extends AbstractPostsController { /** * Prepare a single coupon for create or update. * - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return \WP_Error|stdClass $data Post object. */ protected function prepare_item_for_database( $request ) { @@ -717,7 +717,7 @@ class Coupons extends AbstractPostsController { * prepared for insertion. * * @param WC_Coupon $coupon The coupon object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request ); } @@ -725,7 +725,7 @@ class Coupons extends AbstractPostsController { /** * Create a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -748,7 +748,7 @@ class Coupons extends AbstractPostsController { * Fires after a single item is created or updated via the REST API. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); @@ -764,7 +764,7 @@ class Coupons extends AbstractPostsController { /** * Update a single coupon. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -787,7 +787,7 @@ class Coupons extends AbstractPostsController { * Fires after a single item is created or updated via the REST API. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); @@ -803,7 +803,7 @@ class Coupons extends AbstractPostsController { /** * Get a collection of posts and add the code search option to \WP_Query. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { diff --git a/src/RestApi/Version4/Controllers/CustomerDownloads.php b/src/RestApi/Version4/Controllers/CustomerDownloads.php index 475bb1e900f..8cdc402a2a4 100644 --- a/src/RestApi/Version4/Controllers/CustomerDownloads.php +++ b/src/RestApi/Version4/Controllers/CustomerDownloads.php @@ -51,7 +51,7 @@ class CustomerDownloads extends AbstractController { /** * Check whether a given request has permission to read customers. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -71,7 +71,7 @@ class CustomerDownloads extends AbstractController { /** * Get all customer downloads. * - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. * @return array */ public function get_items( $request ) { @@ -91,7 +91,7 @@ class CustomerDownloads extends AbstractController { * Prepare a single download output for response. * * @param stdClass $download Download object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $download, $request ) { @@ -123,7 +123,7 @@ class CustomerDownloads extends AbstractController { * * @param WP_REST_Response $response The response object. * @param stdClass $download Download object used to create response. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); } @@ -132,7 +132,7 @@ class CustomerDownloads extends AbstractController { * Prepare links for the request. * * @param stdClass $download Download object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array Links for the given customer download. */ protected function prepare_links( $download, $request ) { diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/RestApi/Version4/Controllers/Customers.php index d46d261b5b7..66a6d8f0ecd 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -131,7 +131,7 @@ class Customers extends AbstractController { /** * Check whether a given request has permission to read customers. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -145,7 +145,7 @@ class Customers extends AbstractController { /** * Check if a given request has access create customers. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -160,7 +160,7 @@ class Customers extends AbstractController { /** * Check if a given request has access to read a customer. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -176,7 +176,7 @@ class Customers extends AbstractController { /** * Check if a given request has access update a customer. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -193,7 +193,7 @@ class Customers extends AbstractController { /** * Check if a given request has access delete a customer. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -210,7 +210,7 @@ class Customers extends AbstractController { /** * Check if a given request has access batch create, update and delete items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -264,7 +264,7 @@ class Customers extends AbstractController { /** * Get all customers. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -308,7 +308,7 @@ class Customers extends AbstractController { * @see https://developer.wordpress.org/reference/classes/\ WP_User_Query/ * * @param array $prepared_args Array of arguments for \ WP_User_Query. - * @param WP_REST_Request $request The current request. + * @param \WP_REST_Request $request The current request. */ $prepared_args = apply_filters( 'woocommerce_rest_customer_query', $prepared_args, $request ); @@ -362,7 +362,7 @@ class Customers extends AbstractController { * Create a single customer. * * @throws WC_REST_Exception On invalid params. - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -396,7 +396,7 @@ class Customers extends AbstractController { * Fires after a customer is created or updated via the REST API. * * @param WP_User $user_data Data used to create the customer. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating customer, false when updating customer. */ do_action( 'woocommerce_rest_insert_customer', $user_data, $request, true ); @@ -416,7 +416,7 @@ class Customers extends AbstractController { /** * Get a single customer. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -437,7 +437,7 @@ class Customers extends AbstractController { * Update a single user. * * @throws WC_REST_Exception On invalid params. - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -481,7 +481,7 @@ class Customers extends AbstractController { * Fires after a customer is created or updated via the REST API. * * @param WP_User $customer Data used to create the customer. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating customer, false when updating customer. */ do_action( 'woocommerce_rest_insert_customer', $user_data, $request, false ); @@ -498,7 +498,7 @@ class Customers extends AbstractController { /** * Delete a single customer. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function delete_item( $request ) { @@ -545,7 +545,7 @@ class Customers extends AbstractController { * * @param WP_User $user_data User data. * @param WP_REST_Response $response The response returned from the API. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_customer', $user_data, $response, $request ); @@ -556,7 +556,7 @@ class Customers extends AbstractController { * Prepare a single customer output for response. * * @param WP_User $user_data User object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $user_data, $request ) { @@ -573,7 +573,7 @@ class Customers extends AbstractController { * * @param WP_REST_Response $response The response object. * @param WP_User $user_data User object used to create response. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); } @@ -582,7 +582,7 @@ class Customers extends AbstractController { * Update customer meta fields. * * @param WC_Customer $customer Customer being updated. - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. */ protected function update_customer_meta_fields( $customer, $request ) { $schema = $this->get_item_schema(); diff --git a/src/RestApi/Version4/Controllers/Data.php b/src/RestApi/Version4/Controllers/Data.php index c57b4febf2e..ea41d625d41 100644 --- a/src/RestApi/Version4/Controllers/Data.php +++ b/src/RestApi/Version4/Controllers/Data.php @@ -46,7 +46,7 @@ class Data extends AbstractController { /** * Check whether a given request has permission to read site data. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -60,7 +60,7 @@ class Data extends AbstractController { /** * Check whether a given request has permission to read site settings. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -75,7 +75,7 @@ class Data extends AbstractController { * Return the list of data resources. * * @since 3.5.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -111,7 +111,7 @@ class Data extends AbstractController { * Prepare a data resource object for serialization. * * @param stdClass $resource Resource data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $resource, $request ) { diff --git a/src/RestApi/Version4/Controllers/Data/Continents.php b/src/RestApi/Version4/Controllers/Data/Continents.php index 7e2afd69dae..6790afdb10a 100644 --- a/src/RestApi/Version4/Controllers/Data/Continents.php +++ b/src/RestApi/Version4/Controllers/Data/Continents.php @@ -68,7 +68,7 @@ class Continents extends DataController { * * @since 3.5.0 * @param string $continent_code Continent code. - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|mixed Response data, ready for insertion into collection data. */ public function get_continent( $continent_code = false, $request ) { @@ -154,7 +154,7 @@ class Continents extends DataController { * Return the list of states for all continents. * * @since 3.5.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -174,7 +174,7 @@ class Continents extends DataController { * Return the list of locations for a given continent. * * @since 3.5.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -190,7 +190,7 @@ class Continents extends DataController { * * @since 3.5.0 * @param object $item Data object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -207,7 +207,7 @@ class Continents extends DataController { * * @param WP_REST_Response $response The response object. * @param array $item The original list of continent(s), countries, and states. - * @param WP_REST_Request $request Request used to generate the response. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_data_continent', $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/Data/Countries.php b/src/RestApi/Version4/Controllers/Data/Countries.php index c8b248b18ac..a7d10eff071 100644 --- a/src/RestApi/Version4/Controllers/Data/Countries.php +++ b/src/RestApi/Version4/Controllers/Data/Countries.php @@ -67,7 +67,7 @@ class Countries extends DataController { * Get a list of countries and states. * * @param string $country_code Country code. - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|mixed Response data, ready for insertion into collection data. */ public function get_country( $country_code = false, $request ) { @@ -101,7 +101,7 @@ class Countries extends DataController { * Return the list of states for all countries. * * @since 3.5.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -121,7 +121,7 @@ class Countries extends DataController { * Return the list of states for a given country. * * @since 3.5.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -137,7 +137,7 @@ class Countries extends DataController { * * @since 3.5.0 * @param object $item Data object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -154,7 +154,7 @@ class Countries extends DataController { * * @param WP_REST_Response $response The response object. * @param array $data The original country's states list. - * @param WP_REST_Request $request Request used to generate the response. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_data_country', $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/Data/Currencies.php b/src/RestApi/Version4/Controllers/Data/Currencies.php index d6a892f6b3b..0634c400c27 100644 --- a/src/RestApi/Version4/Controllers/Data/Currencies.php +++ b/src/RestApi/Version4/Controllers/Data/Currencies.php @@ -77,7 +77,7 @@ class Currencies extends DataController { * Get currency information. * * @param string $code Currency code. - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|mixed Response data, ready for insertion into collection data. */ public function get_currency( $code = false, $request ) { @@ -100,7 +100,7 @@ class Currencies extends DataController { /** * Return the list of currencies. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -117,7 +117,7 @@ class Currencies extends DataController { /** * Return information for a specific currency. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -131,7 +131,7 @@ class Currencies extends DataController { /** * Return information for the current site currency. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_current_item( $request ) { @@ -143,7 +143,7 @@ class Currencies extends DataController { * Prepare the data object for response. * * @param object $item Data object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -158,7 +158,7 @@ class Currencies extends DataController { * * @param WP_REST_Response $response The response object. * @param array $item Currency data. - * @param WP_REST_Request $request Request used to generate the response. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_data_currency', $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php index d20177270be..3279cc46c04 100644 --- a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php +++ b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php @@ -49,7 +49,7 @@ class DownloadIPs extends DataController { * Return the download IPs matching the passed parameters. * * @since 3.5.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -85,7 +85,7 @@ class DownloadIPs extends DataController { * * @since 3.5.0 * @param object $item Data object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -100,7 +100,7 @@ class DownloadIPs extends DataController { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_data_download_ip', $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/Leaderboards.php b/src/RestApi/Version4/Controllers/Leaderboards.php index d01cd5f7db2..2271ea0346a 100644 --- a/src/RestApi/Version4/Controllers/Leaderboards.php +++ b/src/RestApi/Version4/Controllers/Leaderboards.php @@ -344,7 +344,7 @@ class Leaderboards extends AbstractController { /** * Return all leaderboards. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -365,7 +365,7 @@ class Leaderboards extends AbstractController { /** * Returns a list of allowed leaderboards. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_allowed_items( $request ) { @@ -399,7 +399,7 @@ class Leaderboards extends AbstractController { * Prepare the data object for response. * * @param object $item Data object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -412,7 +412,7 @@ class Leaderboards extends AbstractController { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_leaderboard', $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/NetworkOrders.php b/src/RestApi/Version4/Controllers/NetworkOrders.php index f2465afdbbb..d13dcd1dbcd 100644 --- a/src/RestApi/Version4/Controllers/NetworkOrders.php +++ b/src/RestApi/Version4/Controllers/NetworkOrders.php @@ -82,7 +82,7 @@ class NetworkOrders extends Orders { /** * Does a permissions check for the proper requested blog * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool $permission */ @@ -102,7 +102,7 @@ class NetworkOrders extends Orders { /** * Get a collection of orders from the requested blog id * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return WP_REST_Response */ diff --git a/src/RestApi/Version4/Controllers/Onboarding/Levels.php b/src/RestApi/Version4/Controllers/Onboarding/Levels.php index ff6bacdc0d9..6f25493294a 100644 --- a/src/RestApi/Version4/Controllers/Onboarding/Levels.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Levels.php @@ -123,7 +123,7 @@ class Levels extends WC_REST_Data_Controller { /** * Return all level items and child tasks. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -147,7 +147,7 @@ class Levels extends WC_REST_Data_Controller { * Prepare the data object for response. * * @param object $item Data object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -162,7 +162,7 @@ class Levels extends WC_REST_Data_Controller { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_onboarding_level', $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/Onboarding/Plugins.php b/src/RestApi/Version4/Controllers/Onboarding/Plugins.php index 60b1b8dd403..90d864bdb1e 100644 --- a/src/RestApi/Version4/Controllers/Onboarding/Plugins.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Plugins.php @@ -81,7 +81,7 @@ class Plugins extends WC_REST_Data_Controller { /** * Check if a given request has access to manage plugins. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { @@ -107,7 +107,7 @@ class Plugins extends WC_REST_Data_Controller { /** * Installs the requested plugin. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array Plugin Status */ public function install_plugin( $request ) { @@ -168,7 +168,7 @@ class Plugins extends WC_REST_Data_Controller { /** * Activate the requested plugin. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array Plugin Status */ public function activate_plugin( $request ) { diff --git a/src/RestApi/Version4/Controllers/Onboarding/Profile.php b/src/RestApi/Version4/Controllers/Onboarding/Profile.php index bdbb2babc62..abbfb7452bd 100644 --- a/src/RestApi/Version4/Controllers/Onboarding/Profile.php +++ b/src/RestApi/Version4/Controllers/Onboarding/Profile.php @@ -69,7 +69,7 @@ class Profile extends WC_REST_Data_Controller { /** * Check whether a given request has permission to read onboarding profile data. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -83,7 +83,7 @@ class Profile extends WC_REST_Data_Controller { /** * Check whether a given request has permission to edit onboarding profile data. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_items_permissions_check( $request ) { @@ -97,7 +97,7 @@ class Profile extends WC_REST_Data_Controller { /** * Return all onboarding profile data. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -118,7 +118,7 @@ class Profile extends WC_REST_Data_Controller { /** * Update onboarding profile data. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function update_items( $request ) { @@ -173,7 +173,7 @@ class Profile extends WC_REST_Data_Controller { * Prepare the data object for response. * * @param object $item Data object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -186,7 +186,7 @@ class Profile extends WC_REST_Data_Controller { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_onboarding_profile', $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/OrderNotes.php b/src/RestApi/Version4/Controllers/OrderNotes.php index 507d82bb5c5..a31e0ee5ac0 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -100,7 +100,7 @@ class OrderNotes extends AbstractController { /** * Check whether a given request has permission to read order notes. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -114,7 +114,7 @@ class OrderNotes extends AbstractController { /** * Check if a given request has access create order notes. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -129,7 +129,7 @@ class OrderNotes extends AbstractController { /** * Check if a given request has access to read a order note. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -145,7 +145,7 @@ class OrderNotes extends AbstractController { /** * Check if a given request has access delete a order note. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -162,7 +162,7 @@ class OrderNotes extends AbstractController { /** * Get order notes from an order. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * * @return array|\WP_Error */ @@ -216,7 +216,7 @@ class OrderNotes extends AbstractController { /** * Create a single order note. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -245,7 +245,7 @@ class OrderNotes extends AbstractController { * Fires after a order note is created or updated via the REST API. * * @param WP_Comment $note New order note object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); @@ -262,7 +262,7 @@ class OrderNotes extends AbstractController { /** * Get a single order note. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -288,7 +288,7 @@ class OrderNotes extends AbstractController { /** * Delete a single order note. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { @@ -326,7 +326,7 @@ class OrderNotes extends AbstractController { * * @param WP_Comment $note The deleted or trashed order note. * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_order_note', $note, $response, $request ); @@ -337,7 +337,7 @@ class OrderNotes extends AbstractController { * Prepare a single order note output for response. * * @param WP_Comment $note Order note object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $note, $request ) { @@ -364,7 +364,7 @@ class OrderNotes extends AbstractController { * * @param WP_REST_Response $response The response object. * @param WP_Comment $note Order note object used to create response. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); } diff --git a/src/RestApi/Version4/Controllers/OrderRefunds.php b/src/RestApi/Version4/Controllers/OrderRefunds.php index 583f2e4f731..f801364f13e 100644 --- a/src/RestApi/Version4/Controllers/OrderRefunds.php +++ b/src/RestApi/Version4/Controllers/OrderRefunds.php @@ -173,7 +173,7 @@ class OrderRefunds extends Orders { * @since 3.0.0 * * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * * @return \WP_Error|WP_REST_Response */ @@ -208,7 +208,7 @@ class OrderRefunds extends Orders { * * @param WP_REST_Response $response The response object. * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } @@ -217,7 +217,7 @@ class OrderRefunds extends Orders { * Prepare a single order refund output for response. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * * @return \WP_Error|WP_REST_Response */ @@ -326,7 +326,7 @@ class OrderRefunds extends Orders { * * @param WP_REST_Response $response The response object. * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); } @@ -335,7 +335,7 @@ class OrderRefunds extends Orders { * Prepare links for the request. * * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ protected function prepare_links( $object, $request ) { @@ -359,7 +359,7 @@ class OrderRefunds extends Orders { * Prepare objects query. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array */ protected function prepare_objects_query( $request ) { @@ -374,7 +374,7 @@ class OrderRefunds extends Orders { /** * Create a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -419,7 +419,7 @@ class OrderRefunds extends Orders { * Fires after a single item is created or updated via the REST API. * * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); @@ -437,7 +437,7 @@ class OrderRefunds extends Orders { * Prepares one object for create or update operation. * * @since 3.0.0 - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data The prepared item, or \WP_Error object on failure. */ @@ -486,7 +486,7 @@ class OrderRefunds extends Orders { * refers to the object type slug. * * @param WC_Data $coupon Object object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); @@ -496,7 +496,7 @@ class OrderRefunds extends Orders { * Save an object data. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. * @return WC_Data|\WP_Error */ diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index a0b6a7bf253..dc688f87766 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -284,7 +284,7 @@ class Orders extends AbstractObjectsController { * * @since 3.0.0 * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { @@ -305,7 +305,7 @@ class Orders extends AbstractObjectsController { * * @param WP_REST_Response $response The response object. * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } @@ -314,7 +314,7 @@ class Orders extends AbstractObjectsController { * Prepare links for the request. * * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ protected function prepare_links( $object, $request ) { @@ -346,7 +346,7 @@ class Orders extends AbstractObjectsController { * Prepare objects query. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array */ protected function prepare_objects_query( $request ) { @@ -412,7 +412,7 @@ class Orders extends AbstractObjectsController { * Prepare a single order for create or update. * * @throws WC_REST_Exception When fails to set any item. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data */ @@ -474,7 +474,7 @@ class Orders extends AbstractObjectsController { * refers to the object type slug. * * @param WC_Data $order Object object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); @@ -485,7 +485,7 @@ class Orders extends AbstractObjectsController { * * @since 3.0.0 * @throws WC_REST_Exception But all errors are validated before returning any data. - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. * @return WC_Data|\WP_Error */ @@ -1696,7 +1696,7 @@ class Orders extends AbstractObjectsController { * Calculate coupons. * * @throws WC_REST_Exception When fails to set any item. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param WC_Order $order Order data. * @return bool */ diff --git a/src/RestApi/Version4/Controllers/PaymentGateways.php b/src/RestApi/Version4/Controllers/PaymentGateways.php index be8e0aaf69e..65b81a4dc1c 100644 --- a/src/RestApi/Version4/Controllers/PaymentGateways.php +++ b/src/RestApi/Version4/Controllers/PaymentGateways.php @@ -72,7 +72,7 @@ class PaymentGateways extends AbstractController { /** * Check whether a given request has permission to view payment gateways. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -85,7 +85,7 @@ class PaymentGateways extends AbstractController { /** * Check if a given request has access to read a payment gateway. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -98,7 +98,7 @@ class PaymentGateways extends AbstractController { /** * Check whether a given request has permission to edit payment gateways. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_items_permissions_check( $request ) { @@ -111,7 +111,7 @@ class PaymentGateways extends AbstractController { /** * Get payment gateways. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -129,7 +129,7 @@ class PaymentGateways extends AbstractController { /** * Get a single payment gateway. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function get_item( $request ) { @@ -146,7 +146,7 @@ class PaymentGateways extends AbstractController { /** * Update A Single Payment Method. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function update_item( $request ) { @@ -220,7 +220,7 @@ class PaymentGateways extends AbstractController { /** * Get a gateway based on the current request object. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|null */ public function get_gateway( $request ) { @@ -240,7 +240,7 @@ class PaymentGateways extends AbstractController { * Prepare a payment gateway for response. * * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $gateway, $request ) { @@ -269,7 +269,7 @@ class PaymentGateways extends AbstractController { * * @param WP_REST_Response $response The response object. * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); } @@ -317,7 +317,7 @@ class PaymentGateways extends AbstractController { * Prepare links for the request. * * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array */ protected function prepare_links( $gateway, $request ) { diff --git a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php index 98e06768bf7..8a3b4dd413d 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php +++ b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php @@ -131,7 +131,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { * Prepare a single product attribute term output for response. * * @param WP_Term $item Term object. - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { @@ -162,7 +162,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { * * @param WP_REST_Response $response The response object. * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); } @@ -171,7 +171,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { * Update term meta fields. * * @param WP_Term $term Term object. - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. * @return bool|\WP_Error */ protected function update_term_meta_fields( $term, $request ) { diff --git a/src/RestApi/Version4/Controllers/ProductAttributes.php b/src/RestApi/Version4/Controllers/ProductAttributes.php index cfe69d770dd..d6c4fd36ffd 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributes.php +++ b/src/RestApi/Version4/Controllers/ProductAttributes.php @@ -121,7 +121,7 @@ class ProductAttributes extends AbstractController { /** * Check if a given request has access to read the attributes. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -135,7 +135,7 @@ class ProductAttributes extends AbstractController { /** * Check if a given request has access to create a attribute. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { @@ -149,7 +149,7 @@ class ProductAttributes extends AbstractController { /** * Check if a given request has access to read a attribute. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -167,7 +167,7 @@ class ProductAttributes extends AbstractController { /** * Check if a given request has access to update a attribute. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { @@ -185,7 +185,7 @@ class ProductAttributes extends AbstractController { /** * Check if a given request has access to delete a attribute. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function delete_item_permissions_check( $request ) { @@ -203,7 +203,7 @@ class ProductAttributes extends AbstractController { /** * Check if a given request has access batch create, update and delete items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -218,7 +218,7 @@ class ProductAttributes extends AbstractController { /** * Get all attributes. * - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. * @return array */ public function get_items( $request ) { @@ -236,8 +236,8 @@ class ProductAttributes extends AbstractController { /** * Create a single attribute. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function create_item( $request ) { global $wpdb; @@ -269,7 +269,7 @@ class ProductAttributes extends AbstractController { * Fires after a single product attribute is created or updated via the REST API. * * @param stdObject $attribute Inserted attribute object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating attribute, false when updating. */ do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, true ); @@ -286,8 +286,8 @@ class ProductAttributes extends AbstractController { /** * Get a single attribute. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function get_item( $request ) { $attribute = $this->get_attribute( (int) $request['id'] ); @@ -304,8 +304,8 @@ class ProductAttributes extends AbstractController { /** * Update a single term from a taxonomy. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function update_item( $request ) { global $wpdb; @@ -339,7 +339,7 @@ class ProductAttributes extends AbstractController { * Fires after a single product attribute is created or updated via the REST API. * * @param stdObject $attribute Inserted attribute object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating attribute, false when updating. */ do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, false ); @@ -353,7 +353,7 @@ class ProductAttributes extends AbstractController { /** * Delete a single attribute. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { @@ -384,7 +384,7 @@ class ProductAttributes extends AbstractController { * * @param stdObject $attribute The deleted attribute. * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_product_attribute', $attribute, $response, $request ); @@ -395,7 +395,7 @@ class ProductAttributes extends AbstractController { * Prepare a single product attribute output for response. * * @param obj $item Term object. - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { @@ -423,7 +423,7 @@ class ProductAttributes extends AbstractController { * * @param WP_REST_Response $response The response object. * @param object $item The original attribute object. - * @param WP_REST_Request $request Request used to generate the response. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_product_attribute', $response, $item, $request ); } @@ -522,7 +522,7 @@ class ProductAttributes extends AbstractController { /** * Get attribute name. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return string */ protected function get_taxonomy( $request ) { diff --git a/src/RestApi/Version4/Controllers/ProductCategories.php b/src/RestApi/Version4/Controllers/ProductCategories.php index e45eb39e32a..cdcaaa5920b 100644 --- a/src/RestApi/Version4/Controllers/ProductCategories.php +++ b/src/RestApi/Version4/Controllers/ProductCategories.php @@ -34,7 +34,7 @@ class ProductCategories extends AbstractTermsContoller { * Prepare a single product category output for response. * * @param WP_Term $item Term object. - * @param WP_REST_Request $request Request instance. + * @param \WP_REST_Request $request Request instance. * @return WP_REST_Response */ public function prepare_item_for_response( $item, $request ) { @@ -88,7 +88,7 @@ class ProductCategories extends AbstractTermsContoller { * * @param WP_REST_Response $response The response object. * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); } @@ -97,7 +97,7 @@ class ProductCategories extends AbstractTermsContoller { * Update term meta fields. * * @param WP_Term $term Term object. - * @param WP_REST_Request $request Request instance. + * @param \WP_REST_Request $request Request instance. * @return bool|\WP_Error * * @since 3.5.5 diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/RestApi/Version4/Controllers/ProductReviews.php index 0085c145cd2..75696bd1080 100644 --- a/src/RestApi/Version4/Controllers/ProductReviews.php +++ b/src/RestApi/Version4/Controllers/ProductReviews.php @@ -129,7 +129,7 @@ class ProductReviews extends AbstractController { /** * Check whether a given request has permission to read webhook deliveries. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -143,7 +143,7 @@ class ProductReviews extends AbstractController { /** * Check if a given request has access to read a product review. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -160,7 +160,7 @@ class ProductReviews extends AbstractController { /** * Check if a given request has access to create a new product review. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { @@ -174,7 +174,7 @@ class ProductReviews extends AbstractController { /** * Check if a given request has access to update a product review. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { @@ -191,7 +191,7 @@ class ProductReviews extends AbstractController { /** * Check if a given request has access to delete a product review. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function delete_item_permissions_check( $request ) { @@ -208,7 +208,7 @@ class ProductReviews extends AbstractController { /** * Check if a given request has access batch create, update and delete items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return boolean|\WP_Error */ public function batch_items_permissions_check( $request ) { @@ -222,7 +222,7 @@ class ProductReviews extends AbstractController { /** * Get all reviews. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array|\WP_Error */ public function get_items( $request ) { @@ -299,7 +299,7 @@ class ProductReviews extends AbstractController { * @since 3.5.0 * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ * @param array $prepared_args Array of arguments for WP_Comment_Query. - * @param WP_REST_Request $request The current request. + * @param \WP_REST_Request $request The current request. */ $prepared_args = apply_filters( 'woocommerce_rest_product_review_query', $prepared_args, $request ); @@ -364,7 +364,7 @@ class ProductReviews extends AbstractController { /** * Create a single review. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -445,7 +445,7 @@ class ProductReviews extends AbstractController { * * @since 3.5.0 * @param array|\WP_Error $prepared_review The prepared review data for wp_insert_comment(). - * @param WP_REST_Request $request Request used to insert the review. + * @param \WP_REST_Request $request Request used to insert the review. */ $prepared_review = apply_filters( 'woocommerce_rest_pre_insert_product_review', $prepared_review, $request ); if ( is_wp_error( $prepared_review ) ) { @@ -470,7 +470,7 @@ class ProductReviews extends AbstractController { * Fires after a comment is created or updated via the REST API. * * @param WP_Comment $review Inserted or updated comment object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating True when creating a comment, false when updating. */ do_action( 'woocommerce_rest_insert_product_review', $review, $request, true ); @@ -495,7 +495,7 @@ class ProductReviews extends AbstractController { /** * Get a single product review. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -513,7 +513,7 @@ class ProductReviews extends AbstractController { /** * Updates a review. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response Response object on success, or error object on failure. */ public function update_item( $request ) { @@ -599,7 +599,7 @@ class ProductReviews extends AbstractController { /** * Deletes a review. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response Response object on success, or error object on failure. */ public function delete_item( $request ) { @@ -658,7 +658,7 @@ class ProductReviews extends AbstractController { * * @param WP_Comment $review The deleted review data. * @param WP_REST_Response $response The response returned from the API. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_review', $review, $response, $request ); @@ -669,7 +669,7 @@ class ProductReviews extends AbstractController { * Prepare a single product review output for response. * * @param WP_Comment $review Product review object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $review, $request ) { @@ -724,7 +724,7 @@ class ProductReviews extends AbstractController { * * @param WP_REST_Response $response The response object. * @param WP_Comment $review Product review object used to create response. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); } @@ -732,7 +732,7 @@ class ProductReviews extends AbstractController { /** * Prepare a single product review to be inserted into the database. * - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array|\WP_Error $prepared_review */ protected function prepare_item_for_database( $request ) { @@ -777,7 +777,7 @@ class ProductReviews extends AbstractController { * * @since 3.5.0 * @param array $prepared_review The prepared review data for `wp_insert_comment`. - * @param WP_REST_Request $request The current request. + * @param \WP_REST_Request $request The current request. */ return apply_filters( 'woocommerce_rest_preprocess_product_review', $prepared_review, $request ); } diff --git a/src/RestApi/Version4/Controllers/ProductShippingClasses.php b/src/RestApi/Version4/Controllers/ProductShippingClasses.php index 2d23f4538d2..c39c8536444 100644 --- a/src/RestApi/Version4/Controllers/ProductShippingClasses.php +++ b/src/RestApi/Version4/Controllers/ProductShippingClasses.php @@ -34,7 +34,7 @@ class ProductShippingClasses extends AbstractTermsContoller { * Prepare a single product shipping class output for response. * * @param obj $item Term object. - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { @@ -61,7 +61,7 @@ class ProductShippingClasses extends AbstractTermsContoller { * * @param WP_REST_Response $response The response object. * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/ProductTags.php b/src/RestApi/Version4/Controllers/ProductTags.php index 1c88233f4aa..64137497547 100644 --- a/src/RestApi/Version4/Controllers/ProductTags.php +++ b/src/RestApi/Version4/Controllers/ProductTags.php @@ -34,7 +34,7 @@ class ProductTags extends AbstractTermsContoller { * Prepare a single product tag output for response. * * @param obj $item Term object. - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { @@ -61,7 +61,7 @@ class ProductTags extends AbstractTermsContoller { * * @param WP_REST_Response $response The response object. * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); } diff --git a/src/RestApi/Version4/Controllers/ProductVariations.php b/src/RestApi/Version4/Controllers/ProductVariations.php index 66aa74e884a..a1316512337 100644 --- a/src/RestApi/Version4/Controllers/ProductVariations.php +++ b/src/RestApi/Version4/Controllers/ProductVariations.php @@ -148,7 +148,7 @@ class ProductVariations extends Products { /** * Check if a given request has access to update an item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { @@ -170,7 +170,7 @@ class ProductVariations extends Products { * Prepare a single variation output for response. * * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { @@ -237,7 +237,7 @@ class ProductVariations extends Products { * * @param WP_REST_Response $response The response object. * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } @@ -330,7 +330,7 @@ class ProductVariations extends Products { * Prepare objects query. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array */ protected function prepare_objects_query( $request ) { @@ -415,7 +415,7 @@ class ProductVariations extends Products { /** * Prepare a single variation for create or update. * - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data */ @@ -615,7 +615,7 @@ class ProductVariations extends Products { * refers to the object type slug. * * @param WC_Data $variation Object object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); @@ -634,7 +634,7 @@ class ProductVariations extends Products { /** * Delete a variation. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error|WP_REST_Response */ @@ -725,7 +725,7 @@ class ProductVariations extends Products { * * @param WC_Data $object The deleted or trashed object. * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); @@ -736,7 +736,7 @@ class ProductVariations extends Products { * Bulk create, update and delete items. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array Of \WP_Error or WP_REST_Response. */ public function batch_items( $request ) { @@ -759,7 +759,7 @@ class ProductVariations extends Products { } } - $request = new WP_REST_Request( $request->get_method() ); + $request = new \WP_REST_Request( $request->get_method() ); $request->set_body_params( $body_params ); return parent::batch_items( $request ); @@ -769,7 +769,7 @@ class ProductVariations extends Products { * Prepare links for the request. * * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ protected function prepare_links( $object, $request ) { @@ -1200,7 +1200,7 @@ class ProductVariations extends Products { /** * Get a collection of posts and add the post title filter option to \WP_Query. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/RestApi/Version4/Controllers/Products.php index f5ee4bf5167..e843da48e58 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -143,7 +143,7 @@ class Products extends AbstractObjectsController { * Prepare a single product output for response. * * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * * @since 3.0.0 * @return WP_REST_Response @@ -175,7 +175,7 @@ class Products extends AbstractObjectsController { * * @param WP_REST_Response $response The response object. * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } @@ -183,7 +183,7 @@ class Products extends AbstractObjectsController { /** * Prepare a single product for create or update. * - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data */ @@ -584,7 +584,7 @@ class Products extends AbstractObjectsController { * refers to the object type slug. * * @param WC_Data $product Object object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); @@ -593,7 +593,7 @@ class Products extends AbstractObjectsController { /** * Get a collection of posts and add the post title filter option to \WP_Query. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -689,7 +689,7 @@ class Products extends AbstractObjectsController { * Make extra product orderby features supported by WooCommerce available to the WC API. * This includes 'price', 'popularity', and 'rating'. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array */ protected function prepare_objects_query( $request ) { @@ -1171,7 +1171,7 @@ class Products extends AbstractObjectsController { * Prepare links for the request. * * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * * @return array Links for the given post. */ @@ -1365,7 +1365,7 @@ class Products extends AbstractObjectsController { * Save default attributes. * * @param WC_Product $product Product instance. - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * * @since 3.0.0 * @return WC_Product @@ -1435,7 +1435,7 @@ class Products extends AbstractObjectsController { /** * Delete a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return WP_REST_Response|\WP_Error */ @@ -1565,7 +1565,7 @@ class Products extends AbstractObjectsController { * * @param WC_Data $object The deleted or trashed object. * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php index 8893ce02e67..e6727ededf7 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -45,7 +45,7 @@ class Reports extends AbstractController { /** * Check whether a given request has permission to read reports. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -60,7 +60,7 @@ class Reports extends AbstractController { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -189,7 +189,7 @@ class Reports extends AbstractController { * Prepare a report object for serialization. * * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -226,7 +226,7 @@ class Reports extends AbstractController { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Categories.php b/src/RestApi/Version4/Controllers/Reports/Categories.php index 987e0a91249..7929eb8e936 100644 --- a/src/RestApi/Version4/Controllers/Reports/Categories.php +++ b/src/RestApi/Version4/Controllers/Reports/Categories.php @@ -51,7 +51,7 @@ class Categories extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -102,7 +102,7 @@ class Categories extends Reports { * Prepare a report object for serialization. * * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -123,7 +123,7 @@ class Categories extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_categories', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/CouponStats.php b/src/RestApi/Version4/Controllers/Reports/CouponStats.php index c4cd0ae6450..b8c40152a71 100644 --- a/src/RestApi/Version4/Controllers/Reports/CouponStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CouponStats.php @@ -49,7 +49,7 @@ class CouponStats extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -99,7 +99,7 @@ class CouponStats extends Reports { * Prepare a report object for serialization. * * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -119,7 +119,7 @@ class CouponStats extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_coupons_stats', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Coupons.php b/src/RestApi/Version4/Controllers/Reports/Coupons.php index 154378ad514..59dd8ac40b4 100644 --- a/src/RestApi/Version4/Controllers/Reports/Coupons.php +++ b/src/RestApi/Version4/Controllers/Reports/Coupons.php @@ -47,7 +47,7 @@ class Coupons extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -90,7 +90,7 @@ class Coupons extends Reports { * Prepare a report object for serialization. * * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -111,7 +111,7 @@ class Coupons extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_coupons', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php index 5f7d3d28fd1..be1c23cda27 100644 --- a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php @@ -69,7 +69,7 @@ class CustomerStats extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -87,7 +87,7 @@ class CustomerStats extends Reports { * Prepare a report object for serialization. * * @param Array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -107,7 +107,7 @@ class CustomerStats extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_customers_stats', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Customers.php b/src/RestApi/Version4/Controllers/Reports/Customers.php index 90f490ccd5c..7177a7b7b4f 100644 --- a/src/RestApi/Version4/Controllers/Reports/Customers.php +++ b/src/RestApi/Version4/Controllers/Reports/Customers.php @@ -76,7 +76,7 @@ class Customers extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -119,7 +119,7 @@ class Customers extends Reports { * Prepare a report object for serialization. * * @param array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -141,7 +141,7 @@ class Customers extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_customers', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php index 0ceb11c5379..e0811dd72e9 100644 --- a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php +++ b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php @@ -56,7 +56,7 @@ class DownloadStats extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -102,7 +102,7 @@ class DownloadStats extends Reports { * Prepare a report object for serialization. * * @param Array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -122,7 +122,7 @@ class DownloadStats extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_downloads_stats', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Downloads.php b/src/RestApi/Version4/Controllers/Reports/Downloads.php index 8b68663f6a0..e1b3bf61230 100644 --- a/src/RestApi/Version4/Controllers/Reports/Downloads.php +++ b/src/RestApi/Version4/Controllers/Reports/Downloads.php @@ -28,7 +28,7 @@ class Downloads extends Reports { /** * Get items. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -79,7 +79,7 @@ class Downloads extends Reports { * Prepare a report object for serialization. * * @param Array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -114,7 +114,7 @@ class Downloads extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_downloads', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Import.php b/src/RestApi/Version4/Controllers/Reports/Import.php index 2d329136632..57c5dc5a544 100644 --- a/src/RestApi/Version4/Controllers/Reports/Import.php +++ b/src/RestApi/Version4/Controllers/Reports/Import.php @@ -96,7 +96,7 @@ class Import extends Reports { /** * Makes sure the current user has access to WRITE the settings APIs. * - * @param WP_REST_Request $request Full data about the request. + * @param \WP_REST_Request $request Full data about the request. * @return \WP_Error|bool */ public function import_permissions_check( $request ) { @@ -109,7 +109,7 @@ class Import extends Reports { /** * Import data based on user request params. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function import_items( $request ) { @@ -137,7 +137,7 @@ class Import extends Reports { /** * Prepare request object as query args. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array */ protected function prepare_objects_query( $request ) { @@ -152,7 +152,7 @@ class Import extends Reports { * Prepare the data object for response. * * @param object $item Data object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -165,7 +165,7 @@ class Import extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_reports_import', $response, $item, $request ); } @@ -226,7 +226,7 @@ class Import extends Reports { /** * Cancel all queued import actions. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function cancel_import( $request ) { @@ -246,7 +246,7 @@ class Import extends Reports { /** * Delete all imported items. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function delete_imported_items( $request ) { @@ -273,7 +273,7 @@ class Import extends Reports { /** * Get the status of the current import. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_import_status( $request ) { @@ -295,7 +295,7 @@ class Import extends Reports { /** * Get the total orders and customers based on user supplied params. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_import_totals( $request ) { diff --git a/src/RestApi/Version4/Controllers/Reports/OrderStats.php b/src/RestApi/Version4/Controllers/Reports/OrderStats.php index abd50fe495d..faf23e7a79d 100644 --- a/src/RestApi/Version4/Controllers/Reports/OrderStats.php +++ b/src/RestApi/Version4/Controllers/Reports/OrderStats.php @@ -59,7 +59,7 @@ class OrderStats extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -109,7 +109,7 @@ class OrderStats extends Reports { * Prepare a report object for serialization. * * @param Array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -129,7 +129,7 @@ class OrderStats extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_orders_stats', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Orders.php b/src/RestApi/Version4/Controllers/Reports/Orders.php index 50a02acdb10..e0bdb1f1f8a 100644 --- a/src/RestApi/Version4/Controllers/Reports/Orders.php +++ b/src/RestApi/Version4/Controllers/Reports/Orders.php @@ -54,7 +54,7 @@ class Orders extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -98,7 +98,7 @@ class Orders extends Reports { * Prepare a report object for serialization. * * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -119,7 +119,7 @@ class Orders extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_orders', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php index ed85445c06c..88e485eab09 100644 --- a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php +++ b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php @@ -111,7 +111,7 @@ class PerformanceIndicators extends Reports { return true; } - $request = new WP_REST_Request( 'GET', '/wc/v4/reports' ); + $request = new \WP_REST_Request( 'GET', '/wc/v4/reports' ); $response = rest_do_request( $request ); $endpoints = $response->get_data(); $allowed_stats = array(); @@ -121,7 +121,7 @@ class PerformanceIndicators extends Reports { foreach ( $endpoints as $endpoint ) { if ( '/stats' === substr( $endpoint['slug'], -6 ) ) { - $request = new WP_REST_Request( 'OPTIONS', $endpoint['path'] ); + $request = new \WP_REST_Request( 'OPTIONS', $endpoint['path'] ); $response = rest_do_request( $request ); $data = $response->get_data(); @@ -155,7 +155,7 @@ class PerformanceIndicators extends Reports { /** * Returns a list of allowed performance indicators. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_allowed_items( $request ) { @@ -244,7 +244,7 @@ class PerformanceIndicators extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -271,7 +271,7 @@ class PerformanceIndicators extends Reports { } $request_url = $this->endpoints[ $report ]; - $request = new WP_REST_Request( 'GET', $request_url ); + $request = new \WP_REST_Request( 'GET', $request_url ); $request->set_param( 'before', $query_args['before'] ); $request->set_param( 'after', $query_args['after'] ); @@ -322,7 +322,7 @@ class PerformanceIndicators extends Reports { * Prepare a report object for serialization. * * @param stdClass $stat_data Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $stat_data, $request ) { @@ -342,7 +342,7 @@ class PerformanceIndicators extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_performance_indicators', $response, $stat_data, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/ProductStats.php b/src/RestApi/Version4/Controllers/Reports/ProductStats.php index 1539aa97ea0..19c7e5e40a3 100644 --- a/src/RestApi/Version4/Controllers/Reports/ProductStats.php +++ b/src/RestApi/Version4/Controllers/Reports/ProductStats.php @@ -44,7 +44,7 @@ class ProductStats extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -114,7 +114,7 @@ class ProductStats extends Reports { * Prepare a report object for serialization. * * @param Array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -134,7 +134,7 @@ class ProductStats extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_products_stats', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Products.php b/src/RestApi/Version4/Controllers/Reports/Products.php index 56bc5e6edff..299687f04f1 100644 --- a/src/RestApi/Version4/Controllers/Reports/Products.php +++ b/src/RestApi/Version4/Controllers/Reports/Products.php @@ -37,7 +37,7 @@ class Products extends Reports { /** * Get items. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * * @return array|\WP_Error */ @@ -92,7 +92,7 @@ class Products extends Reports { * Prepare a report object for serialization. * * @param Array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -113,7 +113,7 @@ class Products extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_products', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php index 4e34d6e1fa7..38a586e4dff 100644 --- a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php +++ b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php @@ -48,7 +48,7 @@ class RevenueStats extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -98,7 +98,7 @@ class RevenueStats extends Reports { * Prepare a report object for serialization. * * @param Array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -118,7 +118,7 @@ class RevenueStats extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_revenue_stats', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Stock.php b/src/RestApi/Version4/Controllers/Reports/Stock.php index df7f798906d..4967d31aaba 100644 --- a/src/RestApi/Version4/Controllers/Reports/Stock.php +++ b/src/RestApi/Version4/Controllers/Reports/Stock.php @@ -28,7 +28,7 @@ class Stock extends Reports { /** * Maps query arguments from the REST request. * - * @param WP_REST_Request $request Request array. + * @param \WP_REST_Request $request Request array. * @return array */ protected function prepare_reports_query( $request ) { @@ -139,7 +139,7 @@ class Stock extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -182,7 +182,7 @@ class Stock extends Reports { * Prepare a report object for serialization. * * @param WC_Product $product Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $product, $request ) { @@ -211,7 +211,7 @@ class Stock extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_stock', $response, $product, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/StockStats.php b/src/RestApi/Version4/Controllers/Reports/StockStats.php index f9524fe115b..df3b371c1cb 100644 --- a/src/RestApi/Version4/Controllers/Reports/StockStats.php +++ b/src/RestApi/Version4/Controllers/Reports/StockStats.php @@ -28,7 +28,7 @@ class StockStats extends Reports { /** * Get Stock Status Totals. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -44,7 +44,7 @@ class StockStats extends Reports { * Prepare a report object for serialization. * * @param WC_Product $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -64,7 +64,7 @@ class StockStats extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_stock_stats', $response, $product, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/TaxStats.php b/src/RestApi/Version4/Controllers/Reports/TaxStats.php index 0d0aa5cc825..3b15000dacf 100644 --- a/src/RestApi/Version4/Controllers/Reports/TaxStats.php +++ b/src/RestApi/Version4/Controllers/Reports/TaxStats.php @@ -79,7 +79,7 @@ class TaxStats extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -125,7 +125,7 @@ class TaxStats extends Reports { * Prepare a report object for serialization. * * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -145,7 +145,7 @@ class TaxStats extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_taxes_stats', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Taxes.php b/src/RestApi/Version4/Controllers/Reports/Taxes.php index 6ae0e6ed8fb..4c59faf3838 100644 --- a/src/RestApi/Version4/Controllers/Reports/Taxes.php +++ b/src/RestApi/Version4/Controllers/Reports/Taxes.php @@ -47,7 +47,7 @@ class Taxes extends Reports { /** * Get all reports. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return array|\WP_Error */ public function get_items( $request ) { @@ -90,7 +90,7 @@ class Taxes extends Reports { * Prepare a report object for serialization. * * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -109,7 +109,7 @@ class Taxes extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_taxes', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Reports/Variations.php b/src/RestApi/Version4/Controllers/Reports/Variations.php index 206272ea1ee..3d162c472c5 100644 --- a/src/RestApi/Version4/Controllers/Reports/Variations.php +++ b/src/RestApi/Version4/Controllers/Reports/Variations.php @@ -37,7 +37,7 @@ class Variations extends Reports { /** * Get items. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * * @return array|\WP_Error */ @@ -92,7 +92,7 @@ class Variations extends Reports { * Prepare a report object for serialization. * * @param array $report Report data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { @@ -113,7 +113,7 @@ class Variations extends Reports { * * @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. + * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_report_variations', $response, $report, $request ); } diff --git a/src/RestApi/Version4/Controllers/Settings.php b/src/RestApi/Version4/Controllers/Settings.php index d5c748c2ea3..08e9aea2271 100644 --- a/src/RestApi/Version4/Controllers/Settings.php +++ b/src/RestApi/Version4/Controllers/Settings.php @@ -58,7 +58,7 @@ class Settings extends AbstractController { /** * Makes sure the current user has access to WRITE the settings APIs. * - * @param WP_REST_Request $request Full data about the request. + * @param \WP_REST_Request $request Full data about the request. * @return \WP_Error|bool */ public function update_items_permissions_check( $request ) { @@ -72,7 +72,7 @@ class Settings extends AbstractController { /** * Update a setting. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -86,7 +86,7 @@ class Settings extends AbstractController { * Get all settings groups items. * * @since 3.0.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -142,7 +142,7 @@ class Settings extends AbstractController { * * @since 3.0.0 * @param array $item Group object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -203,7 +203,7 @@ class Settings extends AbstractController { * Makes sure the current user has access to READ the settings APIs. * * @since 3.0.0 - * @param WP_REST_Request $request Full data about the request. + * @param \WP_REST_Request $request Full data about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { diff --git a/src/RestApi/Version4/Controllers/SettingsOptions.php b/src/RestApi/Version4/Controllers/SettingsOptions.php index d0cd3105ce6..7a7e8eb8575 100644 --- a/src/RestApi/Version4/Controllers/SettingsOptions.php +++ b/src/RestApi/Version4/Controllers/SettingsOptions.php @@ -102,7 +102,7 @@ class SettingsOptions extends AbstractController { * Return a single setting. * * @since 3.0.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -121,7 +121,7 @@ class SettingsOptions extends AbstractController { * Return all settings in a group. * * @since 3.0.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -273,7 +273,7 @@ class SettingsOptions extends AbstractController { * Bulk create, update and delete items. * * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return array Of \WP_Error or WP_REST_Response. */ public function batch_items( $request ) { @@ -289,7 +289,7 @@ class SettingsOptions extends AbstractController { foreach ( $items['update'] as $item ) { $to_update[] = array_merge( $request->get_url_params(), $item ); } - $request = new WP_REST_Request( $request->get_method() ); + $request = new \WP_REST_Request( $request->get_method() ); $request->set_body_params( array( 'update' => $to_update ) ); } @@ -300,7 +300,7 @@ class SettingsOptions extends AbstractController { * Update a single setting in a group. * * @since 3.0.0 - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -343,7 +343,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param object $item Setting object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { @@ -382,7 +382,7 @@ class SettingsOptions extends AbstractController { * Makes sure the current user has access to READ the settings APIs. * * @since 3.0.0 - * @param WP_REST_Request $request Full data about the request. + * @param \WP_REST_Request $request Full data about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -397,7 +397,7 @@ class SettingsOptions extends AbstractController { * Makes sure the current user has access to WRITE the settings APIs. * * @since 3.0.0 - * @param WP_REST_Request $request Full data about the request. + * @param \WP_REST_Request $request Full data about the request. * @return \WP_Error|boolean */ public function update_items_permissions_check( $request ) { diff --git a/src/RestApi/Version4/Controllers/ShippingMethods.php b/src/RestApi/Version4/Controllers/ShippingMethods.php index 68b30fa2a9e..357a9e7c4b7 100644 --- a/src/RestApi/Version4/Controllers/ShippingMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingMethods.php @@ -66,7 +66,7 @@ class ShippingMethods extends AbstractController { /** * Check whether a given request has permission to view shipping methods. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -79,7 +79,7 @@ class ShippingMethods extends AbstractController { /** * Check if a given request has access to read a shipping method. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -92,7 +92,7 @@ class ShippingMethods extends AbstractController { /** * Get shipping methods. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -109,7 +109,7 @@ class ShippingMethods extends AbstractController { /** * Get a single Shipping Method. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function get_item( $request ) { @@ -129,7 +129,7 @@ class ShippingMethods extends AbstractController { * Prepare a shipping method for response. * * @param WC_Shipping_Method $method Shipping method object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $method, $request ) { @@ -153,7 +153,7 @@ class ShippingMethods extends AbstractController { * * @param WP_REST_Response $response The response object. * @param WC_Shipping_Method $method Shipping method object used to create response. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_shipping_method', $response, $method, $request ); } @@ -162,7 +162,7 @@ class ShippingMethods extends AbstractController { * Prepare links for the request. * * @param WC_Shipping_Method $method Shipping method object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return array */ protected function prepare_links( $method, $request ) { diff --git a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php index 3f4bf6ac116..52af3e6ce46 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php @@ -49,7 +49,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { /** * Get all Shipping Zone Locations. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function get_items( $request ) { @@ -74,7 +74,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { /** * Update all Shipping Zone Locations. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function update_items( $request ) { @@ -118,7 +118,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { * Prepare the Shipping Zone Location for the REST response. * * @param array $item Shipping Zone Location. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { diff --git a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php index b90b5aea41e..4791455aa7f 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php @@ -99,7 +99,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { /** * Get a single Shipping Zone Method. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function get_item( $request ) { @@ -132,7 +132,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { /** * Get all Shipping Zone Methods. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function get_items( $request ) { @@ -156,8 +156,8 @@ class ShippingZoneMethods extends AbstractShippingZonesController { /** * Create a new shipping zone method instance. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function create_item( $request ) { $method_id = $request['method_id']; @@ -192,7 +192,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { /** * Delete a shipping method instance. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function delete_item( $request ) { @@ -238,7 +238,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * * @param object $method * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'rest_delete_product_review', $method, $response, $request ); @@ -248,7 +248,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { /** * Update A Single Shipping Zone Method. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function update_item( $request ) { @@ -286,7 +286,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * * @param int $instance_id Instance ID. * @param WC_Shipping_Method $method Shipping method data. - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * * @return WC_Shipping_Method */ @@ -341,7 +341,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Prepare the Shipping Zone Method for the REST response. * * @param array $item Shipping Zone Method. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { diff --git a/src/RestApi/Version4/Controllers/ShippingZones.php b/src/RestApi/Version4/Controllers/ShippingZones.php index c58aa6dd792..e5621ae48f5 100644 --- a/src/RestApi/Version4/Controllers/ShippingZones.php +++ b/src/RestApi/Version4/Controllers/ShippingZones.php @@ -89,7 +89,7 @@ class ShippingZones extends AbstractShippingZonesController { /** * Get a single Shipping Zone. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response|\WP_Error */ public function get_item( $request ) { @@ -109,7 +109,7 @@ class ShippingZones extends AbstractShippingZonesController { /** * Get all Shipping Zones. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return WP_REST_Response */ public function get_items( $request ) { @@ -131,8 +131,8 @@ class ShippingZones extends AbstractShippingZonesController { /** * Create a single Shipping Zone. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function create_item( $request ) { $zone = new \WC_Shipping_Zone( null ); @@ -161,8 +161,8 @@ class ShippingZones extends AbstractShippingZonesController { /** * Update a single Shipping Zone. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function update_item( $request ) { $zone = $this->get_zone( $request->get_param( 'id' ) ); @@ -197,8 +197,8 @@ class ShippingZones extends AbstractShippingZonesController { /** * Delete a single Shipping Zone. * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|\WP_Error + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Request|\WP_Error */ public function delete_item( $request ) { $zone = $this->get_zone( $request->get_param( 'id' ) ); @@ -224,7 +224,7 @@ class ShippingZones extends AbstractShippingZonesController { * Prepare the Shipping Zone for the REST response. * * @param array $item Shipping Zone. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { diff --git a/src/RestApi/Version4/Controllers/SystemStatus.php b/src/RestApi/Version4/Controllers/SystemStatus.php index 569f7814d31..ea2c0d4fdf1 100644 --- a/src/RestApi/Version4/Controllers/SystemStatus.php +++ b/src/RestApi/Version4/Controllers/SystemStatus.php @@ -45,7 +45,7 @@ class SystemStatus extends AbstractController { /** * Check whether a given request has permission to view system status. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -58,7 +58,7 @@ class SystemStatus extends AbstractController { /** * Get a system status info, by section. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -1150,7 +1150,7 @@ class SystemStatus extends AbstractController { * Prepare the system status response * * @param array $system_status System status data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $system_status, $request ) { @@ -1164,7 +1164,7 @@ class SystemStatus extends AbstractController { * * @param WP_REST_Response $response The response object. * @param mixed $system_status System status - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_system_status', $response, $system_status, $request ); } diff --git a/src/RestApi/Version4/Controllers/SystemStatusTools.php b/src/RestApi/Version4/Controllers/SystemStatusTools.php index e2cb1017058..734febcd1fe 100644 --- a/src/RestApi/Version4/Controllers/SystemStatusTools.php +++ b/src/RestApi/Version4/Controllers/SystemStatusTools.php @@ -70,7 +70,7 @@ class SystemStatusTools extends AbstractController { /** * Check whether a given request has permission to view system status tools. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -83,7 +83,7 @@ class SystemStatusTools extends AbstractController { /** * Check whether a given request has permission to view a specific system status tool. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -96,7 +96,7 @@ class SystemStatusTools extends AbstractController { /** * Check whether a given request has permission to execute a specific system status tool. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { @@ -203,7 +203,7 @@ class SystemStatusTools extends AbstractController { /** * Get a list of system status tools. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -229,7 +229,7 @@ class SystemStatusTools extends AbstractController { /** * Return a single tool. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -254,7 +254,7 @@ class SystemStatusTools extends AbstractController { /** * Update (execute) a tool. * - * @param WP_REST_Request $request Request data. + * @param \WP_REST_Request $request Request data. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -278,7 +278,7 @@ class SystemStatusTools extends AbstractController { * Fires after a WooCommerce REST system status tool has been executed. * * @param array $tool Details about the tool that has been executed. - * @param WP_REST_Request $request The current WP_REST_Request object. + * @param \WP_REST_Request $request The current \WP_REST_Request object. */ do_action( 'woocommerce_rest_insert_system_status_tool', $tool, $request ); @@ -291,7 +291,7 @@ class SystemStatusTools extends AbstractController { * Prepare a tool item for serialization. * * @param array $item Object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/RestApi/Version4/Controllers/TaxClasses.php index 408bc2e3e74..58324ce45e4 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -77,7 +77,7 @@ class TaxClasses extends AbstractController { /** * Check whether a given request has permission to read tax classes. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -91,7 +91,7 @@ class TaxClasses extends AbstractController { /** * Check if a given request has access create tax classes. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -106,7 +106,7 @@ class TaxClasses extends AbstractController { /** * Check if a given request has access delete a tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -121,7 +121,7 @@ class TaxClasses extends AbstractController { /** * Get all tax classes. * - * @param WP_REST_Request $request Request params. + * @param \WP_REST_Request $request Request params. * @return array */ public function get_items( $request ) { @@ -155,7 +155,7 @@ class TaxClasses extends AbstractController { /** * Create a single tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -190,7 +190,7 @@ class TaxClasses extends AbstractController { * Fires after a tax class is created or updated via the REST API. * * @param stdClass $tax_class Data used to create the tax class. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating tax class, false when updating tax class. */ do_action( 'woocommerce_rest_insert_tax_class', (object) $tax_class, $request, true ); @@ -207,7 +207,7 @@ class TaxClasses extends AbstractController { /** * Delete a single tax class. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function delete_item( $request ) { @@ -268,7 +268,7 @@ class TaxClasses extends AbstractController { * * @param stdClass $tax_class The tax data. * @param WP_REST_Response $response The response returned from the API. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_tax', (object) $tax_class, $response, $request ); @@ -279,7 +279,7 @@ class TaxClasses extends AbstractController { * Prepare a single tax class output for response. * * @param array $tax_class Tax class data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $tax_class, $request ) { @@ -299,7 +299,7 @@ class TaxClasses extends AbstractController { * * @param WP_REST_Response $response The response object. * @param stdClass $tax_class Tax object used to create response. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_tax', $response, (object) $tax_class, $request ); } diff --git a/src/RestApi/Version4/Controllers/Taxes.php b/src/RestApi/Version4/Controllers/Taxes.php index 3617d63129a..7218745c131 100644 --- a/src/RestApi/Version4/Controllers/Taxes.php +++ b/src/RestApi/Version4/Controllers/Taxes.php @@ -105,7 +105,7 @@ class Taxes extends AbstractController { /** * Check whether a given request has permission to read taxes. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -119,7 +119,7 @@ class Taxes extends AbstractController { /** * Check if a given request has access create taxes. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -134,7 +134,7 @@ class Taxes extends AbstractController { /** * Check if a given request has access to read a tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -148,7 +148,7 @@ class Taxes extends AbstractController { /** * Check if a given request has access update a tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -163,7 +163,7 @@ class Taxes extends AbstractController { /** * Check if a given request has access delete a tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -178,7 +178,7 @@ class Taxes extends AbstractController { /** * Check if a given request has access batch create, update and delete items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -193,7 +193,7 @@ class Taxes extends AbstractController { /** * Get all taxes and allow filtering by tax code. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -220,7 +220,7 @@ class Taxes extends AbstractController { * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. * * @param array $prepared_args Array of arguments for $wpdb->get_results(). - * @param WP_REST_Request $request The current request. + * @param \WP_REST_Request $request The current request. */ $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request ); @@ -302,7 +302,7 @@ class Taxes extends AbstractController { /** * Take tax data from the request and return the updated or newly created rate. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @param stdClass|null $current Existing tax object. * @return object */ @@ -372,7 +372,7 @@ class Taxes extends AbstractController { /** * Create a single tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -388,7 +388,7 @@ class Taxes extends AbstractController { * Fires after a tax is created or updated via the REST API. * * @param stdClass $tax Data used to create the tax. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating tax, false when updating tax. */ do_action( 'woocommerce_rest_insert_tax', $tax, $request, true ); @@ -405,7 +405,7 @@ class Taxes extends AbstractController { /** * Get a single tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -425,7 +425,7 @@ class Taxes extends AbstractController { /** * Update a single tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -444,7 +444,7 @@ class Taxes extends AbstractController { * Fires after a tax is created or updated via the REST API. * * @param stdClass $tax Data used to create the tax. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating tax, false when updating tax. */ do_action( 'woocommerce_rest_insert_tax', $tax, $request, false ); @@ -459,7 +459,7 @@ class Taxes extends AbstractController { /** * Delete a single tax. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function delete_item( $request ) { @@ -493,7 +493,7 @@ class Taxes extends AbstractController { * * @param stdClass $tax The tax data. * @param WP_REST_Response $response The response returned from the API. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request ); @@ -504,7 +504,7 @@ class Taxes extends AbstractController { * Prepare a single tax output for response. * * @param stdClass $tax Tax object. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $tax, $request ) { @@ -558,7 +558,7 @@ class Taxes extends AbstractController { * * @param WP_REST_Response $response The response object. * @param stdClass $tax Tax object used to create response. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_tax', $response, $tax, $request ); } diff --git a/src/RestApi/Version4/Controllers/Webhooks.php b/src/RestApi/Version4/Controllers/Webhooks.php index 27c41c09a0b..b72f13ae2ad 100644 --- a/src/RestApi/Version4/Controllers/Webhooks.php +++ b/src/RestApi/Version4/Controllers/Webhooks.php @@ -111,7 +111,7 @@ class Webhooks extends AbstractController { /** * Check whether a given request has permission to read webhooks. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { @@ -125,7 +125,7 @@ class Webhooks extends AbstractController { /** * Check if a given request has access create webhooks. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -140,7 +140,7 @@ class Webhooks extends AbstractController { /** * Check if a given request has access to read a webhook. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { @@ -154,7 +154,7 @@ class Webhooks extends AbstractController { /** * Check if a given request has access update a webhook. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -169,7 +169,7 @@ class Webhooks extends AbstractController { /** * Check if a given request has access delete a webhook. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -184,7 +184,7 @@ class Webhooks extends AbstractController { /** * Check if a given request has access batch create, update and delete items. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * * @return bool|\WP_Error */ @@ -209,7 +209,7 @@ class Webhooks extends AbstractController { /** * Get all webhooks. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { @@ -232,7 +232,7 @@ class Webhooks extends AbstractController { * Filter arguments, before passing to WC_Webhook_Data_Store->search_webhooks, when querying webhooks via the REST API. * * @param array $args Array of arguments for $wpdb->get_results(). - * @param WP_REST_Request $request The current request. + * @param \WP_REST_Request $request The current request. */ $prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request ); unset( $prepared_args['page'] ); @@ -279,7 +279,7 @@ class Webhooks extends AbstractController { /** * Get a single item. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function get_item( $request ) { @@ -298,7 +298,7 @@ class Webhooks extends AbstractController { /** * Create a single webhook. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function create_item( $request ) { @@ -338,7 +338,7 @@ class Webhooks extends AbstractController { * Fires after a single item is created or updated via the REST API. * * @param WC_Webhook $webhook Webhook data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating True when creating item, false when updating. */ do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, true ); @@ -358,7 +358,7 @@ class Webhooks extends AbstractController { /** * Update a single webhook. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|WP_REST_Response */ public function update_item( $request ) { @@ -418,7 +418,7 @@ class Webhooks extends AbstractController { * Fires after a single item is created or updated via the REST API. * * @param WC_Webhook $webhook Webhook data. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @param bool $creating True when creating item, false when updating. */ do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, false ); @@ -432,7 +432,7 @@ class Webhooks extends AbstractController { /** * Delete a single webhook. * - * @param WP_REST_Request $request Full details about the request. + * @param \WP_REST_Request $request Full details about the request. * @return WP_REST_Response|\WP_Error */ public function delete_item( $request ) { @@ -464,7 +464,7 @@ class Webhooks extends AbstractController { * * @param WC_Webhook $webhook The deleted or trashed item. * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_webhook_object", $webhook, $response, $request ); @@ -474,7 +474,7 @@ class Webhooks extends AbstractController { /** * Prepare a single webhook for create or update. * - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return \WP_Error|stdClass $data Post object. */ protected function prepare_item_for_database( $request ) { @@ -519,7 +519,7 @@ class Webhooks extends AbstractController { * * @param stdClass $data An object representing a single item prepared * for inserting or updating the database. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $data, $request ); } @@ -528,7 +528,7 @@ class Webhooks extends AbstractController { * Prepare a single webhook output for response. * * @param int $id Webhook ID. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. * @return WP_REST_Response $response */ public function prepare_item_for_response( $id, $request ) { @@ -567,7 +567,7 @@ class Webhooks extends AbstractController { * * @param WP_REST_Response $response The response object. * @param WC_Webhook $webhook Webhook object used to create response. - * @param WP_REST_Request $request Request object. + * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); } From 1aee7b5644310f46ecfdf024f8a6c02440999d0f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 11:52:27 +0100 Subject: [PATCH 049/440] Add post_type_counts to status API --- src/RestApi/Version4/Controllers/SystemStatus.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/RestApi/Version4/Controllers/SystemStatus.php b/src/RestApi/Version4/Controllers/SystemStatus.php index ea2c0d4fdf1..d9c53b3c428 100644 --- a/src/RestApi/Version4/Controllers/SystemStatus.php +++ b/src/RestApi/Version4/Controllers/SystemStatus.php @@ -544,6 +544,15 @@ class SystemStatus extends AbstractController { 'type' => 'string', ), ), + 'post_type_counts' => array( + 'description' => __( 'Post type counts.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), ), ); @@ -566,6 +575,7 @@ class SystemStatus extends AbstractController { 'settings' => $this->get_settings(), 'security' => $this->get_security_info(), 'pages' => $this->get_pages(), + 'post_type_counts' => $this->get_post_type_counts(), ); } @@ -745,13 +755,13 @@ class SystemStatus extends AbstractController { ); $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); - $global_tables = $wpdb->tables( 'global', true ); + $global_tables = $wpdb->tables( 'global', true ); foreach ( $database_table_information as $table ) { // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { continue; } - $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce' : 'other'; + $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; $tables[ $table_type ][ $table->name ] = array( 'data' => $table->data, From 60a5a8a0ff868adc034e2d90f47f2209dc218c01 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 12:31:43 +0100 Subject: [PATCH 050/440] Update readme file --- README.md | 58 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index dd792585a9c..bf6d658bea9 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,54 @@ ---- -title: 'WooCommerce REST API' ---- - WooCommerce REST API === -This repository houses the WooCommerce REST API found in the core WooCommerce plugin. +This repository is home to the WooCommerce REST API package. -It can also be used as a standalone plugin (it still requires WooCommerce!), or can be pulled into other projects and feature plugins that need new API features that are not yet in the core release. +The stable version of this package is bundled with [WooCommerce core](https://github.com/woocommerce/woocommerce) releases, but it can also be used as a standalone plugin so bleeding-edge API features can be tested or used by other feature plugins. -Once stable, changes in woocommerce-rest-api are brought over to [WooCommerce core](https://github.com/woocommerce/woocommerce) when they are ready for release. +## Using this package -## Endpoint namespaces +This package is [hosted on Packagist](https://packagist.org/packages/woocommerce/woocommerce-rest-api) and can be included using composer.json: -* Current stable WC REST API version: **wc/v3** - **[Docs](https://woocommerce.github.io/woocommerce-rest-api-docs/)** -* WC Blocks REST API version (internal use only): **wc-blocks/v1** -* Older versions: - * **wc/v1** - **[Docs](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v1.html)** - * **wc/v2** - **[Docs](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v2.html)** +```json +"require": { + "woocommerce/woocommerce-rest-api": "1.0.0" +}, +``` + +Since multiple versions of this package may be included at the same time, WooCommerce handles loading __only the latest version__ by using a special loader. + +After including the package and installing dependencies, include the main `woocommerce-rest-api.php` file in your code: + +```php +include 'vendor/woocommerce-rest-api/woocommerce-rest-api.php'; +``` + +This will register the version of the package with WooCommerce and make it available after the `woocommerce_loaded` hook is fired. + +## API documentation + +- [Usage documentation for the REST API can be found here](https://github.com/woocommerce/woocommerce/wiki/Getting-started-with-the-REST-API). +- [Contribution documentation can be found here.](https://github.com/woocommerce/woocommerce/wiki/Contributing-to-the-WooCommerce-REST-API) + +### Versions + +| Namespace | Status | Docs | +| -------- | -------- | -------- | +| `wc/v4` | Development | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/) | +| `wc/v3` | Stable | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/) | +| `wc/v2` | Deprecated - October 2020 | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v2.html) | +| `wc/v1` | Deprecated - April 2019 | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v1.html) | + +Note: API Versions are kept around for 2 years after being replaced, and may be removed in the next major version after that date passes. ## Contributing -Please read the [WooCommerce contributor guidelines](https://github.com/woocommerce/woocommerce/blob/master/.github/CONTRIBUTING.md) for more information how you can contribute. +Please read the [WooCommerce contributor guidelines](https://github.com/woocommerce/woocommerce/blob/master/.github/CONTRIBUTING.md) for more information how you can contribute to WooCommerce, and [the REST API contribution documentation here](https://github.com/woocommerce/woocommerce/wiki/Contributing-to-the-WooCommerce-REST-API). -Endpoints are located in the `includes/` directory. Endpoints currently inherit from the stable version of the endpoint. If you need to change the behavior of an endpoint, you can do so in these classes. +Within this package, namespaces and endpoint classes are located within the `src/RestAPI/` directory. If you need to change the behavior of an endpoint, you can do so in these classes. -phpunit tests for the API are located in the `tests/unit-tests/` folder and are also merged and shipped with WooCommerce core. You can use the same helpers/framework files that core uses, or introduce new ones. - -Run tests using `phpunit` in the root of this folder. Code coverage reports can be ran with `phpunit --coverage-html /tmp/coverage`. +Run tests using `phpunit` in the root of the package. All pull-requests must pass unit tests in order to be accepted. ## Translation -For strings located in API endpoints, use `woocommerce` as your text-domain. These endpoints will at some point be merged back into WooCommerce Core. +For strings located in API endpoints, use `woocommerce` as your text-domain. These endpoints will be translated in the WooCommerce Core PO/MO files. From 6cbe095fc65837fc16d9fd9ea24a2cedc3017757 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 14:08:22 +0100 Subject: [PATCH 051/440] Endpoints should overwrite --- .../Controllers/AbstractTermsContoller.php | 9 +- src/RestApi/Version4/Controllers/Coupons.php | 9 +- .../Controllers/CustomerDownloads.php | 3 +- .../Version4/Controllers/Customers.php | 9 +- src/RestApi/Version4/Controllers/Data.php | 3 +- .../Version4/Controllers/Leaderboards.php | 6 +- .../Version4/Controllers/NetworkOrders.php | 3 +- .../Version4/Controllers/OrderNotes.php | 114 ++++++++------- .../Version4/Controllers/OrderRefunds.php | 6 +- src/RestApi/Version4/Controllers/Orders.php | 9 +- .../Version4/Controllers/PaymentGateways.php | 6 +- .../Controllers/ProductAttributeTerms.php | 9 +- .../Controllers/ProductAttributes.php | 9 +- .../Version4/Controllers/ProductReviews.php | 9 +- .../Controllers/ProductVariations.php | 9 +- src/RestApi/Version4/Controllers/Products.php | 9 +- src/RestApi/Version4/Controllers/Reports.php | 3 +- src/RestApi/Version4/Controllers/Settings.php | 6 +- .../Version4/Controllers/SettingsOptions.php | 9 +- .../Version4/Controllers/ShippingMethods.php | 6 +- .../Controllers/ShippingZoneLocations.php | 3 +- .../Controllers/ShippingZoneMethods.php | 6 +- .../Version4/Controllers/ShippingZones.php | 6 +- .../Version4/Controllers/SystemStatus.php | 3 +- .../Controllers/SystemStatusTools.php | 6 +- .../Version4/Controllers/TaxClasses.php | 6 +- src/RestApi/Version4/Controllers/Taxes.php | 9 +- src/RestApi/Version4/Controllers/Webhooks.php | 136 ++++++++++-------- 28 files changed, 249 insertions(+), 172 deletions(-) diff --git a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php index cc443fa594b..7d431443c3a 100644 --- a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php +++ b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php @@ -58,7 +58,8 @@ abstract class AbstractTermsContoller extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -98,7 +99,8 @@ abstract class AbstractTermsContoller extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -112,7 +114,8 @@ abstract class AbstractTermsContoller extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/RestApi/Version4/Controllers/Coupons.php index 35818399f99..69a2cb4edb6 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -67,7 +67,8 @@ class Coupons extends AbstractPostsController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -107,7 +108,8 @@ class Coupons extends AbstractPostsController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -121,7 +123,8 @@ class Coupons extends AbstractPostsController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/CustomerDownloads.php b/src/RestApi/Version4/Controllers/CustomerDownloads.php index 8cdc402a2a4..24625e464c4 100644 --- a/src/RestApi/Version4/Controllers/CustomerDownloads.php +++ b/src/RestApi/Version4/Controllers/CustomerDownloads.php @@ -44,7 +44,8 @@ class CustomerDownloads extends AbstractController { 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/RestApi/Version4/Controllers/Customers.php index 66a6d8f0ecd..e571d175b1f 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -65,7 +65,8 @@ class Customers extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -110,7 +111,8 @@ class Customers extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -124,7 +126,8 @@ class Customers extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Data.php b/src/RestApi/Version4/Controllers/Data.php index ea41d625d41..129d7bfe2b7 100644 --- a/src/RestApi/Version4/Controllers/Data.php +++ b/src/RestApi/Version4/Controllers/Data.php @@ -39,7 +39,8 @@ class Data extends AbstractController { 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Leaderboards.php b/src/RestApi/Version4/Controllers/Leaderboards.php index 2271ea0346a..d93d885fa27 100644 --- a/src/RestApi/Version4/Controllers/Leaderboards.php +++ b/src/RestApi/Version4/Controllers/Leaderboards.php @@ -42,7 +42,8 @@ class Leaderboards extends AbstractController { 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -55,7 +56,8 @@ class Leaderboards extends AbstractController { 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_allowed_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/NetworkOrders.php b/src/RestApi/Version4/Controllers/NetworkOrders.php index d13dcd1dbcd..fa23c096d42 100644 --- a/src/RestApi/Version4/Controllers/NetworkOrders.php +++ b/src/RestApi/Version4/Controllers/NetworkOrders.php @@ -32,7 +32,8 @@ class NetworkOrders extends Orders { 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } } diff --git a/src/RestApi/Version4/Controllers/OrderNotes.php b/src/RestApi/Version4/Controllers/OrderNotes.php index a31e0ee5ac0..0faa9ad6d64 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -34,67 +34,75 @@ class OrderNotes extends AbstractController { * Register the routes for order notes. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( - 'note' => array( - 'type' => 'string', - 'description' => __( 'Order note content.', 'woocommerce' ), - 'required' => true, + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', ), - ) ), + ), + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( + 'note' => array( + 'type' => 'string', + 'description' => __( 'Order note content.', 'woocommerce' ), + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + true + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', ), ), + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => \WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + true + ); } /** diff --git a/src/RestApi/Version4/Controllers/OrderRefunds.php b/src/RestApi/Version4/Controllers/OrderRefunds.php index f801364f13e..54030afe7b2 100644 --- a/src/RestApi/Version4/Controllers/OrderRefunds.php +++ b/src/RestApi/Version4/Controllers/OrderRefunds.php @@ -71,7 +71,8 @@ class OrderRefunds extends Orders { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -109,7 +110,8 @@ class OrderRefunds extends Orders { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index dc688f87766..ae3b11008e1 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -65,7 +65,8 @@ class Orders extends AbstractObjectsController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -105,7 +106,8 @@ class Orders extends AbstractObjectsController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -119,7 +121,8 @@ class Orders extends AbstractObjectsController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/PaymentGateways.php b/src/RestApi/Version4/Controllers/PaymentGateways.php index 65b81a4dc1c..50645ead356 100644 --- a/src/RestApi/Version4/Controllers/PaymentGateways.php +++ b/src/RestApi/Version4/Controllers/PaymentGateways.php @@ -38,7 +38,8 @@ class PaymentGateways extends AbstractController { 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( $this->namespace, @@ -65,7 +66,8 @@ class PaymentGateways extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php index 8a3b4dd413d..a5514d72732 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php +++ b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php @@ -59,7 +59,8 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -103,7 +104,8 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -123,7 +125,8 @@ class ProductAttributeTerms extends AbstractTermsContoller { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/ProductAttributes.php b/src/RestApi/Version4/Controllers/ProductAttributes.php index d6c4fd36ffd..ddf5547bba9 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributes.php +++ b/src/RestApi/Version4/Controllers/ProductAttributes.php @@ -60,7 +60,8 @@ class ProductAttributes extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -100,7 +101,8 @@ class ProductAttributes extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -114,7 +116,8 @@ class ProductAttributes extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/RestApi/Version4/Controllers/ProductReviews.php index 75696bd1080..e7ebff54136 100644 --- a/src/RestApi/Version4/Controllers/ProductReviews.php +++ b/src/RestApi/Version4/Controllers/ProductReviews.php @@ -68,7 +68,8 @@ class ProductReviews extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -108,7 +109,8 @@ class ProductReviews extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -122,7 +124,8 @@ class ProductReviews extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/ProductVariations.php b/src/RestApi/Version4/Controllers/ProductVariations.php index a1316512337..806c4d2411a 100644 --- a/src/RestApi/Version4/Controllers/ProductVariations.php +++ b/src/RestApi/Version4/Controllers/ProductVariations.php @@ -65,7 +65,8 @@ class ProductVariations extends Products { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( $this->namespace, @@ -112,7 +113,8 @@ class ProductVariations extends Products { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', @@ -130,7 +132,8 @@ class ProductVariations extends Products { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/RestApi/Version4/Controllers/Products.php index e843da48e58..6c8ca1fa96a 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -65,7 +65,8 @@ class Products extends AbstractObjectsController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -109,7 +110,8 @@ class Products extends AbstractObjectsController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -123,7 +125,8 @@ class Products extends AbstractObjectsController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php index e6727ededf7..284ff185d14 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -38,7 +38,8 @@ class Reports extends AbstractController { 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Settings.php b/src/RestApi/Version4/Controllers/Settings.php index 08e9aea2271..28e43e29d54 100644 --- a/src/RestApi/Version4/Controllers/Settings.php +++ b/src/RestApi/Version4/Controllers/Settings.php @@ -39,7 +39,8 @@ class Settings extends AbstractController { 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( $this->namespace, @@ -51,7 +52,8 @@ class Settings extends AbstractController { 'permission_callback' => array( $this, 'update_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/SettingsOptions.php b/src/RestApi/Version4/Controllers/SettingsOptions.php index 7a7e8eb8575..f4bbcacde72 100644 --- a/src/RestApi/Version4/Controllers/SettingsOptions.php +++ b/src/RestApi/Version4/Controllers/SettingsOptions.php @@ -45,7 +45,8 @@ class SettingsOptions extends AbstractController { 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -65,7 +66,8 @@ class SettingsOptions extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); register_rest_route( @@ -94,7 +96,8 @@ class SettingsOptions extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/ShippingMethods.php b/src/RestApi/Version4/Controllers/ShippingMethods.php index 357a9e7c4b7..3f8174386f0 100644 --- a/src/RestApi/Version4/Controllers/ShippingMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingMethods.php @@ -38,7 +38,8 @@ class ShippingMethods extends AbstractController { 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( $this->namespace, @@ -59,7 +60,8 @@ class ShippingMethods extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php index 52af3e6ce46..706b780d2c3 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php @@ -42,7 +42,8 @@ class ShippingZoneLocations extends AbstractShippingZonesController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php index 4791455aa7f..1375b5eea6a 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php @@ -51,7 +51,8 @@ class ShippingZoneMethods extends AbstractShippingZonesController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -92,7 +93,8 @@ class ShippingZoneMethods extends AbstractShippingZonesController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/ShippingZones.php b/src/RestApi/Version4/Controllers/ShippingZones.php index e5621ae48f5..fb42e1cb4df 100644 --- a/src/RestApi/Version4/Controllers/ShippingZones.php +++ b/src/RestApi/Version4/Controllers/ShippingZones.php @@ -45,7 +45,8 @@ class ShippingZones extends AbstractShippingZonesController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -82,7 +83,8 @@ class ShippingZones extends AbstractShippingZonesController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/SystemStatus.php b/src/RestApi/Version4/Controllers/SystemStatus.php index d9c53b3c428..e9c34ae1018 100644 --- a/src/RestApi/Version4/Controllers/SystemStatus.php +++ b/src/RestApi/Version4/Controllers/SystemStatus.php @@ -38,7 +38,8 @@ class SystemStatus extends AbstractController { 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/SystemStatusTools.php b/src/RestApi/Version4/Controllers/SystemStatusTools.php index 734febcd1fe..e1edacd817f 100644 --- a/src/RestApi/Version4/Controllers/SystemStatusTools.php +++ b/src/RestApi/Version4/Controllers/SystemStatusTools.php @@ -38,7 +38,8 @@ class SystemStatusTools extends AbstractController { 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -63,7 +64,8 @@ class SystemStatusTools extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/RestApi/Version4/Controllers/TaxClasses.php index 58324ce45e4..7dfc3303ac0 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -44,7 +44,8 @@ class TaxClasses extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -70,7 +71,8 @@ class TaxClasses extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Taxes.php b/src/RestApi/Version4/Controllers/Taxes.php index 7218745c131..f5bc66417ee 100644 --- a/src/RestApi/Version4/Controllers/Taxes.php +++ b/src/RestApi/Version4/Controllers/Taxes.php @@ -44,7 +44,8 @@ class Taxes extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -84,7 +85,8 @@ class Taxes extends AbstractController { ), ), 'schema' => array( $this, 'get_public_item_schema' ), - ) + ), + true ); register_rest_route( @@ -98,7 +100,8 @@ class Taxes extends AbstractController { 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), - ) + ), + true ); } diff --git a/src/RestApi/Version4/Controllers/Webhooks.php b/src/RestApi/Version4/Controllers/Webhooks.php index b72f13ae2ad..5c3122d8ec8 100644 --- a/src/RestApi/Version4/Controllers/Webhooks.php +++ b/src/RestApi/Version4/Controllers/Webhooks.php @@ -34,78 +34,90 @@ class Webhooks extends AbstractController { * Register the routes for webhooks. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( + 'topic' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook topic.', 'woocommerce' ), + ), + 'delivery_url' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( - 'topic' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Webhook topic.', 'woocommerce' ), - ), - 'delivery_url' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + true + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - ), + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => \WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + true + ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), + array( + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); + true + ); } /** From f4da7e1826bff40e0a46648280a34b99fab042dd Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 14:38:13 +0100 Subject: [PATCH 052/440] Add currency_symbol to order response --- src/RestApi/Version4/Controllers/Orders.php | 11 +++++++++++ src/RestApi/Version4/changelog.md | 1 + 2 files changed, 12 insertions(+) diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index ae3b11008e1..8833af19e9b 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -237,6 +237,10 @@ class Orders extends AbstractObjectsController { ); } + // Currency symbols. + $currency_symbol = get_woocommerce_currency_symbol( $data['currency'] ); + $data['currency_symbol'] = html_entity_decode( $currency_symbol ); + return array( 'id' => $object->get_id(), 'parent_id' => $data['parent_id'], @@ -246,6 +250,7 @@ class Orders extends AbstractObjectsController { 'version' => $data['version'], 'status' => $data['status'], 'currency' => $data['currency'], + 'currency_symbol' => $data['currency_symbol'], 'date_created' => $data['date_created'], 'date_created_gmt' => $data['date_created_gmt'], 'date_modified' => $data['date_modified'], @@ -869,6 +874,12 @@ class Orders extends AbstractObjectsController { 'enum' => array_keys( get_woocommerce_currencies() ), 'context' => array( 'view', 'edit' ), ), + 'currency_symbol' => array( + 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), 'date_created' => array( 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md index 070667c9c7c..822bc352dc7 100644 --- a/src/RestApi/Version4/changelog.md +++ b/src/RestApi/Version4/changelog.md @@ -5,6 +5,7 @@ - All endpoints - Rewritten with namespaces as standalone classes. - Coupons - Added `search` parameter. - Orders - Added order number to schema. +- Orders - Added currency_symbol to schema. - Product Reviews - Updated response links. - Products - Added `low_in_stock` and `search` parameter. - Product Variations - Added `search` parameter. From e865ca1b71e14633411c7ad3e3afb74ce0392c6e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 15:10:51 +0100 Subject: [PATCH 053/440] Fix leaderboard endpoint --- src/RestApi/Version4/Controllers/Leaderboards.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RestApi/Version4/Controllers/Leaderboards.php b/src/RestApi/Version4/Controllers/Leaderboards.php index d93d885fa27..4b01bc9ad36 100644 --- a/src/RestApi/Version4/Controllers/Leaderboards.php +++ b/src/RestApi/Version4/Controllers/Leaderboards.php @@ -14,7 +14,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Leaderboards class. */ -class Leaderboards extends AbstractController { +class Leaderboards extends Data { /** * Route base. From ccf3a939ed9f3059e6ee144bfd8d3522037c3668 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 15:31:04 +0100 Subject: [PATCH 054/440] Delete responses --- .../Version4/Controllers/OrderNotes.php | 13 +++++-- .../Controllers/ProductAttributes.php | 13 +++++-- .../Controllers/ProductVariations.php | 20 +++++++---- src/RestApi/Version4/Controllers/Products.php | 34 ++++++------------- .../Controllers/ShippingZoneMethods.php | 24 ++++++++----- .../Version4/Controllers/ShippingZones.php | 19 +++++++---- .../Version4/Controllers/TaxClasses.php | 12 +++++-- src/RestApi/Version4/Controllers/Webhooks.php | 14 +++++--- 8 files changed, 93 insertions(+), 56 deletions(-) diff --git a/src/RestApi/Version4/Controllers/OrderNotes.php b/src/RestApi/Version4/Controllers/OrderNotes.php index 0faa9ad6d64..0b53a46fdd9 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -321,14 +321,21 @@ class OrderNotes extends AbstractController { } $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $note, $request ); - - $result = wc_delete_order_note( $note->comment_ID ); + $previous = $this->prepare_item_for_response( $note, $request ); + $result = wc_delete_order_note( $note->comment_ID ); if ( ! $result ) { return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); } + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); + /** * Fires after a order note is deleted or trashed via the REST API. * diff --git a/src/RestApi/Version4/Controllers/ProductAttributes.php b/src/RestApi/Version4/Controllers/ProductAttributes.php index ddf5547bba9..27c8486ca49 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributes.php +++ b/src/RestApi/Version4/Controllers/ProductAttributes.php @@ -374,14 +374,21 @@ class ProductAttributes extends AbstractController { } $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $attribute, $request ); - - $deleted = wc_delete_attribute( $attribute->attribute_id ); + $previous = $this->prepare_item_for_response( $attribute, $request ); + $deleted = wc_delete_attribute( $attribute->attribute_id ); if ( false === $deleted ) { return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); + /** * Fires after a single attribute is deleted via the REST API. * diff --git a/src/RestApi/Version4/Controllers/ProductVariations.php b/src/RestApi/Version4/Controllers/ProductVariations.php index 806c4d2411a..6e867f4ecfb 100644 --- a/src/RestApi/Version4/Controllers/ProductVariations.php +++ b/src/RestApi/Version4/Controllers/ProductVariations.php @@ -676,12 +676,21 @@ class ProductVariations extends Products { } $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); // If we're forcing, then delete permanently. if ( $force ) { + $previous = $this->prepare_object_for_response( $object, $request ); + $object->delete( true ); - $result = 0 === $object->get_id(); + + $result = 0 === $object->get_id(); + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); } else { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { @@ -707,6 +716,8 @@ class ProductVariations extends Products { $object->delete(); $result = 'trash' === $object->get_status(); } + + $response = $this->prepare_object_for_response( $object, $request ); } if ( ! $result ) { @@ -718,11 +729,6 @@ class ProductVariations extends Products { ); } - // Delete parent product transients. - if ( 0 !== $object->get_parent_id() ) { - wc_delete_product_transients( $object->get_parent_id() ); - } - /** * Fires after a single object is deleted or trashed via the REST API. * diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/RestApi/Version4/Controllers/Products.php index 6c8ca1fa96a..18b581426f5 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -1492,30 +1492,21 @@ class Products extends AbstractObjectsController { } $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); // If we're forcing, then delete permanently. if ( $force ) { - if ( $object->is_type( 'variable' ) ) { - foreach ( $object->get_children() as $child_id ) { - $child = wc_get_product( $child_id ); - if ( ! empty( $child ) ) { - $child->delete( true ); - } - } - } else { - // For other product types, if the product has children, remove the relationship. - foreach ( $object->get_children() as $child_id ) { - $child = wc_get_product( $child_id ); - if ( ! empty( $child ) ) { - $child->set_parent_id( 0 ); - $child->save(); - } - } - } + $previous = $this->prepare_object_for_response( $object, $request ); $object->delete( true ); $result = 0 === $object->get_id(); + + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); } else { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { @@ -1545,6 +1536,8 @@ class Products extends AbstractObjectsController { $object->delete(); $result = 'trash' === $object->get_status(); } + + $response = $this->prepare_object_for_response( $object, $request ); } if ( ! $result ) { @@ -1558,11 +1551,6 @@ class Products extends AbstractObjectsController { ); } - // Delete parent product transients. - if ( 0 !== $object->get_parent_id() ) { - wc_delete_product_transients( $object->get_parent_id() ); - } - /** * Fires after a single object is deleted or trashed via the REST API. * diff --git a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php index 1375b5eea6a..2401e4bc37e 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php @@ -206,6 +206,11 @@ class ShippingZoneMethods extends AbstractShippingZonesController { $instance_id = (int) $request['instance_id']; $force = $request['force']; + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + $methods = $zone->get_shipping_methods(); $method = false; @@ -226,23 +231,26 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } $request->set_param( 'context', 'view' ); - $response = $this->prepare_item_for_response( $method, $request ); + $previous = $this->prepare_item_for_response( $method, $request ); // Actually delete. - if ( $force ) { - $zone->delete_shipping_method( $instance_id ); - } else { - return new \WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); - } + $zone->delete_shipping_method( $instance_id ); + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous, + ) + ); /** - * Fires after a product review is deleted via the REST API. + * Fires after a method is deleted via the REST API. * * @param object $method * @param WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ - do_action( 'rest_delete_product_review', $method, $response, $request ); + do_action( 'woocommerce_rest_delete_shipping_zone_method', $method, $response, $request ); return $response; } diff --git a/src/RestApi/Version4/Controllers/ShippingZones.php b/src/RestApi/Version4/Controllers/ShippingZones.php index fb42e1cb4df..654c1a6dbde 100644 --- a/src/RestApi/Version4/Controllers/ShippingZones.php +++ b/src/RestApi/Version4/Controllers/ShippingZones.php @@ -211,14 +211,21 @@ class ShippingZones extends AbstractShippingZonesController { $force = $request['force']; - $response = $this->get_item( $request ); - - if ( $force ) { - $zone->delete(); - } else { - return new \WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } + $previous = $this->get_item( $request ); + $zone->delete(); + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); + return $response; } diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/RestApi/Version4/Controllers/TaxClasses.php index 7dfc3303ac0..d6d90a667de 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -242,6 +242,9 @@ class TaxClasses extends AbstractController { return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); } + $request->set_param( 'context', 'edit' ); + $previous = $this->prepare_item_for_response( $tax_class, $request ); + update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); // Delete tax rate locations locations from the selected class. @@ -262,8 +265,13 @@ class TaxClasses extends AbstractController { // Delete tax rates in the selected class. $wpdb->delete( $wpdb->prefix . 'woocommerce_tax_rates', array( 'tax_rate_class' => $tax_class['slug'] ), array( '%s' ) ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax_class, $request ); + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); /** * Fires after a tax class is deleted via the REST API. diff --git a/src/RestApi/Version4/Controllers/Webhooks.php b/src/RestApi/Version4/Controllers/Webhooks.php index 5c3122d8ec8..86e4adc650a 100644 --- a/src/RestApi/Version4/Controllers/Webhooks.php +++ b/src/RestApi/Version4/Controllers/Webhooks.php @@ -463,13 +463,19 @@ class Webhooks extends AbstractController { } $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $webhook, $request ); + $previous = $this->prepare_item_for_response( $webhook, $request ); $result = $webhook->delete( true ); - if ( ! $result ) { /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); /** * Fires after a single item is deleted or trashed via the REST API. @@ -478,7 +484,7 @@ class Webhooks extends AbstractController { * @param WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ - do_action( "woocommerce_rest_delete_webhook_object", $webhook, $response, $request ); + do_action( 'woocommerce_rest_delete_webhook_object', $webhook, $response, $request ); return $response; } From f68e5d10808acc03e76ef4848199885916f94a46 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 17:34:11 +0100 Subject: [PATCH 055/440] Add tests --- .gitignore | 3 + composer.json | 3 + composer.lock | 1661 +++++++++++++++++ phpunit.xml.dist | 17 + src/RestApi/Version4/Controllers/Coupons.php | 24 + tests/AbstractRestApiTest.php | 116 ++ tests/Version4/Coupons.php | 234 +++ tests/bootstrap.php | 69 + vendor/composer/autoload_classmap.php | 542 ++++++ vendor/composer/autoload_namespaces.php | 1 + vendor/composer/autoload_psr4.php | 6 + vendor/composer/autoload_real.php | 18 + vendor/composer/autoload_static.php | 613 +++++++ vendor/composer/installed.json | 1705 +++++++++++++++++- 14 files changed, 5011 insertions(+), 1 deletion(-) create mode 100644 composer.lock create mode 100644 phpunit.xml.dist create mode 100644 tests/AbstractRestApiTest.php create mode 100644 tests/Version4/Coupons.php create mode 100755 tests/bootstrap.php diff --git a/.gitignore b/.gitignore index e6f2d231aad..33f6bb1d8a7 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ tests/cli/vendor # Logs /logs + +# composer +vendor/ diff --git a/composer.json b/composer.json index 82ad2e52fc8..8eef292cb10 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,9 @@ "require" : { "composer/installers" : "~1.0" }, + "require-dev": { + "phpunit/phpunit": "6.5.14" + }, "autoload": { "classmap": ["src"] } diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000000..f5d62d80d4d --- /dev/null +++ b/composer.lock @@ -0,0 +1,1661 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "353feb9c7787bea5fd95861d54bca06a", + "packages": [ + { + "name": "composer/installers", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "phpunit/phpunit": "^4.8.36" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "time": "2018-08-27T06:10:37+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "a2c590166b2133a4633738648b6b064edae0814a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2019-03-17T17:37:11+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2019-04-07T13:18:21+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2019-04-30T17:48:53+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-08-05T17:53:17+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "5.3.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.0", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^2.0.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-xdebug": "^2.5.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-04-06T15:36:58+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "791198a2c6254db10131eecfe8c06670700904db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-11-27T05:48:46+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "6.5.14", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", + "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.3", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^1.0.9", + "phpunit/phpunit-mock-objects": "^5.0.9", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^2.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2019-02-01T05:22:47+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "5.0.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.0", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "conflict": { + "phpunit/phpunit": "<6.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5.11" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "abandoned": true, + "time": "2018-08-09T05:50:03+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "2.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-02-01T13:46:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-08-03T08:09:46+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "82ebae02209c21113908c229e9883c419720738a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", + "reference": "82ebae02209c21113908c229e9883c419720738a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8", + "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2019-04-04T09:56:43+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", + "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-12-25T11:19:39+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000000..dfa2605c311 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,17 @@ + + + + + ./tests/ + + + diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/RestApi/Version4/Controllers/Coupons.php index 69a2cb4edb6..a7c2039e300 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -764,6 +764,30 @@ class Coupons extends AbstractPostsController { return $response; } + /** + * Saves a coupon to the database. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|int + */ + protected function save_coupon( $request ) { + try { + $coupon = $this->prepare_item_for_database( $request ); + + if ( is_wp_error( $coupon ) ) { + return $coupon; + } + + $coupon->save(); + return $coupon->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + /** * Update a single coupon. * diff --git a/tests/AbstractRestApiTest.php b/tests/AbstractRestApiTest.php new file mode 100644 index 00000000000..34098e028a6 --- /dev/null +++ b/tests/AbstractRestApiTest.php @@ -0,0 +1,116 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $actual_routes = $this->server->get_routes(); + $expected_routes = $this->routes; + + foreach ( $expected_routes as $expected_route ) { + $this->assertArrayHasKey( $expected_route, $actual_routes ); + } + } + + /** + * Validate that the returned API schema matches what is expected. + * + * @return void + */ + public function test_schema_properties() { + $this->user_request(); + + $request = new \WP_REST_Request( 'OPTIONS', $this->routes[0] ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( count( $this->properties ), count( $properties ) ); + + foreach ( $this->properties as $property ) { + $this->assertArrayHasKey( $property, $properties ); + } + } + + /** + * Set current user to an authenticated user. + */ + protected function user_request() { + wp_set_current_user( $this->user ); + } + + /** + * Set current user to an unauthenticated user. + */ + protected function guest_request() { + wp_set_current_user( 0 ); + } + + /** + * Perform a request and return the status and returned data. + * + * @param string $endpoint Endpoint to hit. + * @param string $type Type of request e.g GET or POST. + * @param array $params Request body. + * @param boolean $authenticated Do request as user or guest. + * @return object + */ + protected function do_request( $endpoint, $type = 'GET', $params = array(), $authenticated = true ) { + $authenticated ? $this->user_request() : $this->guest_request(); + + $request = new \WP_REST_Request( $type, $endpoint ); + $request->set_body_params( $params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + return (object) array( + 'status' => $response->get_status(), + 'data' => $response->get_data(), + ); + } +} diff --git a/tests/Version4/Coupons.php b/tests/Version4/Coupons.php new file mode 100644 index 00000000000..e3fb86edce3 --- /dev/null +++ b/tests/Version4/Coupons.php @@ -0,0 +1,234 @@ +[\d]+)', + '/wc/v4/coupons/batch', + ]; + + /** + * The endpoint schema. + * + * @var array + */ + protected $properties = [ + 'id', + 'code', + 'amount', + 'date_created', + 'date_created_gmt', + 'date_modified', + 'date_modified_gmt', + 'discount_type', + 'description', + 'date_expires', + 'date_expires_gmt', + 'usage_count', + 'individual_use', + 'product_ids', + 'excluded_product_ids', + 'usage_limit', + 'usage_limit_per_user', + 'limit_usage_to_x_items', + 'free_shipping', + 'product_categories', + 'excluded_product_categories', + 'exclude_sale_items', + 'minimum_amount', + 'maximum_amount', + 'email_restrictions', + 'used_by', + 'meta_data', + ]; + + /** + * Test delete. + * + * @return void + */ + public function test_delete() { + $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $result = $this->do_request( + '/wc/v4/coupons/' . $coupon->get_id(), + 'DELETE', + [ 'force' => false ] + ); + $this->assertEquals( 200, $result->status ); + $this->assertEquals( 'trash', get_post_status( $coupon->get_id() ) ); + } + + /** + * Test force delete. + * + * @return void + */ + public function test_force_delete() { + $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $result = $this->do_request( + '/wc/v4/coupons/' . $coupon->get_id(), + 'DELETE', + [ 'force' => true ] + ); + $this->assertEquals( 200, $result->status ); + $this->assertEquals( false, get_post( $coupon->get_id() ) ); + } + + /** + * Test delete. + * + * @return void + */ + public function test_delete_without_permission() { + $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $result = $this->do_request( + '/wc/v4/coupons/' . $coupon->get_id(), + 'DELETE', + [ 'force' => false ], + false + ); + $this->assertEquals( 401, $result->status ); + $this->assertNotEquals( 'trash', get_post_status( $coupon->get_id() ) ); + } + + /** + * Test delete. + * + * @return void + */ + public function test_delete_non_existing() { + $result = $this->do_request( + '/wc/v4/coupons/0', + 'DELETE', + [ 'force' => false ] + ); + $this->assertEquals( 404, $result->status ); + } + + /** + * Test creation. + */ + public function test_create() { + $result = $this->do_request( + '/wc/v4/coupons', + 'POST', + [ + 'code' => 'test', + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + 'description' => 'Test', + 'usage_limit' => 10, + ] + ); + $this->assertEquals( 201, $result->status ); + $this->assertEquals( 'test', $result->data['code'] ); + $this->assertEquals( '5.00', $result->data['amount'] ); + $this->assertEquals( 'fixed_product', $result->data['discount_type'] ); + $this->assertEquals( 'Test', $result->data['description'] ); + $this->assertEquals( 10, $result->data['usage_limit'] ); + } + + /** + * Test creation. + */ + public function test_create_without_permission() { + $result = $this->do_request( + '/wc/v4/coupons', + 'POST', + [ + 'code' => 'test', + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + 'description' => 'Test', + 'usage_limit' => 10, + ], + false + ); + $this->assertEquals( 401, $result->status ); + } + + /** + * Test validation. + */ + public function test_enum_discount_type() { + $result = $this->do_request( + '/wc/v4/coupons', + 'POST', + [ + 'code' => 'test', + 'amount' => '5.00', + 'discount_type' => 'fake', + 'description' => 'Test', + 'usage_limit' => 10, + ] + ); + + $this->assertEquals( 400, $result->status ); + $this->assertEquals( 'Invalid parameter(s): discount_type', $result->data['message'] ); + } + + /** + * Test a batch update. + */ + public function test_batch() { + $coupon_1 = \WC_Helper_Coupon::create_coupon( 'batchcoupon-1' ); + $coupon_2 = \WC_Helper_Coupon::create_coupon( 'batchcoupon-2' ); + $coupon_3 = \WC_Helper_Coupon::create_coupon( 'batchcoupon-3' ); + $coupon_4 = \WC_Helper_Coupon::create_coupon( 'batchcoupon-4' ); + + $result = $this->do_request( + '/wc/v4/coupons/batch', + 'POST', + array( + 'update' => array( + array( + 'id' => $coupon_1->get_id(), + 'amount' => '5.15', + ), + ), + 'delete' => array( + $coupon_2->get_id(), + $coupon_3->get_id(), + ), + 'create' => array( + array( + 'code' => 'new-coupon', + 'amount' => '11.00', + ), + ), + ) + ); + + $this->assertEquals( '5.15', $result->data['update'][0]['amount'] ); + $this->assertEquals( '11.00', $result->data['create'][0]['amount'] ); + $this->assertEquals( 'new-coupon', $result->data['create'][0]['code'] ); + $this->assertEquals( $coupon_2->get_id(), $result->data['delete'][0]['id'] ); + $this->assertEquals( $coupon_3->get_id(), $result->data['delete'][1]['id'] ); + + $result = $this->do_request( + '/wc/v4/coupons' + ); + $this->assertEquals( 3, count( $result->data ) ); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100755 index 00000000000..38893381864 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,69 @@ + $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', + 'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit\\Framework\\CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit\\Framework\\Constraint\\ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit\\Framework\\Constraint\\Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit\\Framework\\Constraint\\Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit\\Framework\\Constraint\\Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit\\Framework\\Constraint\\Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', + 'PHPUnit\\Framework\\Constraint\\Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', + 'PHPUnit\\Framework\\Constraint\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit\\Framework\\Constraint\\GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit\\Framework\\Constraint\\IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit\\Framework\\Constraint\\IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit\\Framework\\Constraint\\IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit\\Framework\\Constraint\\IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit\\Framework\\Constraint\\IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit\\Framework\\Constraint\\IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit\\Framework\\Constraint\\IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit\\Framework\\Constraint\\IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit\\Framework\\Constraint\\IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit\\Framework\\Constraint\\IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', + 'PHPUnit\\Framework\\Constraint\\IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit\\Framework\\Constraint\\IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit\\Framework\\Constraint\\IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', + 'PHPUnit\\Framework\\Constraint\\LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', + 'PHPUnit\\Framework\\Constraint\\LogicalNot' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', + 'PHPUnit\\Framework\\Constraint\\LogicalOr' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', + 'PHPUnit\\Framework\\Constraint\\LogicalXor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit\\Framework\\Constraint\\StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', + 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', + 'PHPUnit\\Framework\\DataProviderTestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', + 'PHPUnit\\Framework\\Error\\Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit\\Framework\\Error\\Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Error.php', + 'PHPUnit\\Framework\\Error\\Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit\\Framework\\Error\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit\\Framework\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit\\Framework\\ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit\\Framework\\ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit\\Framework\\IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit\\Framework\\IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit\\Framework\\IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit\\Framework\\InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit\\Framework\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', + 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/BadMethodCallException.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Match.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/NamespaceMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/ObjectInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invokable.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/ConsecutiveParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtIndex.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedRecorder.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/StatelessInvocation.php', + 'PHPUnit\\Framework\\MockObject\\MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/MockBuilder.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/ForwardCompatibility/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/MatcherCollection.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Verifiable.php', + 'PHPUnit\\Framework\\OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit\\Framework\\RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit\\Framework\\RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit\\Framework\\SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit\\Framework\\SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit\\Framework\\SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit\\Framework\\SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit\\Framework\\SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit\\Framework\\SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit\\Framework\\TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', + 'PHPUnit\\Framework\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit\\Framework\\TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', + 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit\\Framework\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit\\Framework\\WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit\\Runner\\BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit\\Runner\\Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Runner/PhptTestCase.php', + 'PHPUnit\\Runner\\StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit\\Runner\\TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit\\Runner\\Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit\\TextUI\\Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit\\TextUI\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit\\TextUI\\TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit\\Util\\Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit\\Util\\Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit\\Util\\ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit\\Util\\ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit\\Util\\Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit\\Util\\Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit\\Util\\Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit\\Util\\Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit\\Util\\GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit\\Util\\InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit\\Util\\Json' => $vendorDir . '/phpunit/phpunit/src/Util/Json.php', + 'PHPUnit\\Util\\Log\\JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit\\Util\\Log\\TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', + 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', + 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', + 'PHPUnit\\Util\\Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit\\Util\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Util/RegularExpression.php', + 'PHPUnit\\Util\\Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit\\Util\\TestDox\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', + 'PHPUnit\\Util\\TextTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', + 'PHPUnit\\Util\\Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit\\Util\\Xml' => $vendorDir . '/phpunit/phpunit/src/Util/Xml.php', + 'PHPUnit\\Util\\XmlTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', + 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/MockObject.php', + 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php', + 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php', + 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php', + 'PharIo\\Manifest\\AuthorCollection' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollection.php', + 'PharIo\\Manifest\\AuthorCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', + 'PharIo\\Manifest\\AuthorElement' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElement.php', + 'PharIo\\Manifest\\AuthorElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElementCollection.php', + 'PharIo\\Manifest\\BundledComponent' => $vendorDir . '/phar-io/manifest/src/values/BundledComponent.php', + 'PharIo\\Manifest\\BundledComponentCollection' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollection.php', + 'PharIo\\Manifest\\BundledComponentCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', + 'PharIo\\Manifest\\BundlesElement' => $vendorDir . '/phar-io/manifest/src/xml/BundlesElement.php', + 'PharIo\\Manifest\\ComponentElement' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElement.php', + 'PharIo\\Manifest\\ComponentElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElementCollection.php', + 'PharIo\\Manifest\\ContainsElement' => $vendorDir . '/phar-io/manifest/src/xml/ContainsElement.php', + 'PharIo\\Manifest\\CopyrightElement' => $vendorDir . '/phar-io/manifest/src/xml/CopyrightElement.php', + 'PharIo\\Manifest\\CopyrightInformation' => $vendorDir . '/phar-io/manifest/src/values/CopyrightInformation.php', + 'PharIo\\Manifest\\ElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ElementCollection.php', + 'PharIo\\Manifest\\Email' => $vendorDir . '/phar-io/manifest/src/values/Email.php', + 'PharIo\\Manifest\\Exception' => $vendorDir . '/phar-io/manifest/src/exceptions/Exception.php', + 'PharIo\\Manifest\\ExtElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtElement.php', + 'PharIo\\Manifest\\ExtElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ExtElementCollection.php', + 'PharIo\\Manifest\\Extension' => $vendorDir . '/phar-io/manifest/src/values/Extension.php', + 'PharIo\\Manifest\\ExtensionElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtensionElement.php', + 'PharIo\\Manifest\\InvalidApplicationNameException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', + 'PharIo\\Manifest\\InvalidEmailException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', + 'PharIo\\Manifest\\InvalidUrlException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', + 'PharIo\\Manifest\\Library' => $vendorDir . '/phar-io/manifest/src/values/Library.php', + 'PharIo\\Manifest\\License' => $vendorDir . '/phar-io/manifest/src/values/License.php', + 'PharIo\\Manifest\\LicenseElement' => $vendorDir . '/phar-io/manifest/src/xml/LicenseElement.php', + 'PharIo\\Manifest\\Manifest' => $vendorDir . '/phar-io/manifest/src/values/Manifest.php', + 'PharIo\\Manifest\\ManifestDocument' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocument.php', + 'PharIo\\Manifest\\ManifestDocumentException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', + 'PharIo\\Manifest\\ManifestDocumentLoadingException' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', + 'PharIo\\Manifest\\ManifestDocumentMapper' => $vendorDir . '/phar-io/manifest/src/ManifestDocumentMapper.php', + 'PharIo\\Manifest\\ManifestDocumentMapperException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', + 'PharIo\\Manifest\\ManifestElement' => $vendorDir . '/phar-io/manifest/src/xml/ManifestElement.php', + 'PharIo\\Manifest\\ManifestElementException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestElementException.php', + 'PharIo\\Manifest\\ManifestLoader' => $vendorDir . '/phar-io/manifest/src/ManifestLoader.php', + 'PharIo\\Manifest\\ManifestLoaderException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', + 'PharIo\\Manifest\\ManifestSerializer' => $vendorDir . '/phar-io/manifest/src/ManifestSerializer.php', + 'PharIo\\Manifest\\PhpElement' => $vendorDir . '/phar-io/manifest/src/xml/PhpElement.php', + 'PharIo\\Manifest\\PhpExtensionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', + 'PharIo\\Manifest\\PhpVersionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpVersionRequirement.php', + 'PharIo\\Manifest\\Requirement' => $vendorDir . '/phar-io/manifest/src/values/Requirement.php', + 'PharIo\\Manifest\\RequirementCollection' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollection.php', + 'PharIo\\Manifest\\RequirementCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', + 'PharIo\\Manifest\\RequiresElement' => $vendorDir . '/phar-io/manifest/src/xml/RequiresElement.php', + 'PharIo\\Manifest\\Type' => $vendorDir . '/phar-io/manifest/src/values/Type.php', + 'PharIo\\Manifest\\Url' => $vendorDir . '/phar-io/manifest/src/values/Url.php', + 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/AnyVersionConstraint.php', + 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/InvalidVersionException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/HHVM.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeCoverage\\Version' => $vendorDir . '/phpunit/php-code-coverage/src/Version.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php', + 'SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\OperatingSystem' => $vendorDir . '/sebastian/environment/src/OperatingSystem.php', + 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/exceptions/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/exceptions/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\Exception' => $vendorDir . '/sebastian/object-reflector/src/Exception.php', + 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => $vendorDir . '/sebastian/object-reflector/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => $vendorDir . '/sebastian/object-reflector/src/ObjectReflector.php', + 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', + 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', + 'TheSeer\\Tokenizer\\Exception' => $vendorDir . '/theseer/tokenizer/src/Exception.php', + 'TheSeer\\Tokenizer\\NamespaceUri' => $vendorDir . '/theseer/tokenizer/src/NamespaceUri.php', + 'TheSeer\\Tokenizer\\NamespaceUriException' => $vendorDir . '/theseer/tokenizer/src/NamespaceUriException.php', + 'TheSeer\\Tokenizer\\Token' => $vendorDir . '/theseer/tokenizer/src/Token.php', + 'TheSeer\\Tokenizer\\TokenCollection' => $vendorDir . '/theseer/tokenizer/src/TokenCollection.php', + 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php', + 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php', + 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php', 'WC_REST_Blocks_Controllers' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php', 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php', 'WC_REST_Blocks_Product_Attributes_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php', diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index b7fc0125dbc..b24b2176e1b 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'), ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index b265c64a22f..b6f0a419d54 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -6,4 +6,10 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'), + 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), + 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), + 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), + 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 225d4b41ba4..0f499015edf 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -47,6 +47,24 @@ class ComposerAutoloaderInitf71e7bc9895f702f48d84a180f514421 $loader->register(true); + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequiref71e7bc9895f702f48d84a180f514421($fileIdentifier, $file); + } + return $loader; } } + +function composerRequiref71e7bc9895f702f48d84a180f514421($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 47c1be3cacb..116d477d9d1 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -6,7 +6,617 @@ namespace Composer\Autoload; class ComposerStaticInitf71e7bc9895f702f48d84a180f514421 { + public static $files = array ( + '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'p' => + array ( + 'phpDocumentor\\Reflection\\' => 25, + ), + 'W' => + array ( + 'Webmozart\\Assert\\' => 17, + ), + 'S' => + array ( + 'Symfony\\Polyfill\\Ctype\\' => 23, + ), + 'D' => + array ( + 'Doctrine\\Instantiator\\' => 22, + 'DeepCopy\\' => 9, + ), + 'C' => + array ( + 'Composer\\Installers\\' => 20, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'phpDocumentor\\Reflection\\' => + array ( + 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', + 1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', + 2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', + ), + 'Webmozart\\Assert\\' => + array ( + 0 => __DIR__ . '/..' . '/webmozart/assert/src', + ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), + 'Doctrine\\Instantiator\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', + ), + 'DeepCopy\\' => + array ( + 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy', + ), + 'Composer\\Installers\\' => + array ( + 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers', + ), + ); + + public static $prefixesPsr0 = array ( + 'P' => + array ( + 'Prophecy\\' => + array ( + 0 => __DIR__ . '/..' . '/phpspec/prophecy/src', + ), + ), + ); + public static $classMap = array ( + 'File_Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php', + 'PHPUnit\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit\\Framework\\BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit\\Framework\\CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit\\Framework\\Constraint\\ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit\\Framework\\Constraint\\Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit\\Framework\\Constraint\\Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit\\Framework\\Constraint\\Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit\\Framework\\Constraint\\Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', + 'PHPUnit\\Framework\\Constraint\\Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', + 'PHPUnit\\Framework\\Constraint\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit\\Framework\\Constraint\\GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit\\Framework\\Constraint\\IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit\\Framework\\Constraint\\IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit\\Framework\\Constraint\\IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit\\Framework\\Constraint\\IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit\\Framework\\Constraint\\IsFinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit\\Framework\\Constraint\\IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\IsInfinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit\\Framework\\Constraint\\IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit\\Framework\\Constraint\\IsNan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit\\Framework\\Constraint\\IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit\\Framework\\Constraint\\IsReadable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', + 'PHPUnit\\Framework\\Constraint\\IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit\\Framework\\Constraint\\IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit\\Framework\\Constraint\\IsWritable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', + 'PHPUnit\\Framework\\Constraint\\LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', + 'PHPUnit\\Framework\\Constraint\\LogicalNot' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', + 'PHPUnit\\Framework\\Constraint\\LogicalOr' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', + 'PHPUnit\\Framework\\Constraint\\LogicalXor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit\\Framework\\Constraint\\StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', + 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', + 'PHPUnit\\Framework\\DataProviderTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', + 'PHPUnit\\Framework\\Error\\Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit\\Framework\\Error\\Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Error.php', + 'PHPUnit\\Framework\\Error\\Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit\\Framework\\Error\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit\\Framework\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit\\Framework\\ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit\\Framework\\ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit\\Framework\\IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit\\Framework\\IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit\\Framework\\IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit\\Framework\\InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit\\Framework\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', + 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/BadMethodCallException.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Match.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/NamespaceMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/ObjectInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invokable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invokable.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/ConsecutiveParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtIndex.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedRecorder.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/StatelessInvocation.php', + 'PHPUnit\\Framework\\MockObject\\MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/MockBuilder.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/ForwardCompatibility/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/MatcherCollection.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Verifiable.php', + 'PHPUnit\\Framework\\OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit\\Framework\\RiskyTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit\\Framework\\RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit\\Framework\\SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit\\Framework\\SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit\\Framework\\SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit\\Framework\\SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit\\Framework\\SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit\\Framework\\SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit\\Framework\\TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', + 'PHPUnit\\Framework\\TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit\\Framework\\TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', + 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit\\Framework\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit\\Framework\\WarningTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit\\Runner\\BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit\\Runner\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/PhptTestCase.php', + 'PHPUnit\\Runner\\StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit\\Runner\\TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit\\Runner\\Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit\\TextUI\\Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit\\TextUI\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit\\TextUI\\TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit\\Util\\Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit\\Util\\Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit\\Util\\ConfigurationGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit\\Util\\ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit\\Util\\Fileloader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit\\Util\\Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit\\Util\\Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit\\Util\\Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit\\Util\\GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit\\Util\\InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit\\Util\\Json' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Json.php', + 'PHPUnit\\Util\\Log\\JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit\\Util\\Log\\TeamCity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', + 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', + 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', + 'PHPUnit\\Util\\Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit\\Util\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/RegularExpression.php', + 'PHPUnit\\Util\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit\\Util\\TestDox\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', + 'PHPUnit\\Util\\TextTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', + 'PHPUnit\\Util\\Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit\\Util\\Xml' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Xml.php', + 'PHPUnit\\Util\\XmlTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', + 'PHPUnit_Framework_MockObject_MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/MockObject.php', + 'PHP_Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PharIo\\Manifest\\Application' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Application.php', + 'PharIo\\Manifest\\ApplicationName' => __DIR__ . '/..' . '/phar-io/manifest/src/values/ApplicationName.php', + 'PharIo\\Manifest\\Author' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Author.php', + 'PharIo\\Manifest\\AuthorCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollection.php', + 'PharIo\\Manifest\\AuthorCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', + 'PharIo\\Manifest\\AuthorElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElement.php', + 'PharIo\\Manifest\\AuthorElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElementCollection.php', + 'PharIo\\Manifest\\BundledComponent' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponent.php', + 'PharIo\\Manifest\\BundledComponentCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollection.php', + 'PharIo\\Manifest\\BundledComponentCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', + 'PharIo\\Manifest\\BundlesElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/BundlesElement.php', + 'PharIo\\Manifest\\ComponentElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElement.php', + 'PharIo\\Manifest\\ComponentElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElementCollection.php', + 'PharIo\\Manifest\\ContainsElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ContainsElement.php', + 'PharIo\\Manifest\\CopyrightElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/CopyrightElement.php', + 'PharIo\\Manifest\\CopyrightInformation' => __DIR__ . '/..' . '/phar-io/manifest/src/values/CopyrightInformation.php', + 'PharIo\\Manifest\\ElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ElementCollection.php', + 'PharIo\\Manifest\\Email' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Email.php', + 'PharIo\\Manifest\\Exception' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/Exception.php', + 'PharIo\\Manifest\\ExtElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElement.php', + 'PharIo\\Manifest\\ExtElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElementCollection.php', + 'PharIo\\Manifest\\Extension' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Extension.php', + 'PharIo\\Manifest\\ExtensionElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtensionElement.php', + 'PharIo\\Manifest\\InvalidApplicationNameException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', + 'PharIo\\Manifest\\InvalidEmailException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', + 'PharIo\\Manifest\\InvalidUrlException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', + 'PharIo\\Manifest\\Library' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Library.php', + 'PharIo\\Manifest\\License' => __DIR__ . '/..' . '/phar-io/manifest/src/values/License.php', + 'PharIo\\Manifest\\LicenseElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/LicenseElement.php', + 'PharIo\\Manifest\\Manifest' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Manifest.php', + 'PharIo\\Manifest\\ManifestDocument' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocument.php', + 'PharIo\\Manifest\\ManifestDocumentException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', + 'PharIo\\Manifest\\ManifestDocumentLoadingException' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', + 'PharIo\\Manifest\\ManifestDocumentMapper' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestDocumentMapper.php', + 'PharIo\\Manifest\\ManifestDocumentMapperException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', + 'PharIo\\Manifest\\ManifestElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestElement.php', + 'PharIo\\Manifest\\ManifestElementException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestElementException.php', + 'PharIo\\Manifest\\ManifestLoader' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestLoader.php', + 'PharIo\\Manifest\\ManifestLoaderException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', + 'PharIo\\Manifest\\ManifestSerializer' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestSerializer.php', + 'PharIo\\Manifest\\PhpElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/PhpElement.php', + 'PharIo\\Manifest\\PhpExtensionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', + 'PharIo\\Manifest\\PhpVersionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpVersionRequirement.php', + 'PharIo\\Manifest\\Requirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Requirement.php', + 'PharIo\\Manifest\\RequirementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollection.php', + 'PharIo\\Manifest\\RequirementCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', + 'PharIo\\Manifest\\RequiresElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/RequiresElement.php', + 'PharIo\\Manifest\\Type' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Type.php', + 'PharIo\\Manifest\\Url' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Url.php', + 'PharIo\\Version\\AbstractVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/AnyVersionConstraint.php', + 'PharIo\\Version\\ExactVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => __DIR__ . '/..' . '/phar-io/version/src/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidVersionException' => __DIR__ . '/..' . '/phar-io/version/src/InvalidVersionException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => __DIR__ . '/..' . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => __DIR__ . '/..' . '/phar-io/version/src/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => __DIR__ . '/..' . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => __DIR__ . '/..' . '/phar-io/version/src/VersionNumber.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/HHVM.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeCoverage\\Version' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Version.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => __DIR__ . '/..' . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\Exception' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/Exception.php', + 'SebastianBergmann\\Diff\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\OperatingSystem' => __DIR__ . '/..' . '/sebastian/environment/src/OperatingSystem.php', + 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\Exception' => __DIR__ . '/..' . '/sebastian/object-reflector/src/Exception.php', + 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-reflector/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => __DIR__ . '/..' . '/sebastian/object-reflector/src/ObjectReflector.php', + 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => __DIR__ . '/..' . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', + 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php', + 'TheSeer\\Tokenizer\\Exception' => __DIR__ . '/..' . '/theseer/tokenizer/src/Exception.php', + 'TheSeer\\Tokenizer\\NamespaceUri' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUri.php', + 'TheSeer\\Tokenizer\\NamespaceUriException' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUriException.php', + 'TheSeer\\Tokenizer\\Token' => __DIR__ . '/..' . '/theseer/tokenizer/src/Token.php', + 'TheSeer\\Tokenizer\\TokenCollection' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollection.php', + 'TheSeer\\Tokenizer\\TokenCollectionException' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollectionException.php', + 'TheSeer\\Tokenizer\\Tokenizer' => __DIR__ . '/..' . '/theseer/tokenizer/src/Tokenizer.php', + 'TheSeer\\Tokenizer\\XMLSerializer' => __DIR__ . '/..' . '/theseer/tokenizer/src/XMLSerializer.php', 'WC_REST_Blocks_Controllers' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php', 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php', 'WC_REST_Blocks_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php', @@ -179,6 +789,9 @@ class ComposerStaticInitf71e7bc9895f702f48d84a180f514421 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixesPsr0; $loader->classMap = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$classMap; }, null, ClassLoader::class); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index fe51488c706..48457e6bb55 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1 +1,1704 @@ -[] +[ + { + "name": "composer/installers", + "version": "v1.6.0", + "version_normalized": "1.6.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "phpunit/phpunit": "^4.8.36" + }, + "time": "2018-08-27T06:10:37+00:00", + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ] + }, + { + "name": "doctrine/instantiator", + "version": "1.2.0", + "version_normalized": "1.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "a2c590166b2133a4633738648b6b064edae0814a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "time": "2019-03-17T17:37:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ] + }, + { + "name": "myclabs/deep-copy", + "version": "1.9.1", + "version_normalized": "1.9.1.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "time": "2019-04-07T13:18:21+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ] + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "time": "2017-03-05T18:14:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "time": "2017-03-05T17:38:23+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "time": "2017-09-11T18:02:19+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ] + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.1", + "version_normalized": "4.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "time": "2019-04-30T17:48:53+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock." + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "version_normalized": "0.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "time": "2017-07-14T14:27:02+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ] + }, + { + "name": "phpspec/prophecy", + "version": "1.8.0", + "version_normalized": "1.8.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "time": "2018-08-05T17:53:17+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ] + }, + { + "name": "phpunit/php-code-coverage", + "version": "5.3.2", + "version_normalized": "5.3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.0", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^2.0.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-xdebug": "^2.5.5" + }, + "time": "2018-04-06T15:36:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ] + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "version_normalized": "1.4.5.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2017-11-27T13:52:08+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ] + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-06-21T13:50:34+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ] + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "version_normalized": "1.0.9.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "time": "2017-02-26T11:10:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ] + }, + { + "name": "phpunit/php-token-stream", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "791198a2c6254db10131eecfe8c06670700904db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2.4" + }, + "time": "2017-11-27T05:48:46+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ] + }, + { + "name": "phpunit/phpunit", + "version": "6.5.14", + "version_normalized": "6.5.14.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", + "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.3", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^1.0.9", + "phpunit/phpunit-mock-objects": "^5.0.9", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^2.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^1.1" + }, + "time": "2019-02-01T05:22:47+00:00", + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ] + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "5.0.10", + "version_normalized": "5.0.10.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.0", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "conflict": { + "phpunit/phpunit": "<6.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5.11" + }, + "suggest": { + "ext-soap": "*" + }, + "time": "2018-08-09T05:50:03+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "abandoned": true + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "time": "2017-03-04T06:30:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/" + }, + { + "name": "sebastian/comparator", + "version": "2.1.3", + "version_normalized": "2.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.4" + }, + "time": "2018-02-01T13:46:46+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ] + }, + { + "name": "sebastian/diff", + "version": "2.0.1", + "version_normalized": "2.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "time": "2017-08-03T08:09:46+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ] + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "version_normalized": "3.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "time": "2017-07-01T08:51:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ] + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "version_normalized": "3.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "time": "2017-04-03T13:19:02+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ] + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "time": "2017-04-27T15:39:26+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ] + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "version_normalized": "3.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-08-03T12:35:26+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-03-29T09:07:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "version_normalized": "3.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-03-03T06:23:57+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "time": "2015-07-28T20:34:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "version_normalized": "2.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "time": "2016-10-03T07:35:21+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.11.0", + "version_normalized": "1.11.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "82ebae02209c21113908c229e9883c419720738a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", + "reference": "82ebae02209c21113908c229e9883c419720738a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2019-02-06T07:57:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ] + }, + { + "name": "theseer/tokenizer", + "version": "1.1.2", + "version_normalized": "1.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8", + "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "time": "2019-04-04T09:56:43+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats" + }, + { + "name": "webmozart/assert", + "version": "1.4.0", + "version_normalized": "1.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", + "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "time": "2018-12-25T11:19:39+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ] + } +] From 9e5ab0ce932c13a841bb0ef9946e9efce727b599 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 17:37:01 +0100 Subject: [PATCH 056/440] Removing ignored files --- vendor/autoload.php | 7 - vendor/composer/ClassLoader.php | 445 ------ vendor/composer/LICENSE | 21 - vendor/composer/autoload_classmap.php | 718 ---------- vendor/composer/autoload_namespaces.php | 10 - vendor/composer/autoload_psr4.php | 15 - vendor/composer/autoload_real.php | 70 - vendor/composer/autoload_static.php | 799 ----------- vendor/composer/installed.json | 1704 ----------------------- 9 files changed, 3789 deletions(-) delete mode 100644 vendor/autoload.php delete mode 100644 vendor/composer/ClassLoader.php delete mode 100644 vendor/composer/LICENSE delete mode 100644 vendor/composer/autoload_classmap.php delete mode 100644 vendor/composer/autoload_namespaces.php delete mode 100644 vendor/composer/autoload_psr4.php delete mode 100644 vendor/composer/autoload_real.php delete mode 100644 vendor/composer/autoload_static.php delete mode 100644 vendor/composer/installed.json diff --git a/vendor/autoload.php b/vendor/autoload.php deleted file mode 100644 index f8128b854ed..00000000000 --- a/vendor/autoload.php +++ /dev/null @@ -1,7 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - // PSR-4 - private $prefixLengthsPsr4 = array(); - private $prefixDirsPsr4 = array(); - private $fallbackDirsPsr4 = array(); - - // PSR-0 - private $prefixesPsr0 = array(); - private $fallbackDirsPsr0 = array(); - - private $useIncludePath = false; - private $classMap = array(); - private $classMapAuthoritative = false; - private $missingClasses = array(); - private $apcuPrefix; - - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); - } - - return array(); - } - - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - */ - public function add($prefix, $paths, $prepend = false) - { - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - (array) $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - (array) $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - (array) $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - (array) $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - } - - /** - * Unregisters this instance as an autoloader. - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - includeFile($file); - - return true; - } - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } -} - -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; -} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE deleted file mode 100644 index f27399a042d..00000000000 --- a/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php deleted file mode 100644 index 810238a8e84..00000000000 --- a/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,718 +0,0 @@ - $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', - 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', - 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', - 'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', - 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', - 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', - 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', - 'PHPUnit\\Framework\\CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', - 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', - 'PHPUnit\\Framework\\Constraint\\ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', - 'PHPUnit\\Framework\\Constraint\\Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', - 'PHPUnit\\Framework\\Constraint\\Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', - 'PHPUnit\\Framework\\Constraint\\Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', - 'PHPUnit\\Framework\\Constraint\\Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', - 'PHPUnit\\Framework\\Constraint\\Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', - 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', - 'PHPUnit\\Framework\\Constraint\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', - 'PHPUnit\\Framework\\Constraint\\GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', - 'PHPUnit\\Framework\\Constraint\\IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', - 'PHPUnit\\Framework\\Constraint\\IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', - 'PHPUnit\\Framework\\Constraint\\IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', - 'PHPUnit\\Framework\\Constraint\\IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', - 'PHPUnit\\Framework\\Constraint\\IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', - 'PHPUnit\\Framework\\Constraint\\IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', - 'PHPUnit\\Framework\\Constraint\\IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', - 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', - 'PHPUnit\\Framework\\Constraint\\IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', - 'PHPUnit\\Framework\\Constraint\\IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', - 'PHPUnit\\Framework\\Constraint\\IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', - 'PHPUnit\\Framework\\Constraint\\IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', - 'PHPUnit\\Framework\\Constraint\\IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', - 'PHPUnit\\Framework\\Constraint\\IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', - 'PHPUnit\\Framework\\Constraint\\IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', - 'PHPUnit\\Framework\\Constraint\\LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', - 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', - 'PHPUnit\\Framework\\Constraint\\LogicalNot' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', - 'PHPUnit\\Framework\\Constraint\\LogicalOr' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', - 'PHPUnit\\Framework\\Constraint\\LogicalXor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', - 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', - 'PHPUnit\\Framework\\Constraint\\StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', - 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', - 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', - 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', - 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', - 'PHPUnit\\Framework\\DataProviderTestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', - 'PHPUnit\\Framework\\Error\\Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', - 'PHPUnit\\Framework\\Error\\Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Error.php', - 'PHPUnit\\Framework\\Error\\Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', - 'PHPUnit\\Framework\\Error\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', - 'PHPUnit\\Framework\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', - 'PHPUnit\\Framework\\ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', - 'PHPUnit\\Framework\\ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', - 'PHPUnit\\Framework\\IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', - 'PHPUnit\\Framework\\IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', - 'PHPUnit\\Framework\\IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', - 'PHPUnit\\Framework\\InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', - 'PHPUnit\\Framework\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', - 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/BadMethodCallException.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Identity.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Match.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/MethodNameMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/NamespaceMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/ParametersMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Generator.php', - 'PHPUnit\\Framework\\MockObject\\Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/ObjectInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invokable.php', - 'PHPUnit\\Framework\\MockObject\\Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/AnyInvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/AnyParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/ConsecutiveParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtIndex.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastOnce.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtMostCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedRecorder.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/MethodName.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/Parameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/StatelessInvocation.php', - 'PHPUnit\\Framework\\MockObject\\MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/MockBuilder.php', - 'PHPUnit\\Framework\\MockObject\\MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/ForwardCompatibility/MockObject.php', - 'PHPUnit\\Framework\\MockObject\\RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/RuntimeException.php', - 'PHPUnit\\Framework\\MockObject\\Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ConsecutiveCalls.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/MatcherCollection.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnArgument.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnCallback.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnReference.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnSelf.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnStub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnValueMap.php', - 'PHPUnit\\Framework\\MockObject\\Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Verifiable.php', - 'PHPUnit\\Framework\\OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', - 'PHPUnit\\Framework\\RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', - 'PHPUnit\\Framework\\RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', - 'PHPUnit\\Framework\\SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', - 'PHPUnit\\Framework\\SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', - 'PHPUnit\\Framework\\SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', - 'PHPUnit\\Framework\\SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', - 'PHPUnit\\Framework\\SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', - 'PHPUnit\\Framework\\SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', - 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', - 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', - 'PHPUnit\\Framework\\TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', - 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', - 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', - 'PHPUnit\\Framework\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', - 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', - 'PHPUnit\\Framework\\TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', - 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', - 'PHPUnit\\Framework\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', - 'PHPUnit\\Framework\\WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', - 'PHPUnit\\Runner\\BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', - 'PHPUnit\\Runner\\Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', - 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', - 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', - 'PHPUnit\\Runner\\PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Runner/PhptTestCase.php', - 'PHPUnit\\Runner\\StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', - 'PHPUnit\\Runner\\TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', - 'PHPUnit\\Runner\\Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', - 'PHPUnit\\TextUI\\Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', - 'PHPUnit\\TextUI\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', - 'PHPUnit\\TextUI\\TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', - 'PHPUnit\\Util\\Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', - 'PHPUnit\\Util\\Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', - 'PHPUnit\\Util\\ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', - 'PHPUnit\\Util\\ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', - 'PHPUnit\\Util\\Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', - 'PHPUnit\\Util\\Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', - 'PHPUnit\\Util\\Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', - 'PHPUnit\\Util\\Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', - 'PHPUnit\\Util\\GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', - 'PHPUnit\\Util\\InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', - 'PHPUnit\\Util\\Json' => $vendorDir . '/phpunit/phpunit/src/Util/Json.php', - 'PHPUnit\\Util\\Log\\JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', - 'PHPUnit\\Util\\Log\\TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', - 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', - 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', - 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', - 'PHPUnit\\Util\\Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', - 'PHPUnit\\Util\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Util/RegularExpression.php', - 'PHPUnit\\Util\\Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', - 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', - 'PHPUnit\\Util\\TestDox\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', - 'PHPUnit\\Util\\TextTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', - 'PHPUnit\\Util\\Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', - 'PHPUnit\\Util\\Xml' => $vendorDir . '/phpunit/phpunit/src/Util/Xml.php', - 'PHPUnit\\Util\\XmlTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', - 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/MockObject.php', - 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', - 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', - 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', - 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php', - 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php', - 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php', - 'PharIo\\Manifest\\AuthorCollection' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollection.php', - 'PharIo\\Manifest\\AuthorCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', - 'PharIo\\Manifest\\AuthorElement' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElement.php', - 'PharIo\\Manifest\\AuthorElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElementCollection.php', - 'PharIo\\Manifest\\BundledComponent' => $vendorDir . '/phar-io/manifest/src/values/BundledComponent.php', - 'PharIo\\Manifest\\BundledComponentCollection' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollection.php', - 'PharIo\\Manifest\\BundledComponentCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', - 'PharIo\\Manifest\\BundlesElement' => $vendorDir . '/phar-io/manifest/src/xml/BundlesElement.php', - 'PharIo\\Manifest\\ComponentElement' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElement.php', - 'PharIo\\Manifest\\ComponentElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElementCollection.php', - 'PharIo\\Manifest\\ContainsElement' => $vendorDir . '/phar-io/manifest/src/xml/ContainsElement.php', - 'PharIo\\Manifest\\CopyrightElement' => $vendorDir . '/phar-io/manifest/src/xml/CopyrightElement.php', - 'PharIo\\Manifest\\CopyrightInformation' => $vendorDir . '/phar-io/manifest/src/values/CopyrightInformation.php', - 'PharIo\\Manifest\\ElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ElementCollection.php', - 'PharIo\\Manifest\\Email' => $vendorDir . '/phar-io/manifest/src/values/Email.php', - 'PharIo\\Manifest\\Exception' => $vendorDir . '/phar-io/manifest/src/exceptions/Exception.php', - 'PharIo\\Manifest\\ExtElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtElement.php', - 'PharIo\\Manifest\\ExtElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ExtElementCollection.php', - 'PharIo\\Manifest\\Extension' => $vendorDir . '/phar-io/manifest/src/values/Extension.php', - 'PharIo\\Manifest\\ExtensionElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtensionElement.php', - 'PharIo\\Manifest\\InvalidApplicationNameException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', - 'PharIo\\Manifest\\InvalidEmailException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', - 'PharIo\\Manifest\\InvalidUrlException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', - 'PharIo\\Manifest\\Library' => $vendorDir . '/phar-io/manifest/src/values/Library.php', - 'PharIo\\Manifest\\License' => $vendorDir . '/phar-io/manifest/src/values/License.php', - 'PharIo\\Manifest\\LicenseElement' => $vendorDir . '/phar-io/manifest/src/xml/LicenseElement.php', - 'PharIo\\Manifest\\Manifest' => $vendorDir . '/phar-io/manifest/src/values/Manifest.php', - 'PharIo\\Manifest\\ManifestDocument' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocument.php', - 'PharIo\\Manifest\\ManifestDocumentException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', - 'PharIo\\Manifest\\ManifestDocumentLoadingException' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', - 'PharIo\\Manifest\\ManifestDocumentMapper' => $vendorDir . '/phar-io/manifest/src/ManifestDocumentMapper.php', - 'PharIo\\Manifest\\ManifestDocumentMapperException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', - 'PharIo\\Manifest\\ManifestElement' => $vendorDir . '/phar-io/manifest/src/xml/ManifestElement.php', - 'PharIo\\Manifest\\ManifestElementException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestElementException.php', - 'PharIo\\Manifest\\ManifestLoader' => $vendorDir . '/phar-io/manifest/src/ManifestLoader.php', - 'PharIo\\Manifest\\ManifestLoaderException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', - 'PharIo\\Manifest\\ManifestSerializer' => $vendorDir . '/phar-io/manifest/src/ManifestSerializer.php', - 'PharIo\\Manifest\\PhpElement' => $vendorDir . '/phar-io/manifest/src/xml/PhpElement.php', - 'PharIo\\Manifest\\PhpExtensionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', - 'PharIo\\Manifest\\PhpVersionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpVersionRequirement.php', - 'PharIo\\Manifest\\Requirement' => $vendorDir . '/phar-io/manifest/src/values/Requirement.php', - 'PharIo\\Manifest\\RequirementCollection' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollection.php', - 'PharIo\\Manifest\\RequirementCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', - 'PharIo\\Manifest\\RequiresElement' => $vendorDir . '/phar-io/manifest/src/xml/RequiresElement.php', - 'PharIo\\Manifest\\Type' => $vendorDir . '/phar-io/manifest/src/values/Type.php', - 'PharIo\\Manifest\\Url' => $vendorDir . '/phar-io/manifest/src/values/Url.php', - 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/AbstractVersionConstraint.php', - 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/AndVersionConstraintGroup.php', - 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/AnyVersionConstraint.php', - 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/ExactVersionConstraint.php', - 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/Exception.php', - 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/GreaterThanOrEqualToVersionConstraint.php', - 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/InvalidVersionException.php', - 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/OrVersionConstraintGroup.php', - 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php', - 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/SpecificMajorAndMinorVersionConstraint.php', - 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/SpecificMajorVersionConstraint.php', - 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/UnsupportedVersionConstraintException.php', - 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php', - 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/VersionConstraint.php', - 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php', - 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php', - 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php', - 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', - 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/HHVM.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', - 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', - 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php', - 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', - 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', - 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', - 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', - 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', - 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', - 'SebastianBergmann\\CodeCoverage\\Version' => $vendorDir . '/phpunit/php-code-coverage/src/Version.php', - 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', - 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', - 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', - 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', - 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', - 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', - 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', - 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', - 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', - 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', - 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', - 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', - 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', - 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', - 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', - 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', - 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', - 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', - 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', - 'SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php', - 'SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', - 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', - 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', - 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', - 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', - 'SebastianBergmann\\Environment\\OperatingSystem' => $vendorDir . '/sebastian/environment/src/OperatingSystem.php', - 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', - 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', - 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', - 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', - 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/exceptions/Exception.php', - 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', - 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/exceptions/RuntimeException.php', - 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', - 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', - 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', - 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\Exception' => $vendorDir . '/sebastian/object-reflector/src/Exception.php', - 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => $vendorDir . '/sebastian/object-reflector/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => $vendorDir . '/sebastian/object-reflector/src/ObjectReflector.php', - 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', - 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', - 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', - 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', - 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', - 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', - 'TheSeer\\Tokenizer\\Exception' => $vendorDir . '/theseer/tokenizer/src/Exception.php', - 'TheSeer\\Tokenizer\\NamespaceUri' => $vendorDir . '/theseer/tokenizer/src/NamespaceUri.php', - 'TheSeer\\Tokenizer\\NamespaceUriException' => $vendorDir . '/theseer/tokenizer/src/NamespaceUriException.php', - 'TheSeer\\Tokenizer\\Token' => $vendorDir . '/theseer/tokenizer/src/Token.php', - 'TheSeer\\Tokenizer\\TokenCollection' => $vendorDir . '/theseer/tokenizer/src/TokenCollection.php', - 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php', - 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php', - 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php', - 'WC_REST_Blocks_Controllers' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php', - 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php', - 'WC_REST_Blocks_Product_Attributes_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php', - 'WC_REST_Blocks_Product_Categories_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php', - 'WC_REST_Blocks_Products_Controller' => $baseDir . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php', - 'WC_REST_CRUD_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-controller.php', - 'WC_REST_Controllers_V1' => $baseDir . '/src/RestApi/Version1/class-wc-rest-controllers-v1.php', - 'WC_REST_Controllers_V2' => $baseDir . '/src/RestApi/Version2/class-wc-rest-controllers-v2.php', - 'WC_REST_Controllers_V3' => $baseDir . '/src/RestApi/Version3/class-wc-rest-controllers-v3.php', - 'WC_REST_Coupons_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/RestApi/Version3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => $baseDir . '/src/RestApi/Version3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php', - 'WooCommerce\\RestApi' => $baseDir . '/src/RestApi.php', - 'WooCommerce\\RestApi\\Version4\\Controllers' => $baseDir . '/src/RestApi/Version4/Controllers.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractController.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractObjectsController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractObjectsController.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractPostsController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractPostsController.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractShippingZonesController' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractTermsContoller' => $baseDir . '/src/RestApi/Version4/Controllers/AbstractTermsContoller.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Coupons' => $baseDir . '/src/RestApi/Version4/Controllers/Coupons.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\CustomerDownloads' => $baseDir . '/src/RestApi/Version4/Controllers/CustomerDownloads.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Customers' => $baseDir . '/src/RestApi/Version4/Controllers/Customers.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data' => $baseDir . '/src/RestApi/Version4/Controllers/Data.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Continents' => $baseDir . '/src/RestApi/Version4/Controllers/Data/Continents.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Countries' => $baseDir . '/src/RestApi/Version4/Controllers/Data/Countries.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Currencies' => $baseDir . '/src/RestApi/Version4/Controllers/Data/Currencies.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\DownloadIPs' => $baseDir . '/src/RestApi/Version4/Controllers/Data/DownloadIPs.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Leaderboards' => $baseDir . '/src/RestApi/Version4/Controllers/Leaderboards.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\NetworkOrders' => $baseDir . '/src/RestApi/Version4/Controllers/NetworkOrders.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Levels' => $baseDir . '/src/RestApi/Version4/Controllers/Onboarding/Levels.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Plugins' => $baseDir . '/src/RestApi/Version4/Controllers/Onboarding/Plugins.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Profile' => $baseDir . '/src/RestApi/Version4/Controllers/Onboarding/Profile.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\OrderNotes' => $baseDir . '/src/RestApi/Version4/Controllers/OrderNotes.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\OrderRefunds' => $baseDir . '/src/RestApi/Version4/Controllers/OrderRefunds.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Orders' => $baseDir . '/src/RestApi/Version4/Controllers/Orders.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\PaymentGateways' => $baseDir . '/src/RestApi/Version4/Controllers/PaymentGateways.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductAttributeTerms' => $baseDir . '/src/RestApi/Version4/Controllers/ProductAttributeTerms.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductAttributes' => $baseDir . '/src/RestApi/Version4/Controllers/ProductAttributes.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductCategories' => $baseDir . '/src/RestApi/Version4/Controllers/ProductCategories.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductReviews' => $baseDir . '/src/RestApi/Version4/Controllers/ProductReviews.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductShippingClasses' => $baseDir . '/src/RestApi/Version4/Controllers/ProductShippingClasses.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductTags' => $baseDir . '/src/RestApi/Version4/Controllers/ProductTags.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductVariations' => $baseDir . '/src/RestApi/Version4/Controllers/ProductVariations.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Products' => $baseDir . '/src/RestApi/Version4/Controllers/Products.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports' => $baseDir . '/src/RestApi/Version4/Controllers/Reports.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Categories' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Categories.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\CouponStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/CouponStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Coupons' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Coupons.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\CustomerStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/CustomerStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Customers' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Customers.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\DownloadStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/DownloadStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Downloads' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Downloads.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Import' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Import.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\OrderStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/OrderStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Orders' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Orders.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\PerformanceIndicators' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\ProductStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/ProductStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Products' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Products.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\RevenueStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/RevenueStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Stock' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Stock.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\StockStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/StockStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\TaxStats' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/TaxStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Taxes' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Taxes.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Variations' => $baseDir . '/src/RestApi/Version4/Controllers/Reports/Variations.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Settings' => $baseDir . '/src/RestApi/Version4/Controllers/Settings.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\SettingsOptions' => $baseDir . '/src/RestApi/Version4/Controllers/SettingsOptions.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingMethods' => $baseDir . '/src/RestApi/Version4/Controllers/ShippingMethods.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZoneLocations' => $baseDir . '/src/RestApi/Version4/Controllers/ShippingZoneLocations.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZoneMethods' => $baseDir . '/src/RestApi/Version4/Controllers/ShippingZoneMethods.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZones' => $baseDir . '/src/RestApi/Version4/Controllers/ShippingZones.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\SystemStatus' => $baseDir . '/src/RestApi/Version4/Controllers/SystemStatus.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\SystemStatusTools' => $baseDir . '/src/RestApi/Version4/Controllers/SystemStatusTools.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\TaxClasses' => $baseDir . '/src/RestApi/Version4/Controllers/TaxClasses.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Taxes' => $baseDir . '/src/RestApi/Version4/Controllers/Taxes.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Webhooks' => $baseDir . '/src/RestApi/Version4/Controllers/Webhooks.php', - 'WooCommerce\\Utilities\\SingletonTrait' => $baseDir . '/src/Utilities/SingletonTrait.php', -); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php deleted file mode 100644 index b24b2176e1b..00000000000 --- a/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,10 +0,0 @@ - array($vendorDir . '/phpspec/prophecy/src'), -); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php deleted file mode 100644 index b6f0a419d54..00000000000 --- a/vendor/composer/autoload_psr4.php +++ /dev/null @@ -1,15 +0,0 @@ - array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'), - 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), - 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), - 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), - 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), - 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'), -); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php deleted file mode 100644 index 0f499015edf..00000000000 --- a/vendor/composer/autoload_real.php +++ /dev/null @@ -1,70 +0,0 @@ -= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInitf71e7bc9895f702f48d84a180f514421::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } - - $loader->register(true); - - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequiref71e7bc9895f702f48d84a180f514421($fileIdentifier, $file); - } - - return $loader; - } -} - -function composerRequiref71e7bc9895f702f48d84a180f514421($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php deleted file mode 100644 index 116d477d9d1..00000000000 --- a/vendor/composer/autoload_static.php +++ /dev/null @@ -1,799 +0,0 @@ - __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', - '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'p' => - array ( - 'phpDocumentor\\Reflection\\' => 25, - ), - 'W' => - array ( - 'Webmozart\\Assert\\' => 17, - ), - 'S' => - array ( - 'Symfony\\Polyfill\\Ctype\\' => 23, - ), - 'D' => - array ( - 'Doctrine\\Instantiator\\' => 22, - 'DeepCopy\\' => 9, - ), - 'C' => - array ( - 'Composer\\Installers\\' => 20, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'phpDocumentor\\Reflection\\' => - array ( - 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', - 1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', - 2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', - ), - 'Webmozart\\Assert\\' => - array ( - 0 => __DIR__ . '/..' . '/webmozart/assert/src', - ), - 'Symfony\\Polyfill\\Ctype\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', - ), - 'Doctrine\\Instantiator\\' => - array ( - 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', - ), - 'DeepCopy\\' => - array ( - 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy', - ), - 'Composer\\Installers\\' => - array ( - 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers', - ), - ); - - public static $prefixesPsr0 = array ( - 'P' => - array ( - 'Prophecy\\' => - array ( - 0 => __DIR__ . '/..' . '/phpspec/prophecy/src', - ), - ), - ); - - public static $classMap = array ( - 'File_Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php', - 'File_Iterator_Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php', - 'File_Iterator_Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php', - 'PHPUnit\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php', - 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php', - 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', - 'PHPUnit\\Framework\\BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/BaseTestListener.php', - 'PHPUnit\\Framework\\CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', - 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', - 'PHPUnit\\Framework\\Constraint\\ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', - 'PHPUnit\\Framework\\Constraint\\Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', - 'PHPUnit\\Framework\\Constraint\\Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', - 'PHPUnit\\Framework\\Constraint\\Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', - 'PHPUnit\\Framework\\Constraint\\Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', - 'PHPUnit\\Framework\\Constraint\\Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php', - 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', - 'PHPUnit\\Framework\\Constraint\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', - 'PHPUnit\\Framework\\Constraint\\GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', - 'PHPUnit\\Framework\\Constraint\\IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', - 'PHPUnit\\Framework\\Constraint\\IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', - 'PHPUnit\\Framework\\Constraint\\IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', - 'PHPUnit\\Framework\\Constraint\\IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', - 'PHPUnit\\Framework\\Constraint\\IsFinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', - 'PHPUnit\\Framework\\Constraint\\IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', - 'PHPUnit\\Framework\\Constraint\\IsInfinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', - 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', - 'PHPUnit\\Framework\\Constraint\\IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', - 'PHPUnit\\Framework\\Constraint\\IsNan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', - 'PHPUnit\\Framework\\Constraint\\IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', - 'PHPUnit\\Framework\\Constraint\\IsReadable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', - 'PHPUnit\\Framework\\Constraint\\IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', - 'PHPUnit\\Framework\\Constraint\\IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', - 'PHPUnit\\Framework\\Constraint\\IsWritable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', - 'PHPUnit\\Framework\\Constraint\\LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', - 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', - 'PHPUnit\\Framework\\Constraint\\LogicalNot' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', - 'PHPUnit\\Framework\\Constraint\\LogicalOr' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', - 'PHPUnit\\Framework\\Constraint\\LogicalXor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', - 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', - 'PHPUnit\\Framework\\Constraint\\StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', - 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', - 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', - 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', - 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', - 'PHPUnit\\Framework\\DataProviderTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', - 'PHPUnit\\Framework\\Error\\Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', - 'PHPUnit\\Framework\\Error\\Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Error.php', - 'PHPUnit\\Framework\\Error\\Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php', - 'PHPUnit\\Framework\\Error\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php', - 'PHPUnit\\Framework\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception.php', - 'PHPUnit\\Framework\\ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', - 'PHPUnit\\Framework\\ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', - 'PHPUnit\\Framework\\IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php', - 'PHPUnit\\Framework\\IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', - 'PHPUnit\\Framework\\IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', - 'PHPUnit\\Framework\\InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', - 'PHPUnit\\Framework\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', - 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/BadMethodCallException.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Identity.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Match.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/MethodNameMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/NamespaceMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/ParametersMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Generator' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Generator.php', - 'PHPUnit\\Framework\\MockObject\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/ObjectInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invokable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invokable.php', - 'PHPUnit\\Framework\\MockObject\\Matcher' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/AnyInvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/AnyParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/ConsecutiveParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtIndex.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastOnce.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtMostCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedRecorder.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/MethodName.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/Parameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/StatelessInvocation.php', - 'PHPUnit\\Framework\\MockObject\\MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/MockBuilder.php', - 'PHPUnit\\Framework\\MockObject\\MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/ForwardCompatibility/MockObject.php', - 'PHPUnit\\Framework\\MockObject\\RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/RuntimeException.php', - 'PHPUnit\\Framework\\MockObject\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ConsecutiveCalls.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/MatcherCollection.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnArgument.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnCallback.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnReference.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnSelf.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnStub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnValueMap.php', - 'PHPUnit\\Framework\\MockObject\\Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Verifiable.php', - 'PHPUnit\\Framework\\OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/OutputError.php', - 'PHPUnit\\Framework\\RiskyTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTest.php', - 'PHPUnit\\Framework\\RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTestError.php', - 'PHPUnit\\Framework\\SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php', - 'PHPUnit\\Framework\\SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php', - 'PHPUnit\\Framework\\SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', - 'PHPUnit\\Framework\\SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestError.php', - 'PHPUnit\\Framework\\SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', - 'PHPUnit\\Framework\\SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SyntheticError.php', - 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php', - 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php', - 'PHPUnit\\Framework\\TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php', - 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php', - 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', - 'PHPUnit\\Framework\\TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php', - 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php', - 'PHPUnit\\Framework\\TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', - 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', - 'PHPUnit\\Framework\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Warning.php', - 'PHPUnit\\Framework\\WarningTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/WarningTestCase.php', - 'PHPUnit\\Runner\\BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', - 'PHPUnit\\Runner\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php', - 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php', - 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', - 'PHPUnit\\Runner\\PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/PhptTestCase.php', - 'PHPUnit\\Runner\\StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', - 'PHPUnit\\Runner\\TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', - 'PHPUnit\\Runner\\Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php', - 'PHPUnit\\TextUI\\Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php', - 'PHPUnit\\TextUI\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', - 'PHPUnit\\TextUI\\TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php', - 'PHPUnit\\Util\\Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php', - 'PHPUnit\\Util\\Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php', - 'PHPUnit\\Util\\ConfigurationGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', - 'PHPUnit\\Util\\ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php', - 'PHPUnit\\Util\\Fileloader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Fileloader.php', - 'PHPUnit\\Util\\Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php', - 'PHPUnit\\Util\\Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php', - 'PHPUnit\\Util\\Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php', - 'PHPUnit\\Util\\GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php', - 'PHPUnit\\Util\\InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', - 'PHPUnit\\Util\\Json' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Json.php', - 'PHPUnit\\Util\\Log\\JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php', - 'PHPUnit\\Util\\Log\\TeamCity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TeamCity.php', - 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', - 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', - 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', - 'PHPUnit\\Util\\Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php', - 'PHPUnit\\Util\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/RegularExpression.php', - 'PHPUnit\\Util\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php', - 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', - 'PHPUnit\\Util\\TestDox\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', - 'PHPUnit\\Util\\TextTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', - 'PHPUnit\\Util\\Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php', - 'PHPUnit\\Util\\Xml' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Xml.php', - 'PHPUnit\\Util\\XmlTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', - 'PHPUnit_Framework_MockObject_MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/MockObject.php', - 'PHP_Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php', - 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ASYNC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AWAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMPILER_HALT_OFFSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENUM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUALS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_JOIN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_CP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_OP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ONUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SHAPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SUPER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php', - 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', - 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHERE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_ATTRIBUTE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CHILDREN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_REQUIRED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TEXT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PharIo\\Manifest\\Application' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Application.php', - 'PharIo\\Manifest\\ApplicationName' => __DIR__ . '/..' . '/phar-io/manifest/src/values/ApplicationName.php', - 'PharIo\\Manifest\\Author' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Author.php', - 'PharIo\\Manifest\\AuthorCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollection.php', - 'PharIo\\Manifest\\AuthorCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', - 'PharIo\\Manifest\\AuthorElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElement.php', - 'PharIo\\Manifest\\AuthorElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElementCollection.php', - 'PharIo\\Manifest\\BundledComponent' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponent.php', - 'PharIo\\Manifest\\BundledComponentCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollection.php', - 'PharIo\\Manifest\\BundledComponentCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', - 'PharIo\\Manifest\\BundlesElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/BundlesElement.php', - 'PharIo\\Manifest\\ComponentElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElement.php', - 'PharIo\\Manifest\\ComponentElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElementCollection.php', - 'PharIo\\Manifest\\ContainsElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ContainsElement.php', - 'PharIo\\Manifest\\CopyrightElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/CopyrightElement.php', - 'PharIo\\Manifest\\CopyrightInformation' => __DIR__ . '/..' . '/phar-io/manifest/src/values/CopyrightInformation.php', - 'PharIo\\Manifest\\ElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ElementCollection.php', - 'PharIo\\Manifest\\Email' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Email.php', - 'PharIo\\Manifest\\Exception' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/Exception.php', - 'PharIo\\Manifest\\ExtElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElement.php', - 'PharIo\\Manifest\\ExtElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElementCollection.php', - 'PharIo\\Manifest\\Extension' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Extension.php', - 'PharIo\\Manifest\\ExtensionElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtensionElement.php', - 'PharIo\\Manifest\\InvalidApplicationNameException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', - 'PharIo\\Manifest\\InvalidEmailException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', - 'PharIo\\Manifest\\InvalidUrlException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', - 'PharIo\\Manifest\\Library' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Library.php', - 'PharIo\\Manifest\\License' => __DIR__ . '/..' . '/phar-io/manifest/src/values/License.php', - 'PharIo\\Manifest\\LicenseElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/LicenseElement.php', - 'PharIo\\Manifest\\Manifest' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Manifest.php', - 'PharIo\\Manifest\\ManifestDocument' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocument.php', - 'PharIo\\Manifest\\ManifestDocumentException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', - 'PharIo\\Manifest\\ManifestDocumentLoadingException' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', - 'PharIo\\Manifest\\ManifestDocumentMapper' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestDocumentMapper.php', - 'PharIo\\Manifest\\ManifestDocumentMapperException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', - 'PharIo\\Manifest\\ManifestElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestElement.php', - 'PharIo\\Manifest\\ManifestElementException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestElementException.php', - 'PharIo\\Manifest\\ManifestLoader' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestLoader.php', - 'PharIo\\Manifest\\ManifestLoaderException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', - 'PharIo\\Manifest\\ManifestSerializer' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestSerializer.php', - 'PharIo\\Manifest\\PhpElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/PhpElement.php', - 'PharIo\\Manifest\\PhpExtensionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', - 'PharIo\\Manifest\\PhpVersionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpVersionRequirement.php', - 'PharIo\\Manifest\\Requirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Requirement.php', - 'PharIo\\Manifest\\RequirementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollection.php', - 'PharIo\\Manifest\\RequirementCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', - 'PharIo\\Manifest\\RequiresElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/RequiresElement.php', - 'PharIo\\Manifest\\Type' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Type.php', - 'PharIo\\Manifest\\Url' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Url.php', - 'PharIo\\Version\\AbstractVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/AbstractVersionConstraint.php', - 'PharIo\\Version\\AndVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/AndVersionConstraintGroup.php', - 'PharIo\\Version\\AnyVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/AnyVersionConstraint.php', - 'PharIo\\Version\\ExactVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/ExactVersionConstraint.php', - 'PharIo\\Version\\Exception' => __DIR__ . '/..' . '/phar-io/version/src/Exception.php', - 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/GreaterThanOrEqualToVersionConstraint.php', - 'PharIo\\Version\\InvalidVersionException' => __DIR__ . '/..' . '/phar-io/version/src/InvalidVersionException.php', - 'PharIo\\Version\\OrVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/OrVersionConstraintGroup.php', - 'PharIo\\Version\\PreReleaseSuffix' => __DIR__ . '/..' . '/phar-io/version/src/PreReleaseSuffix.php', - 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/SpecificMajorAndMinorVersionConstraint.php', - 'PharIo\\Version\\SpecificMajorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/SpecificMajorVersionConstraint.php', - 'PharIo\\Version\\UnsupportedVersionConstraintException' => __DIR__ . '/..' . '/phar-io/version/src/UnsupportedVersionConstraintException.php', - 'PharIo\\Version\\Version' => __DIR__ . '/..' . '/phar-io/version/src/Version.php', - 'PharIo\\Version\\VersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraint.php', - 'PharIo\\Version\\VersionConstraintParser' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintParser.php', - 'PharIo\\Version\\VersionConstraintValue' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintValue.php', - 'PharIo\\Version\\VersionNumber' => __DIR__ . '/..' . '/phar-io/version/src/VersionNumber.php', - 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php', - 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Driver.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/HHVM.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', - 'SebastianBergmann\\CodeCoverage\\Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/Exception.php', - 'SebastianBergmann\\CodeCoverage\\Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Filter.php', - 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', - 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Builder.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Node\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/File.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Iterator.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Clover.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Crap4j.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', - 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/PHP.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Text.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', - 'SebastianBergmann\\CodeCoverage\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', - 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', - 'SebastianBergmann\\CodeCoverage\\Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Util.php', - 'SebastianBergmann\\CodeCoverage\\Version' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Version.php', - 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => __DIR__ . '/..' . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', - 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php', - 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php', - 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php', - 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php', - 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php', - 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php', - 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php', - 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php', - 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php', - 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php', - 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php', - 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php', - 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php', - 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php', - 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php', - 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php', - 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php', - 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php', - 'SebastianBergmann\\Diff\\Exception' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/Exception.php', - 'SebastianBergmann\\Diff\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php', - 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', - 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', - 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php', - 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php', - 'SebastianBergmann\\Environment\\OperatingSystem' => __DIR__ . '/..' . '/sebastian/environment/src/OperatingSystem.php', - 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php', - 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php', - 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php', - 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php', - 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/Exception.php', - 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php', - 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/RuntimeException.php', - 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php', - 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Enumerator.php', - 'SebastianBergmann\\ObjectEnumerator\\Exception' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Exception.php', - 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\Exception' => __DIR__ . '/..' . '/sebastian/object-reflector/src/Exception.php', - 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-reflector/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => __DIR__ . '/..' . '/sebastian/object-reflector/src/ObjectReflector.php', - 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php', - 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php', - 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php', - 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => __DIR__ . '/..' . '/sebastian/resource-operations/src/ResourceOperations.php', - 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', - 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php', - 'TheSeer\\Tokenizer\\Exception' => __DIR__ . '/..' . '/theseer/tokenizer/src/Exception.php', - 'TheSeer\\Tokenizer\\NamespaceUri' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUri.php', - 'TheSeer\\Tokenizer\\NamespaceUriException' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUriException.php', - 'TheSeer\\Tokenizer\\Token' => __DIR__ . '/..' . '/theseer/tokenizer/src/Token.php', - 'TheSeer\\Tokenizer\\TokenCollection' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollection.php', - 'TheSeer\\Tokenizer\\TokenCollectionException' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollectionException.php', - 'TheSeer\\Tokenizer\\Tokenizer' => __DIR__ . '/..' . '/theseer/tokenizer/src/Tokenizer.php', - 'TheSeer\\Tokenizer\\XMLSerializer' => __DIR__ . '/..' . '/theseer/tokenizer/src/XMLSerializer.php', - 'WC_REST_Blocks_Controllers' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php', - 'WC_REST_Blocks_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php', - 'WC_REST_Blocks_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php', - 'WC_REST_Blocks_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php', - 'WC_REST_Blocks_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php', - 'WC_REST_CRUD_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-controller.php', - 'WC_REST_Controllers_V1' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-controllers-v1.php', - 'WC_REST_Controllers_V2' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-controllers-v2.php', - 'WC_REST_Controllers_V3' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-controllers-v3.php', - 'WC_REST_Coupons_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php', - 'WooCommerce\\RestApi' => __DIR__ . '/../..' . '/src/RestApi.php', - 'WooCommerce\\RestApi\\Version4\\Controllers' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractController.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractObjectsController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractObjectsController.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractPostsController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractPostsController.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractShippingZonesController' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\AbstractTermsContoller' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/AbstractTermsContoller.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Coupons' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Coupons.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\CustomerDownloads' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/CustomerDownloads.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Customers' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Customers.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Continents' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data/Continents.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Countries' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data/Countries.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\Currencies' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data/Currencies.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Data\\DownloadIPs' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Data/DownloadIPs.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Leaderboards' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Leaderboards.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\NetworkOrders' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/NetworkOrders.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Levels' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Onboarding/Levels.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Plugins' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Onboarding/Plugins.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Onboarding\\Profile' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Onboarding/Profile.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\OrderNotes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/OrderNotes.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\OrderRefunds' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/OrderRefunds.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Orders' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Orders.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\PaymentGateways' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/PaymentGateways.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductAttributeTerms' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductAttributeTerms.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductAttributes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductAttributes.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductCategories' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductCategories.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductReviews' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductReviews.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductShippingClasses' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductShippingClasses.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductTags' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductTags.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ProductVariations' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ProductVariations.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Products' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Products.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Categories' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Categories.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\CouponStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/CouponStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Coupons' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Coupons.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\CustomerStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/CustomerStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Customers' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Customers.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\DownloadStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/DownloadStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Downloads' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Downloads.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Import' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Import.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\OrderStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/OrderStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Orders' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Orders.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\PerformanceIndicators' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\ProductStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/ProductStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Products' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Products.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\RevenueStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/RevenueStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Stock' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Stock.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\StockStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/StockStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\TaxStats' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/TaxStats.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Taxes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Taxes.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Reports\\Variations' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Reports/Variations.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Settings' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Settings.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\SettingsOptions' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/SettingsOptions.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingMethods' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ShippingMethods.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZoneLocations' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ShippingZoneLocations.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZoneMethods' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ShippingZoneMethods.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\ShippingZones' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/ShippingZones.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\SystemStatus' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/SystemStatus.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\SystemStatusTools' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/SystemStatusTools.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\TaxClasses' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/TaxClasses.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Taxes' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Taxes.php', - 'WooCommerce\\RestApi\\Version4\\Controllers\\Webhooks' => __DIR__ . '/../..' . '/src/RestApi/Version4/Controllers/Webhooks.php', - 'WooCommerce\\Utilities\\SingletonTrait' => __DIR__ . '/../..' . '/src/Utilities/SingletonTrait.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixesPsr0; - $loader->classMap = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json deleted file mode 100644 index 48457e6bb55..00000000000 --- a/vendor/composer/installed.json +++ /dev/null @@ -1,1704 +0,0 @@ -[ - { - "name": "composer/installers", - "version": "v1.6.0", - "version_normalized": "1.6.0.0", - "source": { - "type": "git", - "url": "https://github.com/composer/installers.git", - "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b", - "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0" - }, - "replace": { - "roundcube/plugin-installer": "*", - "shama/baton": "*" - }, - "require-dev": { - "composer/composer": "1.0.*@dev", - "phpunit/phpunit": "^4.8.36" - }, - "time": "2018-08-27T06:10:37+00:00", - "type": "composer-plugin", - "extra": { - "class": "Composer\\Installers\\Plugin", - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Composer\\Installers\\": "src/Composer/Installers" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kyle Robinson Young", - "email": "kyle@dontkry.com", - "homepage": "https://github.com/shama" - } - ], - "description": "A multi-framework Composer library installer", - "homepage": "https://composer.github.io/installers/", - "keywords": [ - "Craft", - "Dolibarr", - "Eliasis", - "Hurad", - "ImageCMS", - "Kanboard", - "Lan Management System", - "MODX Evo", - "Mautic", - "Maya", - "OXID", - "Plentymarkets", - "Porto", - "RadPHP", - "SMF", - "Thelia", - "WolfCMS", - "agl", - "aimeos", - "annotatecms", - "attogram", - "bitrix", - "cakephp", - "chef", - "cockpit", - "codeigniter", - "concrete5", - "croogo", - "dokuwiki", - "drupal", - "eZ Platform", - "elgg", - "expressionengine", - "fuelphp", - "grav", - "installer", - "itop", - "joomla", - "kohana", - "laravel", - "lavalite", - "lithium", - "magento", - "majima", - "mako", - "mediawiki", - "modulework", - "modx", - "moodle", - "osclass", - "phpbb", - "piwik", - "ppi", - "puppet", - "pxcms", - "reindex", - "roundcube", - "shopware", - "silverstripe", - "sydes", - "symfony", - "typo3", - "wordpress", - "yawik", - "zend", - "zikula" - ] - }, - { - "name": "doctrine/instantiator", - "version": "1.2.0", - "version_normalized": "1.2.0.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "a2c590166b2133a4633738648b6b064edae0814a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", - "reference": "a2c590166b2133a4633738648b6b064edae0814a", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" - }, - "time": "2019-03-17T17:37:11+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ] - }, - { - "name": "myclabs/deep-copy", - "version": "1.9.1", - "version_normalized": "1.9.1.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "time": "2019-04-07T13:18:21+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ] - }, - { - "name": "phar-io/manifest", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" - }, - "time": "2017-03-05T18:14:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)" - }, - { - "name": "phar-io/version", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "time": "2017-03-05T17:38:23+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" - }, - "time": "2017-09-11T18:02:19+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ] - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.1", - "version_normalized": "4.3.1.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "~1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "time": "2019-04-30T17:48:53+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock." - }, - { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", - "version_normalized": "0.4.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" - }, - "time": "2017-07-14T14:27:02+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ] - }, - { - "name": "phpspec/prophecy", - "version": "1.8.0", - "version_normalized": "1.8.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "time": "2018-08-05T17:53:17+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ] - }, - { - "name": "phpunit/php-code-coverage", - "version": "5.3.2", - "version_normalized": "5.3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-xdebug": "^2.5.5" - }, - "time": "2018-04-06T15:36:58+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.3.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ] - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "version_normalized": "1.4.5.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2017-11-27T13:52:08+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ] - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "version_normalized": "1.2.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2015-06-21T13:50:34+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ] - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "version_normalized": "1.0.9.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "time": "2017-02-26T11:10:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ] - }, - { - "name": "phpunit/php-token-stream", - "version": "2.0.2", - "version_normalized": "2.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2.4" - }, - "time": "2017-11-27T05:48:46+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ] - }, - { - "name": "phpunit/phpunit", - "version": "6.5.14", - "version_normalized": "6.5.14.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.9", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" - }, - "time": "2019-02-01T05:22:47+00:00", - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.5.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ] - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.10", - "version_normalized": "5.0.10.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5.11" - }, - "suggest": { - "ext-soap": "*" - }, - "time": "2018-08-09T05:50:03+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "abandoned": true - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "time": "2017-03-04T06:30:41+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/" - }, - { - "name": "sebastian/comparator", - "version": "2.1.3", - "version_normalized": "2.1.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.4" - }, - "time": "2018-02-01T13:46:46+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ] - }, - { - "name": "sebastian/diff", - "version": "2.0.1", - "version_normalized": "2.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2" - }, - "time": "2017-08-03T08:09:46+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ] - }, - { - "name": "sebastian/environment", - "version": "3.1.0", - "version_normalized": "3.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.1" - }, - "time": "2017-07-01T08:51:00+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ] - }, - { - "name": "sebastian/exporter", - "version": "3.1.0", - "version_normalized": "3.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "time": "2017-04-03T13:19:02+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ] - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "time": "2017-04-27T15:39:26+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ] - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "version_normalized": "3.0.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "time": "2017-08-03T12:35:26+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "version_normalized": "1.1.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "time": "2017-03-29T09:07:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "version_normalized": "3.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "time": "2017-03-03T06:23:57+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context" - }, - { - "name": "sebastian/resource-operations", - "version": "1.0.0", - "version_normalized": "1.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "time": "2015-07-28T20:34:47+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "version_normalized": "2.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "time": "2016-10-03T07:35:21+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.11.0", - "version_normalized": "1.11.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "82ebae02209c21113908c229e9883c419720738a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", - "reference": "82ebae02209c21113908c229e9883c419720738a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "time": "2019-02-06T07:57:58+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - }, - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ] - }, - { - "name": "theseer/tokenizer", - "version": "1.1.2", - "version_normalized": "1.1.2.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8", - "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "time": "2019-04-04T09:56:43+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats" - }, - { - "name": "webmozart/assert", - "version": "1.4.0", - "version_normalized": "1.4.0.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "time": "2018-12-25T11:19:39+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ] - } -] From de1c37805425502f172791e0ffa1a7600d0c8996 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 6 Jun 2019 17:39:14 +0100 Subject: [PATCH 057/440] Add more instructions on composer --- README.md | 4 ++++ src/RestApi.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index bf6d658bea9..ac2c5d64e71 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,10 @@ This repository is home to the WooCommerce REST API package. The stable version of this package is bundled with [WooCommerce core](https://github.com/woocommerce/woocommerce) releases, but it can also be used as a standalone plugin so bleeding-edge API features can be tested or used by other feature plugins. +## Using this repo + +After checking out the code, you'll need to run `composer install` in it's root directory to install dependencies and to enable the autoloader. + ## Using this package This package is [hosted on Packagist](https://packagist.org/packages/woocommerce/woocommerce-rest-api) and can be included using composer.json: diff --git a/src/RestApi.php b/src/RestApi.php index d2d23678d84..bb5d7a9161d 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -11,6 +11,8 @@ defined( 'ABSPATH' ) || exit; if ( file_exists( __DIR__ . '/../vendor/autoload.php' ) ) { require __DIR__ . '/../vendor/autoload.php'; +} else { + return; } use WooCommerce\Utilities\SingletonTrait; From 95b72e56f5a67e831d8fe284baec7cc255f60f50 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 7 Jun 2019 16:32:42 +0100 Subject: [PATCH 058/440] Progress adding unit tests from core + wc-admin --- .../Controllers/AbstractObjectsController.php | 61 +- src/RestApi/Version4/Controllers/Coupons.php | 290 +----- src/RestApi/Version4/Controllers/Orders.php | 58 +- tests/AbstractRestApiTest.php | 149 ++- tests/Blocks/products-attributes-terms.php | 105 ++ tests/Blocks/products-attributes.php | 105 ++ tests/Blocks/products-categories.php | 121 +++ tests/Blocks/products.php | 305 ++++++ tests/Version2/coupons.php | 471 +++++++++ tests/Version2/customers.php | 566 +++++++++++ tests/Version2/orders.php | 635 ++++++++++++ tests/Version2/payment-gateways.php | 337 +++++++ tests/Version2/product-reviews.php | 468 +++++++++ tests/Version2/product-variations.php | 473 +++++++++ tests/Version2/products.php | 535 ++++++++++ tests/Version2/settings.php | 892 +++++++++++++++++ tests/Version2/shipping-methods.php | 143 +++ tests/Version2/shipping-zones.php | 800 +++++++++++++++ tests/Version2/system-status.php | 356 +++++++ tests/Version3/coupons.php | 471 +++++++++ tests/Version3/customers.php | 634 ++++++++++++ tests/Version3/functions.php | 251 +++++ tests/Version3/orders.php | 665 +++++++++++++ tests/Version3/payment-gateways.php | 345 +++++++ tests/Version3/product-reviews.php | 470 +++++++++ tests/Version3/product-variations.php | 474 +++++++++ tests/Version3/products.php | 807 +++++++++++++++ tests/Version3/reports-coupons-totals.php | 103 ++ tests/Version3/reports-customers-totals.php | 119 +++ tests/Version3/reports-orders-totals.php | 92 ++ tests/Version3/reports-products-totals.php | 99 ++ tests/Version3/reports-reviews-totals.php | 98 ++ tests/Version3/settings.php | 895 +++++++++++++++++ tests/Version3/shipping-methods.php | 143 +++ tests/Version3/shipping-zones.php | 825 ++++++++++++++++ tests/Version3/system-status.php | 467 +++++++++ tests/Version4/Coupons.php | 316 +++--- .../Version4/Onboarding/onboarding-levels.php | 107 ++ .../Onboarding/onboarding-profile.php | 150 +++ tests/Version4/Orders.php | 657 +++++++++++++ tests/Version4/Reports/reports-categories.php | 182 ++++ .../Reports/reports-coupons-stats.php | 180 ++++ tests/Version4/Reports/reports-coupons.php | 188 ++++ .../Reports/reports-customers-stats.php | 172 ++++ tests/Version4/Reports/reports-customers.php | 405 ++++++++ .../Reports/reports-downloads-stats.php | 365 +++++++ tests/Version4/Reports/reports-downloads.php | 414 ++++++++ tests/Version4/Reports/reports-import.php | 397 ++++++++ tests/Version4/Reports/reports-interval.php | 925 ++++++++++++++++++ .../Version4/Reports/reports-orders-stats.php | 132 +++ tests/Version4/Reports/reports-orders.php | 128 +++ .../reports-performance-indicators.php | 183 ++++ .../Reports/reports-products-stats.php | 171 ++++ tests/Version4/Reports/reports-products.php | 174 ++++ .../Reports/reports-revenue-stats.php | 135 +++ .../Version4/Reports/reports-stock-stats.php | 139 +++ tests/Version4/Reports/reports-stock.php | 119 +++ .../Version4/Reports/reports-taxes-stats.php | 172 ++++ tests/Version4/Reports/reports-taxes.php | 363 +++++++ tests/Version4/Reports/reports-variations.php | 183 ++++ tests/Version4/admin-notes.php | 313 ++++++ tests/Version4/data.php | 119 +++ tests/Version4/leaderboards.php | 154 +++ tests/Version4/product-reviews.php | 50 + tests/Version4/products.php | 62 ++ tests/bootstrap.php | 1 + 66 files changed, 20437 insertions(+), 447 deletions(-) create mode 100644 tests/Blocks/products-attributes-terms.php create mode 100644 tests/Blocks/products-attributes.php create mode 100644 tests/Blocks/products-categories.php create mode 100644 tests/Blocks/products.php create mode 100644 tests/Version2/coupons.php create mode 100644 tests/Version2/customers.php create mode 100644 tests/Version2/orders.php create mode 100644 tests/Version2/payment-gateways.php create mode 100644 tests/Version2/product-reviews.php create mode 100644 tests/Version2/product-variations.php create mode 100644 tests/Version2/products.php create mode 100644 tests/Version2/settings.php create mode 100644 tests/Version2/shipping-methods.php create mode 100644 tests/Version2/shipping-zones.php create mode 100644 tests/Version2/system-status.php create mode 100644 tests/Version3/coupons.php create mode 100644 tests/Version3/customers.php create mode 100644 tests/Version3/functions.php create mode 100644 tests/Version3/orders.php create mode 100644 tests/Version3/payment-gateways.php create mode 100644 tests/Version3/product-reviews.php create mode 100644 tests/Version3/product-variations.php create mode 100644 tests/Version3/products.php create mode 100644 tests/Version3/reports-coupons-totals.php create mode 100644 tests/Version3/reports-customers-totals.php create mode 100644 tests/Version3/reports-orders-totals.php create mode 100644 tests/Version3/reports-products-totals.php create mode 100644 tests/Version3/reports-reviews-totals.php create mode 100644 tests/Version3/settings.php create mode 100644 tests/Version3/shipping-methods.php create mode 100644 tests/Version3/shipping-zones.php create mode 100644 tests/Version3/system-status.php create mode 100644 tests/Version4/Onboarding/onboarding-levels.php create mode 100644 tests/Version4/Onboarding/onboarding-profile.php create mode 100644 tests/Version4/Orders.php create mode 100644 tests/Version4/Reports/reports-categories.php create mode 100644 tests/Version4/Reports/reports-coupons-stats.php create mode 100644 tests/Version4/Reports/reports-coupons.php create mode 100644 tests/Version4/Reports/reports-customers-stats.php create mode 100644 tests/Version4/Reports/reports-customers.php create mode 100644 tests/Version4/Reports/reports-downloads-stats.php create mode 100644 tests/Version4/Reports/reports-downloads.php create mode 100644 tests/Version4/Reports/reports-import.php create mode 100644 tests/Version4/Reports/reports-interval.php create mode 100644 tests/Version4/Reports/reports-orders-stats.php create mode 100644 tests/Version4/Reports/reports-orders.php create mode 100644 tests/Version4/Reports/reports-performance-indicators.php create mode 100644 tests/Version4/Reports/reports-products-stats.php create mode 100644 tests/Version4/Reports/reports-products.php create mode 100644 tests/Version4/Reports/reports-revenue-stats.php create mode 100644 tests/Version4/Reports/reports-stock-stats.php create mode 100644 tests/Version4/Reports/reports-stock.php create mode 100644 tests/Version4/Reports/reports-taxes-stats.php create mode 100644 tests/Version4/Reports/reports-taxes.php create mode 100644 tests/Version4/Reports/reports-variations.php create mode 100644 tests/Version4/admin-notes.php create mode 100644 tests/Version4/data.php create mode 100644 tests/Version4/leaderboards.php create mode 100644 tests/Version4/product-reviews.php create mode 100644 tests/Version4/products.php diff --git a/src/RestApi/Version4/Controllers/AbstractObjectsController.php b/src/RestApi/Version4/Controllers/AbstractObjectsController.php index ce0f5fe2725..ff1a4d9fd7e 100644 --- a/src/RestApi/Version4/Controllers/AbstractObjectsController.php +++ b/src/RestApi/Version4/Controllers/AbstractObjectsController.php @@ -221,7 +221,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $object = $this->save_object( $request, false ); @@ -272,6 +272,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { $args['post_parent__in'] = $request['parent']; $args['post_parent__not_in'] = $request['parent_exclude']; $args['s'] = $request['search']; + $args['fields'] = 'ids'; if ( 'date' === $args['orderby'] ) { $args['orderby'] = 'date ID'; @@ -348,7 +349,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { continue; } - $data = $this->prepare_object_for_response( $object, $request ); + $data = $this->prepare_object_for_response( $object, $request ); $objects[] = $this->prepare_response_for_collection( $data ); } @@ -407,17 +408,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); - - /** - * Filter whether an object is trashable. - * - * Return false to disable trash support for the object. - * - * @param boolean $supports_trash Whether the object type support trashing. - * @param WC_Data $object The object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + $supports_trash = $this->supports_trash( $object ); if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { /* translators: %s: post type */ @@ -425,7 +416,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { } $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); + $previous = $this->prepare_object_for_response( $object, $request ); // If we're forcing, then delete permanently. if ( $force ) { @@ -439,14 +430,12 @@ abstract class AbstractObjectsController extends AbstractPostsController { } // Otherwise, only trash if we haven't already. - if ( is_callable( array( $object, 'get_status' ) ) ) { - if ( 'trash' === $object->get_status() ) { - /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); - } - + if ( is_callable( array( $object, 'get_status' ) ) && 'trash' === $object->get_status() ) { + /* translators: %s: post type */ + return new \WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } else { $object->delete(); - $result = 'trash' === $object->get_status(); + $result = is_callable( array( $object, 'get_status' ) ) ? 'trash' === $object->get_status() : true; } } @@ -455,6 +444,14 @@ abstract class AbstractObjectsController extends AbstractPostsController { return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } + $response = new \WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); + /** * Fires after a single object is deleted or trashed via the REST API. * @@ -467,10 +464,30 @@ abstract class AbstractObjectsController extends AbstractPostsController { return $response; } + /** + * Can this object be trashed? + * + * @oaram object $object Object to check. + * @return boolean + */ + protected function supports_trash( $object ) { + $supports_trash = EMPTY_TRASH_DAYS > 0; + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + return apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + } + /** * Prepare links for the request. * - * @param WC_Data $object Object data. + * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/RestApi/Version4/Controllers/Coupons.php index a7c2039e300..ceb62d7766a 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -14,7 +14,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Coupons controller class. */ -class Coupons extends AbstractPostsController { +class Coupons extends AbstractObjectsController { /** * Route base. @@ -30,13 +30,6 @@ class Coupons extends AbstractPostsController { */ protected $post_type = 'shop_coupon'; - /** - * Coupons actions. - */ - public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 ); - } - /** * Register the routes for coupons. */ @@ -205,7 +198,7 @@ class Coupons extends AbstractPostsController { * Prepare a single coupon output for response. * * @since 3.0.0 - * @param WC_Data $object Object data. + * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ @@ -250,9 +243,6 @@ class Coupons extends AbstractPostsController { $args['s'] = false; } - // Get only ids. - $args['fields'] = 'ids'; - return $args; } @@ -260,7 +250,7 @@ class Coupons extends AbstractPostsController { * Prepare a single coupon for create or update. * * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. + * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { @@ -549,101 +539,6 @@ class Coupons extends AbstractPostsController { return $params; } - /** - * Query args. - * - * @param array $args Query args. - * @param \WP_REST_Request $request Request data. - * @return array - */ - public function query_args( $args, $request ) { - if ( ! empty( $request['code'] ) ) { - $id = wc_get_coupon_id_by_code( $request['code'] ); - $args['post__in'] = array( $id ); - } - - return $args; - } - - /** - * Prepare a single coupon output for response. - * - * @param WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $data - */ - public function prepare_item_for_response( $post, $request ) { - $coupon = new \WC_Coupon( (int) $post->ID ); - $_data = $coupon->get_data(); - - $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); - $format_date = array( 'date_created', 'date_modified' ); - $format_date_utc = array( 'date_expires' ); - $format_null = array( 'usage_limit', 'usage_limit_per_user' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $_data[ $key ] = wc_format_decimal( $_data[ $key ], 2 ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ], false ) : null; - } - foreach ( $format_date_utc as $key ) { - $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; - } - - // Format null values. - foreach ( $format_null as $key ) { - $_data[ $key ] = $_data[ $key ] ? $_data[ $key ] : null; - } - - $data = array( - 'id' => $_data['id'], - 'code' => $_data['code'], - 'date_created' => $_data['date_created'], - 'date_modified' => $_data['date_modified'], - 'discount_type' => $_data['discount_type'], - 'description' => $_data['description'], - 'amount' => $_data['amount'], - 'expiry_date' => $_data['date_expires'], - 'usage_count' => $_data['usage_count'], - 'individual_use' => $_data['individual_use'], - 'product_ids' => $_data['product_ids'], - 'exclude_product_ids' => $_data['excluded_product_ids'], - 'usage_limit' => $_data['usage_limit'], - 'usage_limit_per_user' => $_data['usage_limit_per_user'], - 'limit_usage_to_x_items' => $_data['limit_usage_to_x_items'], - 'free_shipping' => $_data['free_shipping'], - 'product_categories' => $_data['product_categories'], - 'excluded_product_categories' => $_data['excluded_product_categories'], - 'exclude_sale_items' => $_data['exclude_sale_items'], - 'minimum_amount' => $_data['minimum_amount'], - 'maximum_amount' => $_data['maximum_amount'], - 'email_restrictions' => $_data['email_restrictions'], - 'used_by' => $_data['used_by'], - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $post, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); - } - /** * Only return writable props from schema. * @@ -654,179 +549,6 @@ class Coupons extends AbstractPostsController { return empty( $schema['readonly'] ); } - /** - * Prepare a single coupon for create or update. - * - * @param \WP_REST_Request $request Request object. - * @return \WP_Error|stdClass $data Post object. - */ - protected function prepare_item_for_database( $request ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $coupon = new \WC_Coupon( $id ); - $schema = $this->get_item_schema(); - $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - - // Update to schema to make compatible with CRUD schema. - if ( $request['exclude_product_ids'] ) { - $request['excluded_product_ids'] = $request['exclude_product_ids']; - } - if ( $request['expiry_date'] ) { - $request['date_expires'] = $request['expiry_date']; - } - - // Validate required POST fields. - if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { - if ( empty( $request['code'] ) ) { - return new \WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); - } - } - - // Handle all writable props. - foreach ( $data_keys as $key ) { - $value = $request[ $key ]; - - if ( ! is_null( $value ) ) { - switch ( $key ) { - case 'code': - $coupon_code = wc_format_coupon_code( $value ); - $id = $coupon->get_id() ? $coupon->get_id() : 0; - $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); - - if ( $id_from_code ) { - return new \WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); - } - - $coupon->set_code( $coupon_code ); - break; - case 'description': - $coupon->set_description( wp_filter_post_kses( $value ) ); - break; - case 'expiry_date': - $coupon->set_date_expires( $value ); - break; - default: - if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { - $coupon->{"set_{$key}"}( $value ); - } - break; - } - } - } - - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for insertion. - * - * @param WC_Coupon $coupon The coupon object. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request ); - } - - /** - * Create a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $coupon_id = $this->save_coupon( $request ); - if ( is_wp_error( $coupon_id ) ) { - return $coupon_id; - } - - $post = get_post( $coupon_id ); - $this->update_additional_fields_for_object( $post, $request ); - - $this->add_post_meta_fields( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); - - return $response; - } - - /** - * Saves a coupon to the database. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|int - */ - protected function save_coupon( $request ) { - try { - $coupon = $this->prepare_item_for_database( $request ); - - if ( is_wp_error( $coupon ) ) { - return $coupon; - } - - $coupon->save(); - return $coupon->get_id(); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Update a single coupon. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - try { - $post_id = (int) $request['id']; - - if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - $coupon_id = $this->save_coupon( $request ); - if ( is_wp_error( $coupon_id ) ) { - return $coupon_id; - } - - $post = get_post( $coupon_id ); - $this->update_additional_fields_for_object( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - return rest_ensure_response( $response ); - - } catch ( Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - /** * Get a collection of posts and add the code search option to \WP_Query. * @@ -834,9 +556,9 @@ class Coupons extends AbstractPostsController { * @return \WP_Error|WP_REST_Response */ public function get_items( $request ) { - add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10, 2 ); + add_filter( 'posts_where', array( $this, 'add_wp_query_search_code_filter' ), 10, 2 ); $response = parent::get_items( $request ); - remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_search_code_filter' ), 10 ); + remove_filter( 'posts_where', array( $this, 'add_wp_query_search_code_filter' ), 10 ); return $response; } @@ -847,7 +569,7 @@ class Coupons extends AbstractPostsController { * @param object $wp_query \WP_Query object. * @return string */ - public static function add_wp_query_search_code_filter( $where, $wp_query ) { + public function add_wp_query_search_code_filter( $where, $wp_query ) { global $wpdb; $search = $wp_query->get( 'search' ); diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index 8833af19e9b..24ae9a4b24a 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -291,7 +291,7 @@ class Orders extends AbstractObjectsController { * Prepare a single order output for response. * * @since 3.0.0 - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return WP_REST_Response */ @@ -321,7 +321,7 @@ class Orders extends AbstractObjectsController { /** * Prepare links for the request. * - * @param WC_Data $object Object data. + * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ @@ -381,6 +381,47 @@ class Orders extends AbstractObjectsController { // Put the statuses back for further processing (next/prev links, etc). $request['status'] = $statuses; + // Customer. + if ( isset( $request['customer'] ) ) { + if ( ! empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); // WPCS: slow query ok. + } + + $args['meta_query'][] = array( + 'key' => '_customer_user', + 'value' => $request['customer'], + 'type' => 'NUMERIC', + ); + } + + // Search by product. + if ( ! empty( $request['product'] ) ) { + $order_ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item'", + $request['product'] + ) + ); + + // Force WP_Query return empty if don't found any order. + $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); + + $args['post__in'] = $order_ids; + } + + // Search. + if ( ! empty( $args['s'] ) ) { + $order_ids = wc_order_search( $args['s'] ); + + if ( ! empty( $order_ids ) ) { + unset( $args['s'] ); + $args['post__in'] = array_merge( $order_ids, array( 0 ) ); + } + } + // Search by partial order number. if ( ! empty( $request['number'] ) ) { $partial_number = trim( $request['number'] ); @@ -421,7 +462,7 @@ class Orders extends AbstractObjectsController { * * @throws WC_REST_Exception When fails to set any item. * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. + * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { @@ -490,12 +531,11 @@ class Orders extends AbstractObjectsController { /** * Save an object data. - * - * @since 3.0.0 - * @throws WC_REST_Exception But all errors are validated before returning any data. + * * * @param \WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. + * @param bool $creating If is creating a new object. * @return WC_Data|\WP_Error + * @throws \WC_REST_Exception But all errors are validated before returning any data. */ protected function save_object( $request, $creating = false ) { try { @@ -574,9 +614,9 @@ class Orders extends AbstractObjectsController { /** * Gets the product ID from the SKU or posted ID. * - * @throws WC_REST_Exception When SKU or ID is not valid. * @param array $posted Request data. * @return int + * @throws \WC_REST_Exception When SKU or ID is not valid. */ protected function get_product_id( $posted ) { if ( ! empty( $posted['sku'] ) ) { @@ -1711,7 +1751,7 @@ class Orders extends AbstractObjectsController { * * @throws WC_REST_Exception When fails to set any item. * @param \WP_REST_Request $request Request object. - * @param WC_Order $order Order data. + * @param WC_Order $order Order data. * @return bool */ protected function calculate_coupons( $request, $order ) { diff --git a/tests/AbstractRestApiTest.php b/tests/AbstractRestApiTest.php index 34098e028a6..3809d31461e 100644 --- a/tests/AbstractRestApiTest.php +++ b/tests/AbstractRestApiTest.php @@ -2,6 +2,18 @@ /** * REST API Endpoint Test base class. * + * This class can be extended to add test coverage to REST API endpoints. + * + * For each endpoint, please test: + * - Create + * - Read + * - Update + * - Delete + * - How the API responds to logged out/unauthorised users + * - Schema + * - Routes + * - Collection params/queries + * * @package WooCommerce/RestApi/Tests */ @@ -21,7 +33,7 @@ abstract class AbstractRestApiTest extends WC_REST_Unit_Test_Case { /** * The endpoint schema. * - * @var array + * @var array Keys are property names, values are supported context. */ protected $properties = []; @@ -43,6 +55,8 @@ abstract class AbstractRestApiTest extends WC_REST_Unit_Test_Case { 'role' => 'administrator', ) ); + + wp_set_current_user( $this->user ); } /** @@ -63,32 +77,71 @@ abstract class AbstractRestApiTest extends WC_REST_Unit_Test_Case { * @return void */ public function test_schema_properties() { - $this->user_request(); - $request = new \WP_REST_Request( 'OPTIONS', $this->routes[0] ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( count( $this->properties ), count( $properties ) ); + $this->assertEquals( count( array_keys( $this->properties ) ), count( $properties ), print_r( array_diff( array_keys( $properties ), array_keys( $this->properties ) ), true ) ); - foreach ( $this->properties as $property ) { + foreach ( array_keys( $this->properties ) as $property ) { $this->assertArrayHasKey( $property, $properties ); } } /** - * Set current user to an authenticated user. + * Classes should test creation using this method. + * If read-only, test to confirm this. */ - protected function user_request() { - wp_set_current_user( $this->user ); + abstract public function test_create(); + + /** + * Classes should test get/read using this method. + */ + abstract public function test_read(); + + /** + * Classes should test updates using this method. + * If read-only, test to confirm this. + */ + abstract public function test_update(); + + /** + * Classes should test delete using this method. + * If read-only, test to confirm this. + */ + abstract public function test_delete(); + + /** + * Tests delete when there is no user logged in. + */ + public function test_guest_create() { + wp_set_current_user( 0 ); + $this->assertEquals( 0, get_current_user_id() ); } /** - * Set current user to an unauthenticated user. + * Tests delete when there is no user logged in. */ - protected function guest_request() { + public function test_guest_read() { wp_set_current_user( 0 ); + $this->assertEquals( 0, get_current_user_id() ); + } + + /** + * Tests delete when there is no user logged in. + */ + public function test_guest_update() { + wp_set_current_user( 0 ); + $this->assertEquals( 0, get_current_user_id() ); + } + + /** + * Tests delete when there is no user logged in. + */ + public function test_guest_delete() { + wp_set_current_user( 0 ); + $this->assertEquals( 0, get_current_user_id() ); } /** @@ -96,21 +149,81 @@ abstract class AbstractRestApiTest extends WC_REST_Unit_Test_Case { * * @param string $endpoint Endpoint to hit. * @param string $type Type of request e.g GET or POST. - * @param array $params Request body. - * @param boolean $authenticated Do request as user or guest. + * @param array $params Request body or query. * @return object */ - protected function do_request( $endpoint, $type = 'GET', $params = array(), $authenticated = true ) { - $authenticated ? $this->user_request() : $this->guest_request(); - + protected function do_request( $endpoint, $type = 'GET', $params = [] ) { $request = new \WP_REST_Request( $type, $endpoint ); - $request->set_body_params( $params ); + 'GET' === $type ? $request->set_query_params( $params ) : $request->set_body_params( $params ); $response = $this->server->dispatch( $request ); - $data = $response->get_data(); return (object) array( 'status' => $response->get_status(), - 'data' => $response->get_data(), + 'data' => json_decode( wp_json_encode( $response->get_data() ), true ), + 'raw' => $response->get_data(), ); } + + /** + * Test the request/response matched the data we sent. + * + * @param array $response Array of response data from do_request above. + * @param int $status_code Expected status code. + * @param array $data Array of expected data. + */ + protected function assertExpectedResponse( $response, $status_code = 200, $data = array() ) { + $this->assertObjectHasAttribute( 'status', $response ); + $this->assertObjectHasAttribute( 'data', $response ); + $this->assertEquals( $status_code, $response->status, print_r( $response->data, true ) ); + + if ( $data ) { + foreach ( $data as $key => $value ) { + if ( ! isset( $response->data[ $key ] ) ) { + continue; + } + switch ( $key ) { + case 'meta_data': + $this->assertMetaData( $value, $response->data[ $key ] ); + break; + default: + if ( is_array( $value ) ) { + $this->assertArraySubset( $value, $response->data[ $key ] ); + } else { + $this->assertEquals( $value, $response->data[ $key ] ); + } + } + } + } + } + + /** + * Test meta data in a response matches what we expect. + * + * @param array $expected_meta_data Array of data. + * @param array $actual_meta_data Array of data. + */ + protected function assertMetaData( $expected_meta_data, $actual_meta_data ) { + $this->assertTrue( is_array( $actual_meta_data ) ); + $this->assertEquals( count( $expected_meta_data ), count( $actual_meta_data ) ); + + foreach ( $actual_meta_data as $key => $meta ) { + $this->assertArrayHasKey( 'id', $meta ); + $this->assertArrayHasKey( 'key', $meta ); + $this->assertArrayHasKey( 'value', $meta ); + $this->assertEquals( $expected_meta_data[ $key ]['key'], $meta['key'] ); + $this->assertEquals( $expected_meta_data[ $key ]['value'], $meta['value'] ); + } + } + + /** + * Return array of properties for a given context. + * + * @param string $context Context to use. + * @return array + */ + protected function get_properties( $context = 'edit' ) { + return array_keys( array_filter( $this->properties, function( $contexts ) use( $context ) { + return in_array( $context, $contexts ); + } ) ); + } } diff --git a/tests/Blocks/products-attributes-terms.php b/tests/Blocks/products-attributes-terms.php new file mode 100644 index 00000000000..8a85261c08a --- /dev/null +++ b/tests/Blocks/products-attributes-terms.php @@ -0,0 +1,105 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + + $this->contributor = $this->factory->user->create( + array( + 'role' => 'contributor', + ) + ); + + // Create 2 product attributes with terms. + $this->attr_color = WC_Helper_Product::create_attribute( 'color', array( 'red', 'yellow', 'blue' ) ); + $this->attr_size = WC_Helper_Product::create_attribute( 'size', array( 'small', 'medium', 'large', 'xlarge' ) ); + } + + /** + * Test getting attribute terms. + * + * @since 3.6.0 + */ + public function test_get_terms() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_color['attribute_id'] . '/terms' ); + + $response = $this->server->dispatch( $request ); + $response_terms = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 3, count( $response_terms ) ); + $term = $response_terms[0]; + $this->assertArrayHasKey( 'attribute', $term ); + $attribute = $term['attribute']; + $this->assertArrayHasKey( 'id', $attribute ); + $this->assertArrayHasKey( 'name', $attribute ); + $this->assertArrayHasKey( 'slug', $attribute ); + } + + /** + * Test getting invalid attribute terms. + * + * @since 3.6.0 + */ + public function test_get_invalid_attribute_terms() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/99999/terms' ); + + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test un-authorized getting attribute terms. + * + * @since 3.6.0 + */ + public function test_get_unauthed_attribute_terms() { + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_size['attribute_id'] . '/terms' ); + + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting attribute terms as contributor. + * + * @since 3.6.0 + */ + public function test_get_attribute_terms_contributor() { + wp_set_current_user( $this->contributor ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_size['attribute_id'] . '/terms' ); + + $response = $this->server->dispatch( $request ); + $response_terms = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 4, count( $response_terms ) ); + } +} diff --git a/tests/Blocks/products-attributes.php b/tests/Blocks/products-attributes.php new file mode 100644 index 00000000000..8a03a7b02e7 --- /dev/null +++ b/tests/Blocks/products-attributes.php @@ -0,0 +1,105 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + + $this->contributor = $this->factory->user->create( + array( + 'role' => 'contributor', + ) + ); + + // Create 2 product attributes with terms. + $this->attr_color = WC_Helper_Product::create_attribute( 'color', array( 'red', 'yellow', 'blue' ) ); + $this->attr_size = WC_Helper_Product::create_attribute( 'size', array( 'small', 'medium', 'large', 'xlarge' ) ); + } + + /** + * Test getting attributes. + * + * @since 3.6.0 + */ + public function test_get_attributes() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes' ); + + $response = $this->server->dispatch( $request ); + $response_attributes = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $response_attributes ) ); + $attribute = $response_attributes[0]; + $this->assertArrayHasKey( 'id', $attribute ); + $this->assertArrayHasKey( 'name', $attribute ); + $this->assertArrayHasKey( 'slug', $attribute ); + $this->assertArrayHasKey( 'count', $attribute ); + } + + /** + * Test getting invalid attribute. + * + * @since 3.6.0 + */ + public function test_get_invalid_attribute() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/11111' ); + + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test un-authorized getting attribute. + * + * @since 3.6.0 + */ + public function test_get_unauthed_attribute() { + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_size['attribute_id'] ); + + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting attribute as contributor. + * + * @since 3.6.0 + */ + public function test_get_attribute_contributor() { + wp_set_current_user( $this->contributor ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_size['attribute_id'] ); + + $response = $this->server->dispatch( $request ); + $attribute = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $this->attr_size['attribute_id'], $attribute['id'] ); + $this->assertEquals( $this->attr_size['attribute_name'], $attribute['name'] ); + } +} diff --git a/tests/Blocks/products-categories.php b/tests/Blocks/products-categories.php new file mode 100644 index 00000000000..455f6857bcd --- /dev/null +++ b/tests/Blocks/products-categories.php @@ -0,0 +1,121 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + + $this->contributor = $this->factory->user->create( + array( + 'role' => 'contributor', + ) + ); + + // Create 3 product categories. + $parent = wp_insert_term( 'Parent Category', 'product_cat' ); + $child = wp_insert_term( + 'Child Category', + 'product_cat', + array( 'parent' => $parent['term_id'] ) + ); + $single = wp_insert_term( 'Standalone Category', 'product_cat' ); + $this->categories = array( + 'parent' => $parent, + 'child' => $child, + 'single' => $single, + ); + + // Create two products for the parent category. + $this->products = array(); + $this->products[0] = WC_Helper_Product::create_simple_product( false ); + $this->products[0]->set_category_ids( array( $parent['term_id'] ) ); + $this->products[0]->save(); + + $this->products[3] = WC_Helper_Product::create_simple_product( false ); + $this->products[3]->set_category_ids( array( $parent['term_id'], $single['term_id'] ) ); + $this->products[3]->save(); + } + + /** + * Test getting product categories. + * + * @since 3.6.0 + */ + public function test_get_product_categories() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/categories' ); + + $response = $this->server->dispatch( $request ); + $categories = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 4, count( $categories ) ); // Three created and `uncategorized`. + } + + /** + * Test getting invalid product category. + * + * @since 3.6.0 + */ + public function test_get_invalid_product_category() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/categories/007' ); + + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test un-authorized getting product category. + * + * @since 3.6.0 + */ + public function test_get_unauthed_product_category() { + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/categories/' . $this->categories['parent']['term_id'] ); + + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting category as contributor. + * + * @since 3.6.0 + */ + public function test_get_attribute_terms_contributor() { + wp_set_current_user( $this->contributor ); + $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/categories/' . $this->categories['parent']['term_id'] ); + + $response = $this->server->dispatch( $request ); + $category = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $category['name'], 'Parent Category' ); + $this->assertEquals( $category['parent'], 0 ); + $this->assertEquals( $category['count'], 2 ); + } +} diff --git a/tests/Blocks/products.php b/tests/Blocks/products.php new file mode 100644 index 00000000000..1ce12330e1f --- /dev/null +++ b/tests/Blocks/products.php @@ -0,0 +1,305 @@ +user = $this->factory->user->create( + array( + 'role' => 'author', + ) + ); + $this->contributor = $this->factory->user->create( + array( + 'role' => 'contributor', + ) + ); + $this->subscriber = $this->factory->user->create( + array( + 'role' => 'subscriber', + ) + ); + + // Create 3 product categories. + $parent = wp_insert_term( 'Parent Category', 'product_cat' ); + $child = wp_insert_term( + 'Child Category', + 'product_cat', + array( 'parent' => $parent['term_id'] ) + ); + $single = wp_insert_term( 'Standalone Category', 'product_cat' ); + $this->categories = array( + 'parent' => $parent, + 'child' => $child, + 'single' => $single, + ); + + // Create two products, one with 'parent', and one with 'single'. + $this->products = array(); + $this->products[0] = WC_Helper_Product::create_simple_product( false ); + $this->products[0]->set_category_ids( array( $parent['term_id'] ) ); + $this->products[0]->save(); + + $this->products[1] = WC_Helper_Product::create_simple_product( false ); + $this->products[1]->set_category_ids( array( $single['term_id'] ) ); + $this->products[1]->save(); + + $this->products[2] = WC_Helper_Product::create_simple_product( false ); + $this->products[2]->set_category_ids( array( $child['term_id'], $single['term_id'] ) ); + $this->products[2]->save(); + + $this->products[3] = WC_Helper_Product::create_simple_product( false ); + $this->products[3]->set_category_ids( array( $parent['term_id'], $single['term_id'] ) ); + $this->products[3]->save(); + } + + /** + * Test route registration. + * + * @since 3.6.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( '/wc-blocks/v1/products', $routes ); + $this->assertArrayHasKey( '/wc-blocks/v1/products/(?P[\d]+)', $routes ); + } + + /** + * Test getting products. + * + * @since 3.6.0 + */ + public function test_get_products() { + wp_set_current_user( $this->user ); + WC_Helper_Product::create_external_product(); + sleep( 1 ); // So both products have different timestamps. + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 6, count( $products ) ); + } + + /** + * Test getting products as an contributor. + * + * @since 3.6.0 + */ + public function test_get_products_as_contributor() { + wp_set_current_user( $this->contributor ); + WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test getting products as an subscriber. + * + * @since 3.6.0 + */ + public function test_get_products_as_subscriber() { + wp_set_current_user( $this->subscriber ); + WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); + $this->assertEquals( 403, $response->get_status() ); + } + + /** + * Test getting products with custom ordering. + * + * @since 3.6.0 + */ + public function test_get_products_order_by_price() { + wp_set_current_user( $this->user ); + WC_Helper_Product::create_external_product(); + sleep( 1 ); // So both products have different timestamps. + $product = WC_Helper_Product::create_simple_product( false ); // Prevent saving, since we save here. + // Customize the price, otherwise both are 10. + $product->set_props( + array( + 'regular_price' => 15, + 'price' => 15, + ) + ); + $product->save(); + + $request = new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ); + $request->set_param( 'orderby', 'price' ); + $request->set_param( 'order', 'asc' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 6, count( $products ) ); + + $this->assertEquals( 'Dummy Product', $products[1]['name'] ); + $this->assertEquals( '10', $products[1]['price'] ); + } + + /** + * Test product_visibility queries. + * + * @since 3.6.0 + */ + public function test_product_visibility() { + wp_set_current_user( $this->user ); + $visible_product = WC_Helper_Product::create_simple_product(); + $visible_product->set_name( 'Visible Product' ); + $visible_product->set_catalog_visibility( 'visible' ); + $visible_product->save(); + + $catalog_product = WC_Helper_Product::create_simple_product(); + $catalog_product->set_name( 'Catalog Product' ); + $catalog_product->set_catalog_visibility( 'catalog' ); + $catalog_product->save(); + + $search_product = WC_Helper_Product::create_simple_product(); + $search_product->set_name( 'Search Product' ); + $search_product->set_catalog_visibility( 'search' ); + $search_product->save(); + + $hidden_product = WC_Helper_Product::create_simple_product(); + $hidden_product->set_name( 'Hidden Product' ); + $hidden_product->set_catalog_visibility( 'hidden' ); + $hidden_product->save(); + + $query_params = array( + 'catalog_visibility' => 'visible', + ); + $request = new WP_REST_REQUEST( 'GET', '/wc-blocks/v1/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 5, count( $products ) ); + $this->assertEquals( 'Visible Product', $products[0]['name'] ); + + $query_params = array( + 'catalog_visibility' => 'catalog', + 'orderby' => 'id', + 'order' => 'asc', + ); + $request = new WP_REST_REQUEST( 'GET', '/wc-blocks/v1/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 6, count( $products ) ); + $this->assertEquals( 'Dummy Product', $products[0]['name'] ); + + $query_params = array( + 'catalog_visibility' => 'search', + 'orderby' => 'id', + 'order' => 'asc', + ); + $request = new WP_REST_REQUEST( 'GET', '/wc-blocks/v1/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 6, count( $products ) ); + $this->assertEquals( 'Dummy Product', $products[0]['name'] ); + + $query_params = array( + 'catalog_visibility' => 'hidden', + ); + $request = new WP_REST_REQUEST( 'GET', '/wc-blocks/v1/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $products ) ); + $this->assertEquals( 'Hidden Product', $products[0]['name'] ); + } + + /** + * Test product category intersection: Any product in either Single or Child (3). + * + * @since 3.6.0 + */ + public function test_get_products_in_any_categories_child() { + wp_set_current_user( $this->user ); + + $cats = $this->categories['child']['term_id'] . ',' . $this->categories['single']['term_id']; + + $request = new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ); + $request->set_param( 'category', $cats ); + $request->set_param( 'category_operator', 'in' ); + + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 3, count( $response_products ) ); + } + + /** + * Test product category intersection: Any product in both Single and Child (1). + * + * @since 3.6.0 + */ + public function test_get_products_in_all_categories_child() { + wp_set_current_user( $this->user ); + + $cats = $this->categories['child']['term_id'] . ',' . $this->categories['single']['term_id']; + + $request = new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ); + $request->set_param( 'category', $cats ); + $request->set_param( 'category_operator', 'and' ); + + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $response_products ) ); + } + + /** + * Test product category intersection: Any product in both Single and Parent (1). + * + * @since 3.6.0 + */ + public function test_get_products_in_all_categories_parent() { + wp_set_current_user( $this->user ); + + $cats = $this->categories['parent']['term_id'] . ',' . $this->categories['single']['term_id']; + + $request = new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ); + $request->set_param( 'category', $cats ); + $request->set_param( 'category_operator', 'and' ); + + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $response_products ) ); + } +} diff --git a/tests/Version2/coupons.php b/tests/Version2/coupons.php new file mode 100644 index 00000000000..592357327f7 --- /dev/null +++ b/tests/Version2/coupons.php @@ -0,0 +1,471 @@ +endpoint = new WC_REST_Coupons_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/coupons', $routes ); + $this->assertArrayHasKey( '/wc/v2/coupons/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v2/coupons/batch', $routes ); + } + + /** + * Test getting coupons. + * @since 3.0.0 + */ + public function test_get_coupons() { + wp_set_current_user( $this->user ); + + $coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $post_1 = get_post( $coupon_1->get_id() ); + $coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons' ) ); + $coupons = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $coupons ) ); + $this->assertContains( + array( + 'id' => $coupon_1->get_id(), + 'code' => 'dummycoupon-1', + 'amount' => '1.00', + 'date_created' => wc_rest_prepare_date_response( $post_1->post_date_gmt, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $post_1->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $post_1->post_modified_gmt, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $post_1->post_modified_gmt ), + 'discount_type' => 'fixed_cart', + 'description' => 'This is a dummy coupon', + 'date_expires' => '', + 'date_expires_gmt' => '', + 'usage_count' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'excluded_product_ids' => array(), + 'usage_limit' => '', + 'usage_limit_per_user' => '', + 'limit_usage_to_x_items' => null, + 'free_shipping' => false, + 'product_categories' => array(), + 'excluded_product_categories' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '0.00', + 'maximum_amount' => '0.00', + 'email_restrictions' => array(), + 'used_by' => array(), + 'meta_data' => array(), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/coupons/' . $coupon_1->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/coupons' ), + ), + ), + ), + ), + $coupons + ); + } + + /** + * Test getting coupons without valid permissions. + * @since 3.0.0 + */ + public function test_get_coupons_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single coupon. + * @since 3.0.0 + */ + public function test_get_coupon() { + wp_set_current_user( $this->user ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $post = get_post( $coupon->get_id() ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $coupon->get_id(), + 'code' => 'dummycoupon-1', + 'amount' => '1.00', + 'date_created' => wc_rest_prepare_date_response( $post->post_date_gmt, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $post->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $post->post_modified_gmt, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $post->post_modified_gmt ), + 'discount_type' => 'fixed_cart', + 'description' => 'This is a dummy coupon', + 'date_expires' => null, + 'date_expires_gmt' => null, + 'usage_count' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'excluded_product_ids' => array(), + 'usage_limit' => null, + 'usage_limit_per_user' => null, + 'limit_usage_to_x_items' => null, + 'free_shipping' => false, + 'product_categories' => array(), + 'excluded_product_categories' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '0.00', + 'maximum_amount' => '0.00', + 'email_restrictions' => array(), + 'used_by' => array(), + 'meta_data' => array(), + ), + $data + ); + } + + /** + * Test getting a single coupon with an invalid ID. + * @since 3.0.0 + */ + public function test_get_coupon_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single coupon without valid permissions. + * @since 3.0.0 + */ + public function test_get_coupon_without_permission() { + wp_set_current_user( 0 ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test creating a single coupon. + * @since 3.0.0 + */ + public function test_create_coupon() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'POST', '/wc/v2/coupons' ); + $request->set_body_params( + array( + 'code' => 'test', + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + 'description' => 'Test', + 'usage_limit' => 10, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'code' => 'test', + 'amount' => '5.00', + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_type' => 'fixed_product', + 'description' => 'Test', + 'date_expires' => null, + 'date_expires_gmt' => null, + 'usage_count' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'excluded_product_ids' => array(), + 'usage_limit' => 10, + 'usage_limit_per_user' => null, + 'limit_usage_to_x_items' => null, + 'free_shipping' => false, + 'product_categories' => array(), + 'excluded_product_categories' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '0.00', + 'maximum_amount' => '0.00', + 'email_restrictions' => array(), + 'used_by' => array(), + 'meta_data' => array(), + ), + $data + ); + } + + /** + * Test creating a single coupon with invalid fields. + * @since 3.0.0 + */ + public function test_create_coupon_invalid_fields() { + wp_set_current_user( $this->user ); + + // test no code... + $request = new WP_REST_Request( 'POST', '/wc/v2/coupons' ); + $request->set_body_params( + array( + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating a single coupon without valid permissions. + * @since 3.0.0 + */ + public function test_create_coupon_without_permission() { + wp_set_current_user( 0 ); + + // test no code... + $request = new WP_REST_Request( 'POST', '/wc/v2/coupons' ); + $request->set_body_params( + array( + 'code' => 'fail', + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single coupon. + * @since 3.0.0 + */ + public function test_update_coupon() { + wp_set_current_user( $this->user ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $post = get_post( $coupon->get_id() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); + $data = $response->get_data(); + $this->assertEquals( 'This is a dummy coupon', $data['description'] ); + $this->assertEquals( 'fixed_cart', $data['discount_type'] ); + $this->assertEquals( '1.00', $data['amount'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/coupons/' . $coupon->get_id() ); + $request->set_body_params( + array( + 'amount' => '10.00', + 'description' => 'New description', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '10.00', $data['amount'] ); + $this->assertEquals( 'New description', $data['description'] ); + $this->assertEquals( 'fixed_cart', $data['discount_type'] ); + } + + /** + * Test updating a single coupon with an invalid ID. + * @since 3.0.0 + */ + public function test_update_coupon_invalid_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/coupons/0' ); + $request->set_body_params( + array( + 'code' => 'tester', + 'amount' => '10.00', + 'description' => 'New description', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test updating a single coupon without valid permissions. + * @since 3.0.0 + */ + public function test_update_coupon_without_permission() { + wp_set_current_user( 0 ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $post = get_post( $coupon->get_id() ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/coupons/' . $coupon->get_id() ); + $request->set_body_params( + array( + 'amount' => '10.00', + 'description' => 'New description', + ) + ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single coupon. + * @since 3.0.0 + */ + public function test_delete_coupon() { + wp_set_current_user( $this->user ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/' . $coupon->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test deleting a single coupon with an invalid ID. + * @since 3.0.0 + */ + public function test_delete_coupon_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test deleting a single coupon without valid permissions. + * @since 3.0.0 + */ + public function test_delete_coupon_without_permission() { + wp_set_current_user( 0 ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/' . $coupon->get_id() ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch operations on coupons. + * @since 3.0.0 + */ + public function test_batch_coupon() { + wp_set_current_user( $this->user ); + + $coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' ); + $coupon_3 = WC_Helper_Coupon::create_coupon( 'dummycoupon-3' ); + $coupon_4 = WC_Helper_Coupon::create_coupon( 'dummycoupon-4' ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/coupons/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $coupon_1->get_id(), + 'amount' => '5.15', + ), + ), + 'delete' => array( + $coupon_2->get_id(), + $coupon_3->get_id(), + ), + 'create' => array( + array( + 'code' => 'new-coupon', + 'amount' => '11.00', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '5.15', $data['update'][0]['amount'] ); + $this->assertEquals( '11.00', $data['create'][0]['amount'] ); + $this->assertEquals( 'new-coupon', $data['create'][0]['code'] ); + $this->assertEquals( $coupon_2->get_id(), $data['delete'][0]['id'] ); + $this->assertEquals( $coupon_3->get_id(), $data['delete'][1]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v2/coupons' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Test coupon schema. + * @since 3.0.0 + */ + public function test_coupon_schema() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/coupons' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 27, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'code', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_created_gmt', $properties ); + $this->assertArrayHasKey( 'date_modified', $properties ); + $this->assertArrayHasKey( 'date_modified_gmt', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'discount_type', $properties ); + $this->assertArrayHasKey( 'amount', $properties ); + $this->assertArrayHasKey( 'date_expires', $properties ); + $this->assertArrayHasKey( 'date_expires_gmt', $properties ); + $this->assertArrayHasKey( 'usage_count', $properties ); + $this->assertArrayHasKey( 'individual_use', $properties ); + $this->assertArrayHasKey( 'product_ids', $properties ); + $this->assertArrayHasKey( 'excluded_product_ids', $properties ); + $this->assertArrayHasKey( 'usage_limit', $properties ); + $this->assertArrayHasKey( 'usage_limit_per_user', $properties ); + $this->assertArrayHasKey( 'limit_usage_to_x_items', $properties ); + $this->assertArrayHasKey( 'free_shipping', $properties ); + $this->assertArrayHasKey( 'product_categories', $properties ); + $this->assertArrayHasKey( 'excluded_product_categories', $properties ); + $this->assertArrayHasKey( 'exclude_sale_items', $properties ); + $this->assertArrayHasKey( 'minimum_amount', $properties ); + $this->assertArrayHasKey( 'maximum_amount', $properties ); + $this->assertArrayHasKey( 'email_restrictions', $properties ); + $this->assertArrayHasKey( 'used_by', $properties ); + } +} diff --git a/tests/Version2/customers.php b/tests/Version2/customers.php new file mode 100644 index 00000000000..d6519cd246c --- /dev/null +++ b/tests/Version2/customers.php @@ -0,0 +1,566 @@ +endpoint = new WC_REST_Customers_Controller(); + } + + /** + * Test route registration. + * + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( '/wc/v2/customers', $routes ); + $this->assertArrayHasKey( '/wc/v2/customers/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v2/customers/batch', $routes ); + } + + /** + * Test getting customers. + * + * @since 3.0.0 + */ + public function test_get_customers() { + wp_set_current_user( 1 ); + + $customer_1 = WC_Helper_Customer::create_customer(); + WC_Helper_Customer::create_customer( 'test2', 'test2', 'test2@woo.local' ); + + $request = new WP_REST_Request( 'GET', '/wc/v2/customers' ); + $request->set_query_params( + array( + 'orderby' => 'id', + ) + ); + $response = $this->server->dispatch( $request ); + $customers = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $customers ) ); + + $this->assertContains( + array( + 'id' => $customer_1->get_id(), + 'date_created' => wc_rest_prepare_date_response( $customer_1->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $customer_1->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $customer_1->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_1->get_date_modified() ), + 'email' => 'test@woo.local', + 'first_name' => 'Justin', + 'last_name' => '', + 'role' => 'customer', + 'username' => 'testcustomer', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'orders_count' => 0, + 'total_spent' => '0.00', + 'avatar_url' => $customer_1->get_avatar_url(), + 'meta_data' => array(), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/customers/' . $customer_1->get_id() . '' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/customers' ), + ), + ), + ), + ), + $customers + ); + } + + /** + * Test getting customers without valid permissions. + * + * @since 3.0.0 + */ + public function test_get_customers_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test creating a new customer. + * + * @since 3.0.0 + */ + public function test_create_customer() { + wp_set_current_user( 1 ); + + // Test just the basics first.. + $request = new WP_REST_Request( 'POST', '/wc/v2/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test', + 'password' => 'test123', + 'email' => 'create_customer_test@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'create_customer_test@woo.local', + 'first_name' => '', + 'last_name' => '', + 'role' => 'customer', + 'username' => 'create_customer_test', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'orders_count' => 0, + 'total_spent' => '0.00', + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + + // Test extra data + $request = new WP_REST_Request( 'POST', '/wc/v2/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test2', + 'password' => 'test123', + 'email' => 'create_customer_test2@woo.local', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + 'billing' => array( + 'country' => 'US', + 'state' => 'WA', + ), + 'shipping' => array( + 'state' => 'CA', + 'country' => 'US', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'create_customer_test2@woo.local', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + 'role' => 'customer', + 'username' => 'create_customer_test2', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => 'WA', + 'postcode' => '', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => 'CA', + 'postcode' => '', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'orders_count' => 0, + 'total_spent' => '0.00', + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + + // Test without required field + $request = new WP_REST_Request( 'POST', '/wc/v2/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test3', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating customers without valid permissions. + * + * @since 3.0.0 + */ + public function test_create_customer_without_permission() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'POST', '/wc/v2/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test_without_permission', + 'password' => 'test123', + 'email' => 'create_customer_test_without_permission@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single customer. + * + * @since 3.0.0 + */ + public function test_get_customer() { + wp_set_current_user( 1 ); + $customer = WC_Helper_Customer::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'get_customer_test@woo.local', + 'first_name' => 'Justin', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'last_name' => '', + 'role' => 'customer', + 'username' => 'get_customer_test', + 'orders_count' => 0, + 'total_spent' => '0.00', + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + } + + /** + * Test getting a single customer without valid permissions. + * + * @since 3.0.0 + */ + public function test_get_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = WC_Helper_Customer::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single customer with an invalid ID. + * + * @since 3.0.0 + */ + public function test_get_customer_invalid_id() { + wp_set_current_user( 1 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a customer. + * + * @since 3.0.0 + */ + public function test_update_customer() { + wp_set_current_user( 1 ); + $customer = WC_Helper_Customer::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); + $data = $response->get_data(); + $this->assertEquals( 'update_customer_test', $data['username'] ); + $this->assertEquals( 'update_customer_test@woo.local', $data['email'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/customers/' . $customer->get_id() ); + $request->set_body_params( + array( + 'email' => 'updated_email@woo.local', + 'first_name' => 'UpdatedTest', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'updated_email@woo.local', $data['email'] ); + $this->assertEquals( 'UpdatedTest', $data['first_name'] ); + } + + /** + * Test updating a customer without valid permissions. + * + * @since 3.0.0 + */ + public function test_update_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = WC_Helper_Customer::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a customer with an invalid ID. + * + * @since 3.0.0 + */ + public function test_update_customer_invalid_id() { + wp_set_current_user( 1 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + + /** + * Test deleting a customer. + * + * @since 3.0.0 + */ + public function test_delete_customer() { + wp_set_current_user( 1 ); + $customer = WC_Helper_Customer::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/' . $customer->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test deleting a customer with an invalid ID. + * + * @since 3.0.0 + */ + public function test_delete_customer_invalid_id() { + wp_set_current_user( 1 ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test deleting a customer without valid permissions. + * + * @since 3.0.0 + */ + public function test_delete_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = WC_Helper_Customer::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/' . $customer->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test customer batch endpoint. + * + * @since 3.0.0 + */ + public function test_batch_customer() { + wp_set_current_user( 1 ); + + $customer_1 = WC_Helper_Customer::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); + $customer_2 = WC_Helper_Customer::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); + $customer_3 = WC_Helper_Customer::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); + $customer_4 = WC_Helper_Customer::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/customers/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $customer_1->get_id(), + 'last_name' => 'McTest', + ), + ), + 'delete' => array( + $customer_2->get_id(), + $customer_3->get_id(), + ), + 'create' => array( + array( + 'username' => 'newuser', + 'password' => 'test123', + 'email' => 'newuser@woo.local', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'McTest', $data['update'][0]['last_name'] ); + $this->assertEquals( 'newuser', $data['create'][0]['username'] ); + $this->assertEmpty( $data['create'][0]['last_name'] ); + $this->assertEquals( $customer_2->get_id(), $data['delete'][0]['id'] ); + $this->assertEquals( $customer_3->get_id(), $data['delete'][1]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v2/customers' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Test customer schema. + * + * @since 3.0.0 + */ + public function test_customer_schema() { + wp_set_current_user( 1 ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/customers' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 18, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_created_gmt', $properties ); + $this->assertArrayHasKey( 'date_modified', $properties ); + $this->assertArrayHasKey( 'date_modified_gmt', $properties ); + $this->assertArrayHasKey( 'email', $properties ); + $this->assertArrayHasKey( 'first_name', $properties ); + $this->assertArrayHasKey( 'last_name', $properties ); + $this->assertArrayHasKey( 'role', $properties ); + $this->assertArrayHasKey( 'username', $properties ); + $this->assertArrayHasKey( 'password', $properties ); + $this->assertArrayHasKey( 'orders_count', $properties ); + $this->assertArrayHasKey( 'total_spent', $properties ); + $this->assertArrayHasKey( 'avatar_url', $properties ); + $this->assertArrayHasKey( 'billing', $properties ); + $this->assertArrayHasKey( 'first_name', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'last_name', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'company', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'address_1', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'address_2', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'city', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'state', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'postcode', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'country', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'email', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'phone', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'shipping', $properties ); + $this->assertArrayHasKey( 'first_name', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'last_name', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'company', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'address_1', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'address_2', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'city', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'state', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'postcode', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'country', $properties['shipping']['properties'] ); + } +} diff --git a/tests/Version2/orders.php b/tests/Version2/orders.php new file mode 100644 index 00000000000..49df3ce98f7 --- /dev/null +++ b/tests/Version2/orders.php @@ -0,0 +1,635 @@ +endpoint = new WC_REST_Orders_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/orders', $routes ); + $this->assertArrayHasKey( '/wc/v2/orders/batch', $routes ); + $this->assertArrayHasKey( '/wc/v2/orders/(?P[\d]+)', $routes ); + } + + /** + * Test getting all orders. + * @since 3.0.0 + */ + public function test_get_items() { + wp_set_current_user( $this->user ); + + // Create 10 orders. + for ( $i = 0; $i < 10; $i++ ) { + $this->orders[] = WC_Helper_Order::create_order( $this->user ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders' ) ); + $orders = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 10, count( $orders ) ); + } + + /** + * Tests to make sure orders cannot be viewed without valid permissions. + * + * @since 3.0.0 + */ + public function test_get_items_without_permission() { + wp_set_current_user( 0 ); + $this->orders[] = WC_Helper_Order::create_order(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a single order. + * @since 3.0.0 + */ + public function test_get_item() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $order->add_meta_data( 'key', 'value' ); + $order->add_meta_data( 'key2', 'value2' ); + $order->save(); + $this->orders[] = $order; + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $order->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $order->get_id(), $data['id'] ); + + // Test meta data is set. + $this->assertEquals( 'key', $data['meta_data'][0]->key ); + $this->assertEquals( 'value', $data['meta_data'][0]->value ); + $this->assertEquals( 'key2', $data['meta_data'][1]->key ); + $this->assertEquals( 'value2', $data['meta_data'][1]->value ); + } + + /** + * Tests getting a single order without the correct permissions. + * @since 3.0.0 + */ + public function test_get_item_without_permission() { + wp_set_current_user( 0 ); + $order = WC_Helper_Order::create_order(); + $this->orders[] = $order; + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $order->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting an order with an invalid ID. + * @since 3.0.0 + */ + public function test_get_item_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/99999999' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests getting an order with an invalid ID. + * @since 3.5.0 + */ + public function test_get_item_refund_id() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $refund = wc_create_refund( + array( + 'order_id' => $order->get_id(), + ) + ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $refund->get_id() ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests creating an order. + * @since 3.0.0 + */ + public function test_create_order() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); + $request->set_body_params( + array( + 'payment_method' => 'bacs', + 'payment_method_title' => 'Direct Bank Transfer', + 'set_paid' => true, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => '10', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $order = wc_get_order( $data['id'] ); + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); + $this->assertEquals( $order->get_payment_method_title(), $data['payment_method_title'] ); + $this->assertEquals( $order->get_billing_first_name(), $data['billing']['first_name'] ); + $this->assertEquals( $order->get_billing_last_name(), $data['billing']['last_name'] ); + $this->assertEquals( '', $data['billing']['company'] ); + $this->assertEquals( $order->get_billing_address_1(), $data['billing']['address_1'] ); + $this->assertEquals( $order->get_billing_address_2(), $data['billing']['address_2'] ); + $this->assertEquals( $order->get_billing_city(), $data['billing']['city'] ); + $this->assertEquals( $order->get_billing_state(), $data['billing']['state'] ); + $this->assertEquals( $order->get_billing_postcode(), $data['billing']['postcode'] ); + $this->assertEquals( $order->get_billing_country(), $data['billing']['country'] ); + $this->assertEquals( $order->get_billing_email(), $data['billing']['email'] ); + $this->assertEquals( $order->get_billing_phone(), $data['billing']['phone'] ); + $this->assertEquals( $order->get_shipping_first_name(), $data['shipping']['first_name'] ); + $this->assertEquals( $order->get_shipping_last_name(), $data['shipping']['last_name'] ); + $this->assertEquals( '', $data['shipping']['company'] ); + $this->assertEquals( $order->get_shipping_address_1(), $data['shipping']['address_1'] ); + $this->assertEquals( $order->get_shipping_address_2(), $data['shipping']['address_2'] ); + $this->assertEquals( $order->get_shipping_city(), $data['shipping']['city'] ); + $this->assertEquals( $order->get_shipping_state(), $data['shipping']['state'] ); + $this->assertEquals( $order->get_shipping_postcode(), $data['shipping']['postcode'] ); + $this->assertEquals( $order->get_shipping_country(), $data['shipping']['country'] ); + $this->assertEquals( 1, count( $data['line_items'] ) ); + $this->assertEquals( 1, count( $data['shipping_lines'] ) ); + } + + /** + * Test the sanitization of the payment_method_title field through the API. + * + * @since 3.5.2 + */ + public function test_create_update_order_payment_method_title_sanitize() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + // Test when creating order. + $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); + $request->set_body_params( + array( + 'payment_method' => 'bacs', + 'payment_method_title' => '

Sanitize this

', + 'set_paid' => true, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => '10', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $order = wc_get_order( $data['id'] ); + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); + $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this' ); + + // Test when updating order. + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $data['id'] ); + $request->set_body_params( + array( + 'payment_method' => 'bacs', + 'payment_method_title' => '

Sanitize this too

', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $order = wc_get_order( $data['id'] ); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); + $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this too' ); + } + + /** + * Tests creating an order without required fields. + * @since 3.0.0 + */ + public function test_create_order_invalid_fields() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + // non-existent customer + $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); + $request->set_body_params( + array( + 'payment_method' => 'bacs', + 'payment_method_title' => 'Direct Bank Transfer', + 'set_paid' => true, + 'customer_id' => 99999, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => 10, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Tests updating an order. + * + * @since 3.0.0 + */ + public function test_update_order() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); + $request->set_body_params( + array( + 'payment_method' => 'test-update', + 'billing' => array( + 'first_name' => 'Fish', + 'last_name' => 'Face', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'test-update', $data['payment_method'] ); + $this->assertEquals( 'Fish', $data['billing']['first_name'] ); + $this->assertEquals( 'Face', $data['billing']['last_name'] ); + } + + /** + * Tests updating an order and removing items. + * + * @since 3.0.0 + */ + public function test_update_order_remove_items() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $fee = new WC_Order_Item_Fee(); + $fee->set_props( + array( + 'name' => 'Some Fee', + 'tax_status' => 'taxable', + 'total' => '100', + 'tax_class' => '', + ) + ); + $order->add_item( $fee ); + $order->save(); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); + $fee_data = current( $order->get_items( 'fee' ) ); + + $request->set_body_params( + array( + 'fee_lines' => array( + array( + 'id' => $fee_data->get_id(), + 'name' => null, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertTrue( empty( $data['fee_lines'] ) ); + } + + /** + * Tests updating an order and adding a coupon. + * + * @since 3.3.0 + */ + public function test_update_order_add_coupons() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $order_item = current( $order->get_items() ); + $coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon->set_amount( 5 ); + $coupon->save(); + $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); + $request->set_body_params( + array( + 'coupon_lines' => array( + array( + 'code' => 'fake-coupon', + 'discount_total' => '5', + 'discount_tax' => '0', + ), + ), + 'line_items' => array( + array( + 'id' => $order_item->get_id(), + 'product_id' => $order_item->get_product_id(), + 'total' => '35.00', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $data['coupon_lines'] ); + $this->assertEquals( '45.00', $data['total'] ); + } + + /** + * Tests updating an order and removing a coupon. + * + * @since 3.3.0 + */ + public function test_update_order_remove_coupons() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $order_item = current( $order->get_items() ); + $coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon->set_amount( 5 ); + $coupon->save(); + + $order->apply_coupon( $coupon ); + $order->save(); + + // Check that the coupon is applied. + $this->assertEquals( '45.00', $order->get_total() ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); + $coupon_data = current( $order->get_items( 'coupon' ) ); + + $request->set_body_params( + array( + 'coupon_lines' => array( + array( + 'id' => $coupon_data->get_id(), + 'code' => null, + ), + ), + 'line_items' => array( + array( + 'id' => $order_item->get_id(), + 'product_id' => $order_item->get_product_id(), + 'total' => '40.00', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertTrue( empty( $data['coupon_lines'] ) ); + $this->assertEquals( '50.00', $data['total'] ); + } + + /** + * Tests updating an order without the correct permissions. + * + * @since 3.0.0 + */ + public function test_update_order_without_permission() { + wp_set_current_user( 0 ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); + $request->set_body_params( + array( + 'payment_method' => 'test-update', + 'billing' => array( + 'first_name' => 'Fish', + 'last_name' => 'Face', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests that updating an order with an invalid id fails. + * @since 3.0.0 + */ + public function test_update_order_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'POST', '/wc/v2/orders/999999' ); + $request->set_body_params( + array( + 'payment_method' => 'test-update', + 'billing' => array( + 'first_name' => 'Fish', + 'last_name' => 'Face', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test deleting an order. + * @since 3.0.0 + */ + public function test_delete_order() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/' . $order->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( null, get_post( $order->get_id() ) ); + } + + /** + * Test deleting an order without permission/creds. + * @since 3.0.0 + */ + public function test_delete_order_without_permission() { + wp_set_current_user( 0 ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/' . $order->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting an order with an invalid id. + * + * @since 3.0.0 + */ + public function test_delete_order_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/9999999' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test batch managing product reviews. + */ + public function test_orders_batch() { + wp_set_current_user( $this->user ); + + $order1 = WC_Helper_Order::create_order(); + $order2 = WC_Helper_Order::create_order(); + $order3 = WC_Helper_Order::create_order(); + + $request = new WP_REST_Request( 'POST', '/wc/v2/orders/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $order1->get_id(), + 'payment_method' => 'updated', + ), + ), + 'delete' => array( + $order2->get_id(), + $order3->get_id(), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'updated', $data['update'][0]['payment_method'] ); + $this->assertEquals( $order2->get_id(), $data['delete'][0]['id'] ); + $this->assertEquals( $order3->get_id(), $data['delete'][1]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v2/orders' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 1, count( $data ) ); + } + + /** + * Test the order schema. + * @since 3.0.0 + */ + public function test_order_schema() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/orders/' . $order->get_id() ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 42, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + } +} diff --git a/tests/Version2/payment-gateways.php b/tests/Version2/payment-gateways.php new file mode 100644 index 00000000000..d8757c5d31d --- /dev/null +++ b/tests/Version2/payment-gateways.php @@ -0,0 +1,337 @@ +endpoint = new WC_REST_Payment_Gateways_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/payment_gateways', $routes ); + $this->assertArrayHasKey( '/wc/v2/payment_gateways/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all payment gateways. + * + * @since 3.0.0 + */ + public function test_get_payment_gateways() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways' ) ); + $gateways = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( + array( + 'id' => 'cheque', + 'title' => 'Check payments', + 'description' => 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', + 'order' => '', + 'enabled' => false, + 'method_title' => 'Check payments', + 'method_description' => 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', + 'settings' => array_diff_key( + $this->get_settings( 'WC_Gateway_Cheque' ), + array( + 'enabled' => false, + 'description' => false, + ) + ), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/payment_gateways/cheque' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/payment_gateways' ), + ), + ), + ), + ), + $gateways + ); + } + + /** + * Tests to make sure payment gateways cannot viewed without valid permissions. + * + * @since 3.0.0 + */ + public function test_get_payment_gateways_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single payment gateway. + * + * @since 3.0.0 + */ + public function test_get_payment_gateway() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways/paypal' ) ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => 'paypal', + 'title' => 'PayPal', + 'description' => "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account.", + 'order' => '', + 'enabled' => false, + 'method_title' => 'PayPal', + 'method_description' => 'PayPal Standard redirects customers to PayPal to enter their payment information.', + 'settings' => array_diff_key( + $this->get_settings( 'WC_Gateway_Paypal' ), + array( + 'enabled' => false, + 'description' => false, + ) + ), + ), + $paypal + ); + } + + /** + * Test getting a payment gateway without valid permissions. + * + * @since 3.0.0 + */ + public function test_get_payment_gateway_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways/paypal' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a payment gateway with an invalid id. + * + * @since 3.0.0 + */ + public function test_get_payment_gateway_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways/totally_fake_method' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a single payment gateway. + * + * @since 3.0.0 + */ + public function test_update_payment_gateway() { + wp_set_current_user( $this->user ); + + // Test defaults + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways/paypal' ) ); + $paypal = $response->get_data(); + + $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'admin@example.org', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); + + // test updating single setting + $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'email' => 'woo@woo.local', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); + + // test updating multiple settings + $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'testmode' => 'yes', + 'title' => 'PayPal - New Title', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); + + // Test other parameters, and recheck settings + $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertFalse( $paypal['enabled'] ); + $this->assertEquals( 2, $paypal['order'] ); + $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); + + // test bogus + $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'paymentaction' => 'afasfasf', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'paymentaction' => 'authorization', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + $this->assertEquals( 'authorization', $paypal['settings']['paymentaction']['value'] ); + } + + /** + * Test updating a payment gateway without valid permissions. + * + * @since 3.0.0 + */ + public function test_update_payment_gateway_without_permission() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'testmode' => 'yes', + 'title' => 'PayPal - New Title', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a payment gateway with an invalid id. + * + * @since 3.0.0 + */ + public function test_update_payment_gateway_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/totally_fake_method' ); + $request->set_body_params( + array( + 'enabled' => true, + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test the payment gateway schema. + * + * @since 3.0.0 + */ + public function test_payment_gateway_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/payment_gateways' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 8, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'title', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'order', $properties ); + $this->assertArrayHasKey( 'enabled', $properties ); + $this->assertArrayHasKey( 'method_title', $properties ); + $this->assertArrayHasKey( 'method_description', $properties ); + $this->assertArrayHasKey( 'settings', $properties ); + } + + /** + * Loads a particular gateway's settings so we can correctly test API output. + * + * @since 3.0.0 + * @param string $gateway_class Name of WC_Payment_Gateway class. + */ + private function get_settings( $gateway_class ) { + $gateway = new $gateway_class(); + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + // Ignore 'title' settings/fields -- they are UI only + if ( 'title' === $field['type'] ) { + continue; + } + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + +} diff --git a/tests/Version2/product-reviews.php b/tests/Version2/product-reviews.php new file mode 100644 index 00000000000..bf30b5a41f2 --- /dev/null +++ b/tests/Version2/product-reviews.php @@ -0,0 +1,468 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/products/reviews', $routes ); + $this->assertArrayHasKey( '/wc/v3/products/reviews/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/products/reviews/batch', $routes ); + } + + /** + * Test getting all product reviews. + * + * @since 3.0.0 + */ + public function test_get_product_reviews() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + // Create 10 products reviews for the product + for ( $i = 0; $i < 10; $i++ ) { + $review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); + $product_reviews = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 10, count( $product_reviews ) ); + $this->assertContains( + array( + 'id' => $review_id, + 'date_created' => $product_reviews[0]['date_created'], + 'date_created_gmt' => $product_reviews[0]['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => "

Review content here

\n", + 'rating' => 0, + 'verified' => false, + 'reviewer_avatar_urls' => $product_reviews[0]['reviewer_avatar_urls'], + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/products/reviews/' . $review_id ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/products/reviews' ), + ), + ), + 'up' => array( + array( + 'href' => rest_url( '/wc/v3/products/' . $product->get_id() ), + ), + ), + ), + ), + $product_reviews + ); + } + + /** + * Tests to make sure product reviews cannot be viewed without valid permissions. + * + * @since 3.0.0 + */ + public function test_get_product_reviews_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests to make sure an error is returned when an invalid product is loaded. + * + * @since 3.0.0 + */ + public function test_get_product_reviews_invalid_product() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/0/reviews' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests getting a single product review. + * + * @since 3.0.0 + */ + public function test_get_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $product_review_id, + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => "

Review content here

\n", + 'rating' => 0, + 'verified' => false, + 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], + ), + $data + ); + } + + /** + * Tests getting a single product review without the correct permissions. + * + * @since 3.0.0 + */ + public function test_get_product_review_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a product review with an invalid ID. + * + * @since 3.0.0 + */ + public function test_get_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests creating a product review. + * + * @since 3.0.0 + */ + public function test_create_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + 'rating' => '5', + 'product_id' => $product->get_id(), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => 'Hello world.', + 'rating' => 5, + 'verified' => false, + 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], + ), + $data + ); + } + + /** + * Tests creating a product review without required fields. + * + * @since 3.0.0 + */ + public function test_create_product_review_invalid_fields() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + // missing review + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); + $request->set_body_params( + array( + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + + // Missing reviewer. + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer_email' => 'woo@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + + // missing reviewer_email + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Tests updating a product review. + * + * @since 3.0.0 + */ + public function test_update_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); + $data = $response->get_data(); + $this->assertEquals( "

Review content here

\n", $data['review'] ); + $this->assertEquals( 'admin', $data['reviewer'] ); + $this->assertEquals( 'woo@woo.local', $data['reviewer_email'] ); + $this->assertEquals( 0, $data['rating'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); + $request->set_body_params( + array( + 'review' => 'Hello world - updated.', + 'reviewer' => 'Justin', + 'reviewer_email' => 'woo2@woo.local', + 'rating' => 3, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'Hello world - updated.', $data['review'] ); + $this->assertEquals( 'Justin', $data['reviewer'] ); + $this->assertEquals( 'woo2@woo.local', $data['reviewer_email'] ); + $this->assertEquals( 3, $data['rating'] ); + } + + /** + * Tests updating a product review without the correct permissions. + * + * @since 3.0.0 + */ + public function test_update_product_review_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.dev', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests that updating a product review with an invalid id fails. + * + * @since 3.0.0 + */ + public function test_update_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/0' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.dev', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test deleting a product review. + * + * @since 3.0.0 + */ + public function test_delete_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test deleting a product review without permission/creds. + * + * @since 3.0.0 + */ + public function test_delete_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a product review with an invalid id. + * + * @since 3.0.0 + */ + public function test_delete_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test batch managing product reviews. + */ + public function test_product_reviews_batch() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $review_1_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_2_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_3_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_4_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $review_1_id, + 'review' => 'Updated review.', + ), + ), + 'delete' => array( + $review_2_id, + $review_3_id, + ), + 'create' => array( + array( + 'review' => 'New review.', + 'reviewer' => 'Justin', + 'reviewer_email' => 'woo3@woo.local', + 'product_id' => $product->get_id(), + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'Updated review.', $data['update'][0]['review'] ); + $this->assertEquals( 'New review.', $data['create'][0]['review'] ); + $this->assertEquals( $review_2_id, $data['delete'][0]['previous']['id'] ); + $this->assertEquals( $review_3_id, $data['delete'][1]['previous']['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ); + $request->set_param( 'product', $product->get_id() ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Test the product review schema. + * + * @since 3.0.0 + */ + public function test_product_review_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/reviews' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 11, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_created_gmt', $properties ); + $this->assertArrayHasKey( 'product_id', $properties ); + $this->assertArrayHasKey( 'status', $properties ); + $this->assertArrayHasKey( 'reviewer', $properties ); + $this->assertArrayHasKey( 'reviewer_email', $properties ); + $this->assertArrayHasKey( 'review', $properties ); + $this->assertArrayHasKey( 'rating', $properties ); + $this->assertArrayHasKey( 'verified', $properties ); + + if ( get_option( 'show_avatars' ) ) { + $this->assertArrayHasKey( 'reviewer_avatar_urls', $properties ); + } + } +} diff --git a/tests/Version2/product-variations.php b/tests/Version2/product-variations.php new file mode 100644 index 00000000000..7e268a7c657 --- /dev/null +++ b/tests/Version2/product-variations.php @@ -0,0 +1,473 @@ +endpoint = new WC_REST_Product_Variations_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/products/(?P[\d]+)/variations', $routes ); + $this->assertArrayHasKey( '/wc/v2/products/(?P[\d]+)/variations/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v2/products/(?P[\d]+)/variations/batch', $routes ); + } + + /** + * Test getting variations. + * + * @since 3.0.0 + */ + public function test_get_variations() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $variations ) ); + $this->assertEquals( 'DUMMY SKU VARIABLE LARGE', $variations[0]['sku'] ); + $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); + } + + /** + * Test getting variations without permission. + * + * @since 3.0.0 + */ + public function test_get_variations_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single variation. + * + * @since 3.0.0 + */ + public function test_get_variation() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $variation_id, $variation['id'] ); + $this->assertEquals( 'size', $variation['attributes'][0]['name'] ); + } + + /** + * Test getting single variation without permission. + * + * @since 3.0.0 + */ + public function test_get_variation_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single variation. + * + * @since 3.0.0 + */ + public function test_delete_variation() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 1, count( $variations ) ); + } + + /** + * Test deleting a single variation without permission. + * + * @since 3.0.0 + */ + public function test_delete_variation_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single variation with an invalid ID. + * + * @since 3.0.0 + */ + public function test_delete_variation_with_invalid_id() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() . '/variations/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test editing a single variation. + * + * @since 3.0.0 + */ + public function test_update_variation() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $variation = $response->get_data(); + + $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variation['sku'] ); + $this->assertEquals( 10, $variation['regular_price'] ); + $this->assertEmpty( $variation['sale_price'] ); + $this->assertEquals( 'small', $variation['attributes'][0]['option'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU', + 'sale_price' => '8', + 'description' => 'O_O', + 'image' => array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertTrue( isset( $variation['description'] ), print_r( $variation, true ) ); + $this->assertContains( 'O_O', $variation['description'], print_r( $variation, true ) ); + $this->assertEquals( '8', $variation['price'], print_r( $variation, true ) ); + $this->assertEquals( '8', $variation['sale_price'], print_r( $variation, true ) ); + $this->assertEquals( '10', $variation['regular_price'], print_r( $variation, true ) ); + $this->assertEquals( 'FIXED-SKU', $variation['sku'], print_r( $variation, true ) ); + $this->assertEquals( 'medium', $variation['attributes'][0]['option'], print_r( $variation, true ) ); + $this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'], print_r( $variation, true ) ); + $this->assertContains( 'test upload image', $variation['image']['alt'], print_r( $variation, true ) ); + } + + /** + * Test updating a single variation without permission. + * + * @since 3.0.0 + */ + public function test_update_variation_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single variation with an invalid ID. + * + * @since 3.0.0 + */ + public function test_update_variation_with_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/0' ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating a single variation. + * + * @since 3.0.0 + */ + public function test_create_variation() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 2, count( $variations ) ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations' ); + $request->set_body_params( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertContains( 'A medium size.', $variation['description'] ); + $this->assertEquals( '12', $variation['price'] ); + $this->assertEquals( '12', $variation['regular_price'] ); + $this->assertTrue( $variation['purchasable'] ); + $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $variation['sku'] ); + $this->assertEquals( 'medium', $variation['attributes'][0]['option'] ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 3, count( $variations ) ); + } + + /** + * Test creating a single variation without permission. + * + * @since 3.0.0 + */ + public function test_create_variation_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + + $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations' ); + $request->set_body_params( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch managing product variations. + */ + public function test_product_variations_batch() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $children[0], + 'description' => 'Updated description.', + 'image' => array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + ), + ), + 'delete' => array( + $children[1], + ), + 'create' => array( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); + $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $data['create'][0]['sku'] ); + $this->assertEquals( 'medium', $data['create'][0]['attributes'][0]['option'] ); + $this->assertEquals( $children[1], $data['delete'][0]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 2, count( $data ) ); + } + + /** + * Test variation schema. + * + * @since 3.0.0 + */ + public function test_variation_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/products/' . $product->get_id() . '/variations' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 37, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_modified', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'permalink', $properties ); + $this->assertArrayHasKey( 'sku', $properties ); + $this->assertArrayHasKey( 'price', $properties ); + $this->assertArrayHasKey( 'regular_price', $properties ); + $this->assertArrayHasKey( 'sale_price', $properties ); + $this->assertArrayHasKey( 'date_on_sale_from', $properties ); + $this->assertArrayHasKey( 'date_on_sale_to', $properties ); + $this->assertArrayHasKey( 'on_sale', $properties ); + $this->assertArrayHasKey( 'visible', $properties ); + $this->assertArrayHasKey( 'purchasable', $properties ); + $this->assertArrayHasKey( 'virtual', $properties ); + $this->assertArrayHasKey( 'downloadable', $properties ); + $this->assertArrayHasKey( 'downloads', $properties ); + $this->assertArrayHasKey( 'download_limit', $properties ); + $this->assertArrayHasKey( 'download_expiry', $properties ); + $this->assertArrayHasKey( 'tax_status', $properties ); + $this->assertArrayHasKey( 'tax_class', $properties ); + $this->assertArrayHasKey( 'manage_stock', $properties ); + $this->assertArrayHasKey( 'stock_quantity', $properties ); + $this->assertArrayHasKey( 'in_stock', $properties ); + $this->assertArrayHasKey( 'backorders', $properties ); + $this->assertArrayHasKey( 'backorders_allowed', $properties ); + $this->assertArrayHasKey( 'backordered', $properties ); + $this->assertArrayHasKey( 'weight', $properties ); + $this->assertArrayHasKey( 'dimensions', $properties ); + $this->assertArrayHasKey( 'shipping_class', $properties ); + $this->assertArrayHasKey( 'shipping_class_id', $properties ); + $this->assertArrayHasKey( 'image', $properties ); + $this->assertArrayHasKey( 'attributes', $properties ); + $this->assertArrayHasKey( 'menu_order', $properties ); + $this->assertArrayHasKey( 'meta_data', $properties ); + } + + /** + * Test updating a variation stock. + * + * @since 3.0.0 + */ + public function test_update_variation_manage_stock() { + wp_set_current_user( $this->user ); + + $product = WC_Helper_Product::create_variation_product(); + $product->set_manage_stock( false ); + $product->save(); + + $children = $product->get_children(); + $variation_id = $children[0]; + + // Set stock to true. + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => true, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( true, $variation['manage_stock'] ); + + // Set stock to false. + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => false, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( false, $variation['manage_stock'] ); + + // Set stock to false but parent is managing stock. + $product->set_manage_stock( true ); + $product->save(); + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => false, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'parent', $variation['manage_stock'] ); + } +} diff --git a/tests/Version2/products.php b/tests/Version2/products.php new file mode 100644 index 00000000000..e45f51d7f4b --- /dev/null +++ b/tests/Version2/products.php @@ -0,0 +1,535 @@ +endpoint = new WC_REST_Products_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/products', $routes ); + $this->assertArrayHasKey( '/wc/v2/products/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v2/products/batch', $routes ); + } + + /** + * Test getting products. + * + * @since 3.0.0 + */ + public function test_get_products() { + wp_set_current_user( $this->user ); + WC_Helper_Product::create_external_product(); + sleep( 1 ); // So both products have different timestamps. + WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 2, count( $products ) ); + $this->assertEquals( 'Dummy Product', $products[0]['name'] ); + $this->assertEquals( 'DUMMY SKU', $products[0]['sku'] ); + $this->assertEquals( 'Dummy External Product', $products[1]['name'] ); + $this->assertEquals( 'DUMMY EXTERNAL SKU', $products[1]['sku'] ); + } + + /** + * Test getting products without permission. + * + * @since 3.0.0 + */ + public function test_get_products_without_permission() { + wp_set_current_user( 0 ); + WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single product. + * + * @since 3.0.0 + */ + public function test_get_product() { + wp_set_current_user( $this->user ); + $simple = WC_Helper_Product::create_external_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $simple->get_id() ) ); + $product = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( + array( + 'id' => $simple->get_id(), + 'name' => 'Dummy External Product', + 'type' => 'simple', + 'status' => 'publish', + 'sku' => 'DUMMY EXTERNAL SKU', + 'regular_price' => 10, + ), + $product + ); + } + + /** + * Test getting single product without permission. + * + * @since 3.0.0 + */ + public function test_get_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single product. + * + * @since 3.0.0 + */ + public function test_delete_product() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); + $variations = $response->get_data(); + $this->assertEquals( 0, count( $variations ) ); + } + + /** + * Test deleting a single product without permission. + * + * @since 3.0.0 + */ + public function test_delete_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single product with an invalid ID. + * + * @since 3.0.0 + */ + public function test_delete_product_with_invalid_id() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test editing a single product. Tests multiple product types. + * + * @since 3.0.0 + */ + public function test_update_product() { + wp_set_current_user( $this->user ); + + // test simple products. + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 'DUMMY SKU', $data['sku'] ); + $this->assertEquals( 10, $data['regular_price'] ); + $this->assertEmpty( $data['sale_price'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU', + 'sale_price' => '8', + 'description' => 'Testing', + 'images' => array( + array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Testing', $data['description'] ); + $this->assertEquals( '8', $data['price'] ); + $this->assertEquals( '8', $data['sale_price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertEquals( 'FIXED-SKU', $data['sku'] ); + $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); + $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); + $product->delete( true ); + + // test variable product (variations are tested in product-variations.php). + $product = WC_Helper_Product::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); + $data = $response->get_data(); + + foreach ( array( 'small', 'large' ) as $term_name ) { + $this->assertContains( $term_name, $data['attributes'][0]['options'] ); + } + + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'attributes' => array( + array( + 'id' => 0, + 'name' => 'pa_color', + 'options' => array( + 'red', + 'yellow', + ), + 'visible' => false, + 'variation' => 1, + ), + array( + 'id' => 0, + 'name' => 'pa_size', + 'options' => array( + 'small', + ), + 'visible' => false, + 'variation' => 1, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( array( 'small' ), $data['attributes'][0]['options'] ); + $this->assertEquals( array( 'red', 'yellow' ), $data['attributes'][1]['options'] ); + $product->delete( true ); + + // test external product. + $product = WC_Helper_Product::create_external_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 'Buy external product', $data['button_text'] ); + $this->assertEquals( 'http://woocommerce.com', $data['external_url'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'button_text' => 'Test API Update', + 'external_url' => 'http://automattic.com', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'Test API Update', $data['button_text'] ); + $this->assertEquals( 'http://automattic.com', $data['external_url'] ); + } + + /** + * Test updating a single product without permission. + * + * @since 3.0.0 + */ + public function test_update_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single product with an invalid ID. + * + * @since 3.0.0 + */ + public function test_update_product_with_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-INVALID-ID', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating a single product. + * + * @since 3.0.0 + */ + public function test_create_product() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/products/shipping_classes' ); + $request->set_body_params( + array( + 'name' => 'Test', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $shipping_class_id = $data['id']; + + // Create simple. + $request = new WP_REST_Request( 'POST', '/wc/v2/products' ); + $request->set_body_params( + array( + 'type' => 'simple', + 'name' => 'Test Simple Product', + 'sku' => 'DUMMY SKU SIMPLE API', + 'regular_price' => '10', + 'shipping_class' => 'test', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '10', $data['price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertTrue( $data['purchasable'] ); + $this->assertEquals( 'DUMMY SKU SIMPLE API', $data['sku'] ); + $this->assertEquals( 'Test Simple Product', $data['name'] ); + $this->assertEquals( 'simple', $data['type'] ); + $this->assertEquals( $shipping_class_id, $data['shipping_class_id'] ); + + // Create external. + $request = new WP_REST_Request( 'POST', '/wc/v2/products' ); + $request->set_body_params( + array( + 'type' => 'external', + 'name' => 'Test External Product', + 'sku' => 'DUMMY SKU EXTERNAL API', + 'regular_price' => '10', + 'button_text' => 'Test Button', + 'external_url' => 'https://wordpress.org', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '10', $data['price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertFalse( $data['purchasable'] ); + $this->assertEquals( 'DUMMY SKU EXTERNAL API', $data['sku'] ); + $this->assertEquals( 'Test External Product', $data['name'] ); + $this->assertEquals( 'external', $data['type'] ); + $this->assertEquals( 'Test Button', $data['button_text'] ); + $this->assertEquals( 'https://wordpress.org', $data['external_url'] ); + + // Create variable. + $request = new WP_REST_Request( 'POST', '/wc/v2/products' ); + $request->set_body_params( + array( + 'type' => 'variable', + 'name' => 'Test Variable Product', + 'sku' => 'DUMMY SKU VARIABLE API', + 'attributes' => array( + array( + 'id' => 0, + 'name' => 'pa_size', + 'options' => array( + 'small', + 'medium', + ), + 'visible' => false, + 'variation' => 1, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'DUMMY SKU VARIABLE API', $data['sku'] ); + $this->assertEquals( 'Test Variable Product', $data['name'] ); + $this->assertEquals( 'variable', $data['type'] ); + $this->assertEquals( array( 'small', 'medium' ), $data['attributes'][0]['options'] ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); + $products = $response->get_data(); + $this->assertEquals( 3, count( $products ) ); + } + + /** + * Test creating a single product without permission. + * + * @since 3.0.0 + */ + public function test_create_product_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/products' ); + $request->set_body_params( + array( + 'name' => 'Test Product', + 'regular_price' => '12', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch managing products. + */ + public function test_products_batch() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_2 = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'POST', '/wc/v2/products/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $product->get_id(), + 'description' => 'Updated description.', + ), + ), + 'delete' => array( + $product_2->get_id(), + ), + 'create' => array( + array( + 'sku' => 'DUMMY SKU BATCH TEST 1', + 'regular_price' => '10', + 'name' => 'Test Batch Create 1', + 'type' => 'external', + 'button_text' => 'Test Button', + ), + array( + 'sku' => 'DUMMY SKU BATCH TEST 2', + 'regular_price' => '20', + 'name' => 'Test Batch Create 2', + 'type' => 'simple', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); + $this->assertEquals( 'DUMMY SKU BATCH TEST 1', $data['create'][0]['sku'] ); + $this->assertEquals( 'DUMMY SKU BATCH TEST 2', $data['create'][1]['sku'] ); + $this->assertEquals( 'Test Button', $data['create'][0]['button_text'] ); + $this->assertEquals( 'external', $data['create'][0]['type'] ); + $this->assertEquals( 'simple', $data['create'][1]['type'] ); + $this->assertEquals( $product_2->get_id(), $data['delete'][0]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Tests to make sure you can filter products post statuses by both + * the status query arg and WP_Query. + * + * @since 3.0.0 + */ + public function test_products_filter_post_status() { + wp_set_current_user( $this->user ); + for ( $i = 0; $i < 8; $i++ ) { + $product = WC_Helper_Product::create_simple_product(); + if ( 0 === $i % 2 ) { + wp_update_post( + array( + 'ID' => $product->get_id(), + 'post_status' => 'draft', + ) + ); + } + } + + // Test filtering with status=publish. + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_param( 'status', 'publish' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 4, count( $products ) ); + foreach ( $products as $product ) { + $this->assertEquals( 'publish', $product['status'] ); + } + + // Test filtering with status=draft. + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_param( 'status', 'draft' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 4, count( $products ) ); + foreach ( $products as $product ) { + $this->assertEquals( 'draft', $product['status'] ); + } + + // Test filtering with no filters - which should return 'any' (all 8). + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 8, count( $products ) ); + } + + /** + * Test product schema. + * + * @since 3.0.0 + */ + public function test_product_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/products/' . $product->get_id() ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 65, count( $properties ) ); + } +} diff --git a/tests/Version2/settings.php b/tests/Version2/settings.php new file mode 100644 index 00000000000..f88abaa1588 --- /dev/null +++ b/tests/Version2/settings.php @@ -0,0 +1,892 @@ +endpoint = new WC_REST_Setting_Options_Controller(); + WC_Helper_Settings::register(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/settings', $routes ); + $this->assertArrayHasKey( '/wc/v2/settings/(?P[\w-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v2/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all groups. + * + * @since 3.0.0 + */ + public function test_get_groups() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertContains( + array( + 'id' => 'test', + 'label' => 'Test extension', + 'parent_id' => '', + 'description' => 'My awesome test settings.', + 'sub_groups' => array( 'sub-test' ), + '_links' => array( + 'options' => array( + array( + 'href' => rest_url( '/wc/v2/settings/test' ), + ), + ), + ), + ), + $data + ); + + $this->assertContains( + array( + 'id' => 'sub-test', + 'label' => 'Sub test', + 'parent_id' => 'test', + 'description' => '', + 'sub_groups' => array(), + '_links' => array( + 'options' => array( + array( + 'href' => rest_url( '/wc/v2/settings/sub-test' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test /settings without valid permissions/creds. + * + * @since 3.0.0 + */ + public function test_get_groups_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test /settings without valid permissions/creds. + * + * @since 3.0.0 + * @covers WC_Rest_Settings_Controller::get_items + */ + public function test_get_groups_none_registered() { + wp_set_current_user( $this->user ); + + remove_all_filters( 'woocommerce_settings_groups' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings' ) ); + $this->assertEquals( 500, $response->get_status() ); + + WC_Helper_Settings::register(); + } + + /** + * Test groups schema. + * + * @since 3.0.0 + */ + public function test_get_group_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/settings' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 5, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'parent_id', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'sub_groups', $properties ); + } + + /** + * Test settings schema. + * + * @since 3.0.0 + */ + public function test_get_setting_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/settings/test/woocommerce_shop_page_display' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 9, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'value', $properties ); + $this->assertArrayHasKey( 'default', $properties ); + $this->assertArrayHasKey( 'tip', $properties ); + $this->assertArrayHasKey( 'placeholder', $properties ); + $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'options', $properties ); + } + + /** + * Test getting a single group. + * + * @since 3.0.0 + */ + public function test_get_group() { + wp_set_current_user( $this->user ); + + // test route callback receiving an empty group id + $result = $this->endpoint->get_group_settings( '' ); + $this->assertIsWPError( $result ); + + // test getting a group that does not exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/not-real' ) ); + $this->assertEquals( 404, $response->get_status() ); + + // test getting the 'invalid' group + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/invalid' ) ); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid group with settings attached to it + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( 1, count( $data ) ); + $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); + $this->assertEmpty( $data[0]['value'] ); + } + + /** + * Test getting a single group without permission. + * + * @since 3.0.0 + */ + public function test_get_group_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/coupon-data' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single setting. + * + * @since 3.0.0 + */ + public function test_update_setting() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data['value'] ); + + // test updating shop display setting + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'both', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'both', $data['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'subcategories', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'subcategories', $data['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => '', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '', $data['value'] ); + $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); + } + + /** + * Test updating multiple settings at once. + * + * @since 3.0.0 + */ + public function test_update_settings() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data[0]['value'] ); + + // test setting both at once + $request = new WP_REST_Request( 'POST', '/wc/v2/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'both', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'both', $data['update'][0]['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + + // test updating one, but making sure the other value stays the same + $request = new WP_REST_Request( 'POST', '/wc/v2/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + } + + /** + * Test getting a single setting. + * + * @since 3.0.0 + */ + public function test_get_setting() { + wp_set_current_user( $this->user ); + + // test getting an invalid setting from a group that does not exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/not-real/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting an invalid setting from a group that does exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/invalid/invalid' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid setting + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'woocommerce_shop_page_display', $data['id'] ); + $this->assertEquals( 'Shop page display', $data['label'] ); + $this->assertEquals( '', $data['default'] ); + $this->assertEquals( 'select', $data['type'] ); + $this->assertEquals( '', $data['value'] ); + } + + /** + * Test getting a single setting without valid user permissions. + * + * @since 3.0.0 + */ + public function test_get_setting_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test/woocommerce_shop_page_display' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests the GET single setting route handler receiving an empty setting ID. + * + * @since 3.0.0 + */ + public function test_get_setting_empty_setting_id() { + $result = $this->endpoint->get_setting( 'test', '' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler receiving an invalid setting ID. + * + * @since 3.0.0 + */ + public function test_get_setting_invalid_setting_id() { + $result = $this->endpoint->get_setting( 'test', 'invalid' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler encountering an invalid setting type. + * + * @since 3.0.0 + */ + public function test_get_setting_invalid_setting_type() { + // $controller = $this->getMock( 'WC_Rest_Setting_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); + $controller = $this->getMockBuilder( 'WC_Rest_Setting_Options_Controller' )->setMethods( array( 'get_group_settings', 'is_setting_type_valid' ) )->getMock(); + + $controller + ->expects( $this->any() ) + ->method( 'get_group_settings' ) + ->will( $this->returnValue( WC_Helper_Settings::register_test_settings( array() ) ) ); + + $controller + ->expects( $this->any() ) + ->method( 'is_setting_type_valid' ) + ->will( $this->returnValue( false ) ); + + $result = $controller->get_setting( 'test', 'woocommerce_shop_page_display' ); + + $this->assertIsWPError( $result ); + } + + /** + * Test updating a single setting without valid user permissions. + * + * @since 3.0.0 + */ + public function test_update_setting_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'subcategories', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + + /** + * Test updating multiple settings without valid user permissions. + * + * @since 3.0.0 + */ + public function test_update_settings_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a bad setting ID. + * + * @since 3.0.0 + * @covers WC_Rest_Setting_Options_Controller::update_item + */ + public function test_update_setting_bad_setting_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/test/invalid' ); + $request->set_body_params( + array( + 'value' => 'test', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. + * + * @since 3.0.0 + */ + public function test_classic_settings() { + wp_set_current_user( $this->user ); + + // Make sure the group is properly registered + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/products' ) ); + $data = $response->get_data(); + $this->assertTrue( is_array( $data ) ); + $this->assertContains( + array( + 'id' => 'woocommerce_downloads_require_login', + 'label' => 'Access restriction', + 'description' => 'Downloads require login', + 'type' => 'checkbox', + 'default' => 'no', + 'tip' => 'This setting does not apply to guest purchases.', + 'value' => 'no', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/settings/products/woocommerce_downloads_require_login' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/settings/products' ), + ), + ), + ), + ), + $data + ); + + // test get single + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/products/woocommerce_dimension_unit' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'cm', $data['default'] ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); + $request->set_body_params( + array( + 'value' => 'yd', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'yd', $data['value'] ); + $this->assertEquals( 'yd', get_option( 'woocommerce_dimension_unit' ) ); + } + + /** + * Tests our email etting registration to make sure settings added for WP-Admin are available over the API. + * + * @since 3.0.0 + */ + public function test_email_settings() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/email_new_order' ) ); + $settings = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertContains( + array( + 'id' => 'recipient', + 'label' => 'Recipient(s)', + 'description' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', + 'type' => 'text', + 'default' => '', + 'tip' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', + 'value' => '', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/settings/email_new_order/recipient' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/settings/email_new_order' ), + ), + ), + ), + ), + $settings + ); + + // test get single + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/email_new_order/subject' ) ); + $setting = $response->get_data(); + + $this->assertEquals( + array( + 'id' => 'subject', + 'label' => 'Subject', + 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'type' => 'text', + 'default' => '', + 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'value' => '', + ), + $setting + ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_new_order', 'subject' ) ); + $request->set_body_params( + array( + 'value' => 'This is my subject', + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEquals( + array( + 'id' => 'subject', + 'label' => 'Subject', + 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'type' => 'text', + 'default' => '', + 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'value' => 'This is my subject', + ), + $setting + ); + + // test updating another subject and making sure it works with a "similar" id + $request = new WP_REST_Request( 'GET', sprintf( '/wc/v2/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEmpty( $setting['value'] ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); + $request->set_body_params( + array( + 'value' => 'This is my new subject', + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEquals( 'This is my new subject', $setting['value'] ); + + // make sure the other is what we left it + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/email_new_order/subject' ) ); + $setting = $response->get_data(); + + $this->assertEquals( 'This is my subject', $setting['value'] ); + } + + /** + * Test validation of checkbox settings. + * + * @since 3.0.0 + */ + public function test_validation_checkbox() { + wp_set_current_user( $this->user ); + + // test bogus value + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'not_yes_or_no', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // test yes + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'yes', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + // test no + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'no', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test validation of radio settings. + * + * @since 3.0.0 + */ + public function test_validation_radio() { + wp_set_current_user( $this->user ); + + // not a valid option + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); + $request->set_body_params( + array( + 'value' => 'billing2', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // valid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); + $request->set_body_params( + array( + 'value' => 'billing', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test validation of multiselect. + * + * @since 3.0.0 + */ + public function test_validation_multiselect() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v2/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ) ); + $setting = $response->get_data(); + $this->assertEmpty( $setting['value'] ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ); + $request->set_body_params( + array( + 'value' => array( 'AX', 'DZ', 'MMM' ), + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( array( 'AX', 'DZ' ), $setting['value'] ); + } + + /** + * Test validation of select. + * + * @since 3.0.0 + */ + public function test_validation_select() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ) ); + $setting = $response->get_data(); + $this->assertEquals( 'kg', $setting['value'] ); + + // invalid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); + $request->set_body_params( + array( + 'value' => 'pounds', // invalid, should be lbs + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // valid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); + $request->set_body_params( + array( + 'value' => 'lbs', // invalid, should be lbs + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( 'lbs', $setting['value'] ); + } + + /** + * Test to make sure the 'base location' setting is present in the response. + * That it is returned as 'select' and not 'single_select_country', + * and that both state and country options are returned. + * + * @since 3.0.7 + */ + public function test_woocommerce_default_country() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_default_country' ) ); + $setting = $response->get_data(); + + $this->assertEquals( 'select', $setting['type'] ); + $this->assertArrayHasKey( 'GB', $setting['options'] ); + $this->assertArrayHasKey( 'US:OR', $setting['options'] ); + } + + /** + * Test to make sure the store address setting can be fetched and updated. + * + * @since 3.1.1 + */ + public function test_woocommerce_store_address() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_address' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store address 2 (line 2) setting can be fetched and updated. + * + * @since 3.1.1 + */ + public function test_woocommerce_store_address_2() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_address_2' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address_2' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address_2' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store city setting can be fetched and updated. + * + * @since 3.1.1 + */ + public function test_woocommerce_store_city() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_city' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_city' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_city' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store postcode setting can be fetched and updated. + * + * @since 3.1.1 + */ + public function test_woocommerce_store_postcode() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_postcode' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_postcode' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_postcode' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } +} diff --git a/tests/Version2/shipping-methods.php b/tests/Version2/shipping-methods.php new file mode 100644 index 00000000000..65c153e8f31 --- /dev/null +++ b/tests/Version2/shipping-methods.php @@ -0,0 +1,143 @@ +endpoint = new WC_REST_Shipping_Methods_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/shipping_methods', $routes ); + $this->assertArrayHasKey( '/wc/v2/shipping_methods/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all shipping methods. + * + * @since 3.0.0 + */ + public function test_get_shipping_methods() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods' ) ); + $methods = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( + array( + 'id' => 'free_shipping', + 'title' => 'Free shipping', + 'description' => 'Free shipping is a special method which can be triggered with coupons and minimum spends.', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/shipping_methods/free_shipping' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping_methods' ), + ), + ), + ), + ), + $methods + ); + } + + /** + * Tests to make sure shipping methods cannot viewed without valid permissions. + * + * @since 3.0.0 + */ + public function test_get_shipping_methods_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a single shipping method. + * + * @since 3.0.0 + */ + public function test_get_shipping_method() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods/local_pickup' ) ); + $method = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => 'local_pickup', + 'title' => 'Local pickup', + 'description' => 'Allow customers to pick up orders themselves. By default, when using local pickup store base taxes will apply regardless of customer address.', + ), + $method + ); + } + + /** + * Tests getting a single shipping method without the correct permissions. + * + * @since 3.0.0 + */ + public function test_get_shipping_method_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods/local_pickup' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a shipping method with an invalid ID. + * + * @since 3.0.0 + */ + public function test_get_shipping_method_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods/fake_method' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test the shipping method schema. + * + * @since 3.0.0 + */ + public function test_shipping_method_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/shipping_methods' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'title', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + } +} diff --git a/tests/Version2/shipping-zones.php b/tests/Version2/shipping-zones.php new file mode 100644 index 00000000000..c6e2c4a102e --- /dev/null +++ b/tests/Version2/shipping-zones.php @@ -0,0 +1,800 @@ +endpoint = new WC_REST_Shipping_Zones_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + $this->zones = array(); + } + + /** + * Helper method to create a Shipping Zone. + * + * @param string $name Zone name. + * @param int $order Optional. Zone sort order. + * @return WC_Shipping_Zone + */ + protected function create_shipping_zone( $name, $order = 0, $locations = array() ) { + $zone = new WC_Shipping_Zone( null ); + $zone->set_zone_name( $name ); + $zone->set_zone_order( $order ); + $zone->set_locations( $locations ); + $zone->save(); + + $this->zones[] = $zone; + + return $zone; + } + + /** + * Test route registration. + * @since 3.0.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/shipping/zones', $routes ); + $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/locations', $routes ); + $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/methods', $routes ); + $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/methods/(?P[\d]+)', $routes ); + } + + /** + * Test getting all Shipping Zones. + * @since 3.0.0 + */ + public function test_get_zones() { + wp_set_current_user( $this->user ); + + // "Rest of the World" zone exists by default + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( + array( + 'id' => $data[0]['id'], + 'name' => 'Locations not covered by your other zones', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $data[0]['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $data[0]['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + + // Create a zone and make sure it's in the response + $this->create_shipping_zone( 'Zone 1' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 2 ); + $this->assertContains( + array( + 'id' => $data[1]['id'], + 'name' => 'Zone 1', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $data[1]['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $data[1]['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test /shipping/zones without valid permissions/creds. + * @since 3.0.0 + */ + public function test_get_shipping_zones_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test /shipping/zones while Shipping is disabled in WooCommerce. + * @since 3.0.0 + */ + public function test_get_shipping_zones_disabled_shipping() { + wp_set_current_user( $this->user ); + + add_filter( 'wc_shipping_enabled', '__return_false' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones' ) ); + $this->assertEquals( 404, $response->get_status() ); + + remove_filter( 'wc_shipping_enabled', '__return_false' ); + } + + /** + * Test Shipping Zone schema. + * @since 3.0.0 + */ + public function test_get_shipping_zone_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/shipping/zones' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertTrue( $properties['id']['readonly'] ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'order', $properties ); + } + + /** + * Test Shipping Zone create endpoint. + * @since 3.0.0 + */ + public function test_create_shipping_zone() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones' ); + $request->set_body_params( + array( + 'name' => 'Test Zone', + 'order' => 1, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'name' => 'Test Zone', + 'order' => 1, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $data['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $data['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test Shipping Zone create endpoint. + * @since 3.0.0 + */ + public function test_create_shipping_zone_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones' ); + $request->set_body_params( + array( + 'name' => 'Test Zone', + 'order' => 1, + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test Shipping Zone update endpoint. + * @since 3.0.0 + */ + public function test_update_shipping_zone() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/shipping/zones/' . $zone->get_id() ); + $request->set_body_params( + array( + 'name' => 'Zone Test', + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $zone->get_id(), + 'name' => 'Zone Test', + 'order' => 2, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test Shipping Zone update endpoint with a bad zone ID. + * @since 3.0.0 + */ + public function test_update_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/shipping/zones/555555' ); + $request->set_body_params( + array( + 'name' => 'Zone Test', + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint. + * @since 3.0.0 + */ + public function test_delete_shipping_zone() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v2/shipping/zones/' . $zone->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint without permissions. + * @since 3.0.0 + */ + public function test_delete_shipping_zone_without_permission() { + wp_set_current_user( 0 ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v2/shipping/zones/' . $zone->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint with a bad zone ID. + * @since 3.0.0 + */ + public function test_delete_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'DELETE', '/wc/v2/shipping/zones/555555' ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single Shipping Zone. + * @since 3.0.0 + */ + public function test_get_single_shipping_zone() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $zone->get_id(), + 'name' => 'Test Zone', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test getting a single Shipping Zone with a bad zone ID. + * @since 3.0.0 + */ + public function test_get_single_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting Shipping Zone Locations. + * @since 3.0.0 + */ + public function test_get_locations() { + wp_set_current_user( $this->user ); + + // Create a zone + $zone = $this->create_shipping_zone( + 'Zone 1', + 0, + array( + array( + 'code' => 'US', + 'type' => 'country', + ), + ) + ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertEquals( + array( + array( + 'code' => 'US', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test getting Shipping Zone Locations with a bad zone ID. + * @since 3.0.0 + */ + public function test_get_locations_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/1/locations' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test Shipping Zone Locations update endpoint. + * @since 3.0.0 + */ + public function test_update_locations() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + json_encode( + array( + array( + 'code' => 'UK', + 'type' => 'country', + ), + array( + 'code' => 'US', // test that locations missing "type" treated as country. + ), + array( + 'code' => 'SW1A0AA', + 'type' => 'postcode', + ), + array( + 'type' => 'continent', // test that locations missing "code" aren't saved + ), + ) + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + $this->assertEquals( + array( + array( + 'code' => 'UK', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + array( + 'code' => 'US', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + array( + 'code' => 'SW1A0AA', + 'type' => 'postcode', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test updating Shipping Zone Locations with a bad zone ID. + * @since 3.0.0 + */ + public function test_update_locations_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'PUT', '/wc/v2/shipping/zones/1/locations' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting all Shipping Zone Methods and getting a single Shipping Zone Method. + * @since 3.0.0 + */ + public function test_get_methods() { + wp_set_current_user( $this->user ); + + // Create a shipping method and make sure it's in the response + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + + $settings = array(); + $method->init_instance_settings(); + foreach ( $method->get_instance_form_fields() as $id => $field ) { + $data = array( + 'id' => $id, + 'label' => $field['title'], + 'description' => ( empty( $field['description'] ) ? '' : $field['description'] ), + 'type' => $field['type'], + 'value' => $method->instance_settings[ $id ], + 'default' => ( empty( $field['default'] ) ? '' : $field['default'] ), + 'tip' => ( empty( $field['description'] ) ? '' : $field['description'] ), + 'placeholder' => ( empty( $field['placeholder'] ) ? '' : $field['placeholder'] ), + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods' ) ); + $data = $response->get_data(); + $expected = array( + 'id' => $instance_id, + 'instance_id' => $instance_id, + 'title' => $method->instance_settings['title'], + 'order' => $method->method_order, + 'enabled' => ( 'yes' === $method->enabled ), + 'method_id' => $method->id, + 'method_title' => $method->method_title, + 'method_description' => $method->method_description, + 'settings' => $settings, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( $expected, $data ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $expected, $data ); + } + + /** + * Test getting all Shipping Zone Methods with a bad zone ID. + * @since 3.0.0 + */ + public function test_get_methods_invalid_zone_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/1/methods' ) ); + + $this->assertEquals( 404, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/1/methods/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single Shipping Zone Method with a bad ID. + * @since 3.0.0 + */ + public function test_get_methods_invalid_method_id() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Zone 1' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a Shipping Zone Method. + * @since 3.0.0 + */ + public function test_update_methods() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + + // Test defaults + $request = new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '0', $data['settings']['cost']['value'] ); + + // Update a single value + $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 5, + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '5', $data['settings']['cost']['value'] ); + + // Test multiple settings + $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 10, + 'tax_status' => 'none', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'none', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '10', $data['settings']['cost']['value'] ); + + // Test bogus + $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 10, + 'tax_status' => 'this_is_not_a_valid_option', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // Test other parameters + $this->assertTrue( $data['enabled'] ); + $this->assertEquals( 1, $data['order'] ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertFalse( $data['enabled'] ); + $this->assertEquals( 2, $data['order'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '10', $data['settings']['cost']['value'] ); + } + + /** + * Test creating a Shipping Zone Method. + * @since 3.0.0 + */ + public function test_create_method() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods' ); + $request->set_body_params( + array( + 'method_id' => 'flat_rate', + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertFalse( $data['enabled'] ); + $this->assertEquals( 2, $data['order'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '0', $data['settings']['cost']['value'] ); + } + + /** + * Test deleting a Shipping Zone Method. + * @since 3.0.0 + */ + public function test_delete_method() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + $request = new WP_REST_Request( 'DELETE', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } +} diff --git a/tests/Version2/system-status.php b/tests/Version2/system-status.php new file mode 100644 index 00000000000..f9b5e471a16 --- /dev/null +++ b/tests/Version2/system-status.php @@ -0,0 +1,356 @@ +endpoint = new WC_REST_System_Status_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v2/system_status', $routes ); + $this->assertArrayHasKey( '/wc/v2/system_status/tools', $routes ); + $this->assertArrayHasKey( '/wc/v2/system_status/tools/(?P[\w-]+)', $routes ); + } + + /** + * Test to make sure system status cannot be accessed without valid creds + * + * @since 3.0.0 + */ + public function test_get_system_status_info_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure root properties are present. + * (environment, theme, database, etc). + * + * @since 3.0.0 + */ + public function test_get_system_status_info_returns_root_properties() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'environment', $data ); + $this->assertArrayHasKey( 'database', $data ); + $this->assertArrayHasKey( 'active_plugins', $data ); + $this->assertArrayHasKey( 'theme', $data ); + $this->assertArrayHasKey( 'settings', $data ); + $this->assertArrayHasKey( 'security', $data ); + $this->assertArrayHasKey( 'pages', $data ); + } + + /** + * Test to make sure environment response is correct. + * + * @since 3.0.0 + */ + public function test_get_system_status_info_environment() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + $data = $response->get_data(); + $environment = (array) $data['environment']; + + // Make sure all expected data is present. + $this->assertEquals( 32, count( $environment ) ); + + // Test some responses to make sure they match up. + $this->assertEquals( get_option( 'home' ), $environment['home_url'] ); + $this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] ); + $this->assertEquals( WC()->version, $environment['version'] ); + } + + /** + * Test to make sure database response is correct. + * + * @since 3.0.0 + */ + public function test_get_system_status_info_database() { + global $wpdb; + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + $data = $response->get_data(); + $database = (array) $data['database']; + + $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); + $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); + $this->assertEquals( WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); + $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], print_r( $database, true ) ); + $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], print_r( $database, true ) ); + } + + /** + * Test to make sure active plugins response is correct. + * + * @since 3.0.0 + */ + public function test_get_system_status_info_active_plugins() { + wp_set_current_user( $this->user ); + + $actual_plugins = array( 'hello.php' ); + update_option( 'active_plugins', $actual_plugins ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + update_option( 'active_plugins', array() ); + + $data = $response->get_data(); + $plugins = (array) $data['active_plugins']; + + $this->assertEquals( 1, count( $plugins ) ); + $this->assertEquals( 'Hello Dolly', $plugins[0]['name'] ); + } + + /** + * Test to make sure theme response is correct. + * + * @since 3.0.0 + */ + public function test_get_system_status_info_theme() { + wp_set_current_user( $this->user ); + $active_theme = wp_get_theme(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + $data = $response->get_data(); + $theme = (array) $data['theme']; + + $this->assertEquals( 13, count( $theme ) ); + $this->assertEquals( $active_theme->Name, $theme['name'] ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar + } + + /** + * Test to make sure settings response is correct. + * + * @since 3.0.0 + */ + public function test_get_system_status_info_settings() { + wp_set_current_user( $this->user ); + + $term_response = array(); + $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + $data = $response->get_data(); + $settings = (array) $data['settings']; + + $this->assertEquals( 12, count( $settings ) ); + $this->assertEquals( ( 'yes' === get_option( 'woocommerce_api_enabled' ) ), $settings['api_enabled'] ); + $this->assertEquals( get_woocommerce_currency(), $settings['currency'] ); + $this->assertEquals( $term_response, $settings['taxonomies'] ); + } + + /** + * Test to make sure security response is correct. + * + * @since 3.0.0 + */ + public function test_get_system_status_info_security() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + $data = $response->get_data(); + $settings = (array) $data['security']; + + $this->assertEquals( 2, count( $settings ) ); + $this->assertEquals( 'https' === substr( wc_get_page_permalink( 'shop' ), 0, 5 ), $settings['secure_connection'] ); + $this->assertEquals( ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), $settings['hide_errors'] ); + } + + /** + * Test to make sure pages response is correct. + * + * @since 3.0.0 + */ + public function test_get_system_status_info_pages() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); + $data = $response->get_data(); + $pages = $data['pages']; + $this->assertEquals( 5, count( $pages ) ); + } + + /** + * Test system status schema. + * + * @since 3.0.0 + */ + public function test_system_status_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/system_status' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 9, count( $properties ) ); + $this->assertArrayHasKey( 'environment', $properties ); + $this->assertArrayHasKey( 'database', $properties ); + $this->assertArrayHasKey( 'active_plugins', $properties ); + $this->assertArrayHasKey( 'theme', $properties ); + $this->assertArrayHasKey( 'settings', $properties ); + $this->assertArrayHasKey( 'security', $properties ); + $this->assertArrayHasKey( 'pages', $properties ); + } + + /** + * Test to make sure get_items (all tools) response is correct. + * + * @since 3.0.0 + */ + public function test_get_system_tools() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status/tools' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $raw_tools ), count( $data ) ); + $this->assertContains( + array( + 'id' => 'regenerate_thumbnails', + 'name' => 'Regenerate shop thumbnails', + 'action' => 'Regenerate', + 'description' => 'This will regenerate all shop thumbnails to match your theme and/or image settings.', + '_links' => array( + 'item' => array( + array( + 'href' => rest_url( '/wc/v2/system_status/tools/regenerate_thumbnails' ), + 'embeddable' => true, + ), + ), + ), + ), + $data + ); + } + + /** + * Test to make sure system status tools cannot be accessed without valid creds + * + * @since 3.0.0 + */ + public function test_get_system_status_tools_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status/tools' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure we can load a single tool correctly. + * + * @since 3.0.0 + */ + public function test_get_system_tool() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + $raw_tool = $raw_tools['recount_terms']; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status/tools/recount_terms' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertEquals( 'Recount terms', $data['action'] ); + $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); + } + + /** + * Test to make sure a single system status toolscannot be accessed without valid creds. + * + * @since 3.0.0 + */ + public function test_get_system_status_tool_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status/tools/recount_terms' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure we can RUN a tool correctly. + * + * @since 3.0.0 + */ + public function test_execute_system_tool() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + $raw_tool = $raw_tools['recount_terms']; + + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v2/system_status/tools/recount_terms' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertEquals( 'Recount terms', $data['action'] ); + $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); + $this->assertTrue( $data['success'] ); + $this->assertEquals( 1, did_action( 'woocommerce_rest_insert_system_status_tool' ) ); + + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v2/system_status/tools/not_a_real_tool' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test to make sure a tool cannot be run without valid creds. + * + * @since 3.0.0 + */ + public function test_execute_system_status_tool_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v2/system_status/tools/recount_terms' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test system status schema. + * + * @since 3.0.0 + */ + public function test_system_status_tool_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/system_status/tools' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 6, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'action', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'success', $properties ); + $this->assertArrayHasKey( 'message', $properties ); + } +} diff --git a/tests/Version3/coupons.php b/tests/Version3/coupons.php new file mode 100644 index 00000000000..40f9eaee25f --- /dev/null +++ b/tests/Version3/coupons.php @@ -0,0 +1,471 @@ +endpoint = new WC_REST_Coupons_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/coupons', $routes ); + $this->assertArrayHasKey( '/wc/v3/coupons/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/coupons/batch', $routes ); + } + + /** + * Test getting coupons. + * @since 3.5.0 + */ + public function test_get_coupons() { + wp_set_current_user( $this->user ); + + $coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $post_1 = get_post( $coupon_1->get_id() ); + $coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons' ) ); + $coupons = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $coupons ) ); + $this->assertContains( + array( + 'id' => $coupon_1->get_id(), + 'code' => 'dummycoupon-1', + 'amount' => '1.00', + 'date_created' => wc_rest_prepare_date_response( $post_1->post_date_gmt, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $post_1->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $post_1->post_modified_gmt, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $post_1->post_modified_gmt ), + 'discount_type' => 'fixed_cart', + 'description' => 'This is a dummy coupon', + 'date_expires' => '', + 'date_expires_gmt' => '', + 'usage_count' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'excluded_product_ids' => array(), + 'usage_limit' => '', + 'usage_limit_per_user' => '', + 'limit_usage_to_x_items' => null, + 'free_shipping' => false, + 'product_categories' => array(), + 'excluded_product_categories' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '0.00', + 'maximum_amount' => '0.00', + 'email_restrictions' => array(), + 'used_by' => array(), + 'meta_data' => array(), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/coupons/' . $coupon_1->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/coupons' ), + ), + ), + ), + ), + $coupons + ); + } + + /** + * Test getting coupons without valid permissions. + * @since 3.5.0 + */ + public function test_get_coupons_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single coupon. + * @since 3.5.0 + */ + public function test_get_coupon() { + wp_set_current_user( $this->user ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $post = get_post( $coupon->get_id() ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $coupon->get_id(), + 'code' => 'dummycoupon-1', + 'amount' => '1.00', + 'date_created' => wc_rest_prepare_date_response( $post->post_date_gmt, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $post->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $post->post_modified_gmt, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $post->post_modified_gmt ), + 'discount_type' => 'fixed_cart', + 'description' => 'This is a dummy coupon', + 'date_expires' => null, + 'date_expires_gmt' => null, + 'usage_count' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'excluded_product_ids' => array(), + 'usage_limit' => null, + 'usage_limit_per_user' => null, + 'limit_usage_to_x_items' => null, + 'free_shipping' => false, + 'product_categories' => array(), + 'excluded_product_categories' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '0.00', + 'maximum_amount' => '0.00', + 'email_restrictions' => array(), + 'used_by' => array(), + 'meta_data' => array(), + ), + $data + ); + } + + /** + * Test getting a single coupon with an invalid ID. + * @since 3.5.0 + */ + public function test_get_coupon_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single coupon without valid permissions. + * @since 3.5.0 + */ + public function test_get_coupon_without_permission() { + wp_set_current_user( 0 ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test creating a single coupon. + * @since 3.5.0 + */ + public function test_create_coupon() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'POST', '/wc/v3/coupons' ); + $request->set_body_params( + array( + 'code' => 'test', + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + 'description' => 'Test', + 'usage_limit' => 10, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'code' => 'test', + 'amount' => '5.00', + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_type' => 'fixed_product', + 'description' => 'Test', + 'date_expires' => null, + 'date_expires_gmt' => null, + 'usage_count' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'excluded_product_ids' => array(), + 'usage_limit' => 10, + 'usage_limit_per_user' => null, + 'limit_usage_to_x_items' => null, + 'free_shipping' => false, + 'product_categories' => array(), + 'excluded_product_categories' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '0.00', + 'maximum_amount' => '0.00', + 'email_restrictions' => array(), + 'used_by' => array(), + 'meta_data' => array(), + ), + $data + ); + } + + /** + * Test creating a single coupon with invalid fields. + * @since 3.5.0 + */ + public function test_create_coupon_invalid_fields() { + wp_set_current_user( $this->user ); + + // test no code... + $request = new WP_REST_Request( 'POST', '/wc/v3/coupons' ); + $request->set_body_params( + array( + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating a single coupon without valid permissions. + * @since 3.5.0 + */ + public function test_create_coupon_without_permission() { + wp_set_current_user( 0 ); + + // test no code... + $request = new WP_REST_Request( 'POST', '/wc/v3/coupons' ); + $request->set_body_params( + array( + 'code' => 'fail', + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single coupon. + * @since 3.5.0 + */ + public function test_update_coupon() { + wp_set_current_user( $this->user ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $post = get_post( $coupon->get_id() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); + $data = $response->get_data(); + $this->assertEquals( 'This is a dummy coupon', $data['description'] ); + $this->assertEquals( 'fixed_cart', $data['discount_type'] ); + $this->assertEquals( '1.00', $data['amount'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/coupons/' . $coupon->get_id() ); + $request->set_body_params( + array( + 'amount' => '10.00', + 'description' => 'New description', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '10.00', $data['amount'] ); + $this->assertEquals( 'New description', $data['description'] ); + $this->assertEquals( 'fixed_cart', $data['discount_type'] ); + } + + /** + * Test updating a single coupon with an invalid ID. + * @since 3.5.0 + */ + public function test_update_coupon_invalid_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/coupons/0' ); + $request->set_body_params( + array( + 'code' => 'tester', + 'amount' => '10.00', + 'description' => 'New description', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test updating a single coupon without valid permissions. + * @since 3.5.0 + */ + public function test_update_coupon_without_permission() { + wp_set_current_user( 0 ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $post = get_post( $coupon->get_id() ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/coupons/' . $coupon->get_id() ); + $request->set_body_params( + array( + 'amount' => '10.00', + 'description' => 'New description', + ) + ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single coupon. + * @since 3.5.0 + */ + public function test_delete_coupon() { + wp_set_current_user( $this->user ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/' . $coupon->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test deleting a single coupon with an invalid ID. + * @since 3.5.0 + */ + public function test_delete_coupon_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test deleting a single coupon without valid permissions. + * @since 3.5.0 + */ + public function test_delete_coupon_without_permission() { + wp_set_current_user( 0 ); + $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/' . $coupon->get_id() ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch operations on coupons. + * @since 3.5.0 + */ + public function test_batch_coupon() { + wp_set_current_user( $this->user ); + + $coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' ); + $coupon_3 = WC_Helper_Coupon::create_coupon( 'dummycoupon-3' ); + $coupon_4 = WC_Helper_Coupon::create_coupon( 'dummycoupon-4' ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/coupons/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $coupon_1->get_id(), + 'amount' => '5.15', + ), + ), + 'delete' => array( + $coupon_2->get_id(), + $coupon_3->get_id(), + ), + 'create' => array( + array( + 'code' => 'new-coupon', + 'amount' => '11.00', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '5.15', $data['update'][0]['amount'] ); + $this->assertEquals( '11.00', $data['create'][0]['amount'] ); + $this->assertEquals( 'new-coupon', $data['create'][0]['code'] ); + $this->assertEquals( $coupon_2->get_id(), $data['delete'][0]['id'] ); + $this->assertEquals( $coupon_3->get_id(), $data['delete'][1]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/coupons' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Test coupon schema. + * @since 3.5.0 + */ + public function test_coupon_schema() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/coupons' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 27, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'code', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_created_gmt', $properties ); + $this->assertArrayHasKey( 'date_modified', $properties ); + $this->assertArrayHasKey( 'date_modified_gmt', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'discount_type', $properties ); + $this->assertArrayHasKey( 'amount', $properties ); + $this->assertArrayHasKey( 'date_expires', $properties ); + $this->assertArrayHasKey( 'date_expires_gmt', $properties ); + $this->assertArrayHasKey( 'usage_count', $properties ); + $this->assertArrayHasKey( 'individual_use', $properties ); + $this->assertArrayHasKey( 'product_ids', $properties ); + $this->assertArrayHasKey( 'excluded_product_ids', $properties ); + $this->assertArrayHasKey( 'usage_limit', $properties ); + $this->assertArrayHasKey( 'usage_limit_per_user', $properties ); + $this->assertArrayHasKey( 'limit_usage_to_x_items', $properties ); + $this->assertArrayHasKey( 'free_shipping', $properties ); + $this->assertArrayHasKey( 'product_categories', $properties ); + $this->assertArrayHasKey( 'excluded_product_categories', $properties ); + $this->assertArrayHasKey( 'exclude_sale_items', $properties ); + $this->assertArrayHasKey( 'minimum_amount', $properties ); + $this->assertArrayHasKey( 'maximum_amount', $properties ); + $this->assertArrayHasKey( 'email_restrictions', $properties ); + $this->assertArrayHasKey( 'used_by', $properties ); + } +} diff --git a/tests/Version3/customers.php b/tests/Version3/customers.php new file mode 100644 index 00000000000..5995045bb85 --- /dev/null +++ b/tests/Version3/customers.php @@ -0,0 +1,634 @@ +endpoint = new WC_REST_Customers_Controller(); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( '/wc/v3/customers', $routes ); + $this->assertArrayHasKey( '/wc/v3/customers/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/customers/batch', $routes ); + } + + /** + * Test getting customers. + * + * @since 3.5.0 + */ + public function test_get_customers() { + wp_set_current_user( 1 ); + + $customer_1 = WC_Helper_Customer::create_customer(); + WC_Helper_Customer::create_customer( 'test2', 'test2', 'test2@woo.local' ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); + $request->set_query_params( + array( + 'orderby' => 'id', + ) + ); + $response = $this->server->dispatch( $request ); + $customers = $response->get_data(); + $date_created = get_date_from_gmt( date( 'Y-m-d H:i:s', strtotime( $customer_1->get_date_created() ) ) ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $customers ) ); + + $this->assertContains( + array( + 'id' => $customer_1->get_id(), + 'date_created' => wc_rest_prepare_date_response( $date_created, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $date_created ), + 'date_modified' => wc_rest_prepare_date_response( $customer_1->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_1->get_date_modified() ), + 'email' => 'test@woo.local', + 'first_name' => 'Justin', + 'last_name' => '', + 'role' => 'customer', + 'username' => 'testcustomer', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'avatar_url' => $customer_1->get_avatar_url(), + 'meta_data' => array(), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/customers/' . $customer_1->get_id() . '' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/customers' ), + ), + ), + ), + ), + $customers + ); + + update_option( 'timezone_tring', 'America/New York' ); + $customer_3 = WC_Helper_Customer::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); + $request->set_query_params( + array( + 'orderby' => 'id', + ) + ); + $response = $this->server->dispatch( $request ); + $customers = $response->get_data(); + $date_created = get_date_from_gmt( date( 'Y-m-d H:i:s', strtotime( $customer_3->get_date_created() ) ) ); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertContains( + array( + 'id' => $customer_3->get_id(), + 'date_created' => wc_rest_prepare_date_response( $date_created, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $date_created ), + 'date_modified' => wc_rest_prepare_date_response( $customer_3->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_3->get_date_modified() ), + 'email' => 'timezonetest@woo.local', + 'first_name' => 'Justin', + 'last_name' => '', + 'role' => 'customer', + 'username' => 'timezonetest', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'avatar_url' => $customer_3->get_avatar_url(), + 'meta_data' => array(), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/customers/' . $customer_3->get_id() . '' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/customers' ), + ), + ), + ), + ), + $customers + ); + + } + + /** + * Test getting customers without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_customers_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test creating a new customer. + * + * @since 3.5.0 + */ + public function test_create_customer() { + wp_set_current_user( 1 ); + + // Test just the basics first.. + $request = new WP_REST_Request( 'POST', '/wc/v3/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test', + 'password' => 'test123', + 'email' => 'create_customer_test@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'create_customer_test@woo.local', + 'first_name' => '', + 'last_name' => '', + 'role' => 'customer', + 'username' => 'create_customer_test', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + + // Test extra data. + $request = new WP_REST_Request( 'POST', '/wc/v3/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test2', + 'password' => 'test123', + 'email' => 'create_customer_test2@woo.local', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + 'billing' => array( + 'country' => 'US', + 'state' => 'WA', + ), + 'shipping' => array( + 'state' => 'CA', + 'country' => 'US', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'create_customer_test2@woo.local', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + 'role' => 'customer', + 'username' => 'create_customer_test2', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => 'WA', + 'postcode' => '', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => 'CA', + 'postcode' => '', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + + // Test without required field. + $request = new WP_REST_Request( 'POST', '/wc/v3/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test3', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating customers without valid permissions. + * + * @since 3.5.0 + */ + public function test_create_customer_without_permission() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'POST', '/wc/v3/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test_without_permission', + 'password' => 'test123', + 'email' => 'create_customer_test_without_permission@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single customer. + * + * @since 3.5.0 + */ + public function test_get_customer() { + wp_set_current_user( 1 ); + $customer = WC_Helper_Customer::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'get_customer_test@woo.local', + 'first_name' => 'Justin', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'last_name' => '', + 'role' => 'customer', + 'username' => 'get_customer_test', + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + } + + /** + * Test getting a single customer without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = WC_Helper_Customer::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single customer with an invalid ID. + * + * @since 3.5.0 + */ + public function test_get_customer_invalid_id() { + wp_set_current_user( 1 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a customer. + * + * @since 3.5.0 + */ + public function test_update_customer() { + wp_set_current_user( 1 ); + $customer = WC_Helper_Customer::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); + $data = $response->get_data(); + $this->assertEquals( 'update_customer_test', $data['username'] ); + $this->assertEquals( 'update_customer_test@woo.local', $data['email'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/customers/' . $customer->get_id() ); + $request->set_body_params( + array( + 'email' => 'updated_email@woo.local', + 'first_name' => 'UpdatedTest', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'updated_email@woo.local', $data['email'] ); + $this->assertEquals( 'UpdatedTest', $data['first_name'] ); + } + + /** + * Test updating a customer without valid permissions. + * + * @since 3.5.0 + */ + public function test_update_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = WC_Helper_Customer::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a customer with an invalid ID. + * + * @since 3.5.0 + */ + public function test_update_customer_invalid_id() { + wp_set_current_user( 1 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + + /** + * Test deleting a customer. + * + * @since 3.5.0 + */ + public function test_delete_customer() { + wp_set_current_user( 1 ); + $customer = WC_Helper_Customer::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/' . $customer->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test deleting a customer with an invalid ID. + * + * @since 3.5.0 + */ + public function test_delete_customer_invalid_id() { + wp_set_current_user( 1 ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test deleting a customer without valid permissions. + * + * @since 3.5.0 + */ + public function test_delete_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = WC_Helper_Customer::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/' . $customer->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test customer batch endpoint. + * + * @since 3.5.0 + */ + public function test_batch_customer() { + wp_set_current_user( 1 ); + + $customer_1 = WC_Helper_Customer::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); + $customer_2 = WC_Helper_Customer::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); + $customer_3 = WC_Helper_Customer::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); + $customer_4 = WC_Helper_Customer::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/customers/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $customer_1->get_id(), + 'last_name' => 'McTest', + ), + ), + 'delete' => array( + $customer_2->get_id(), + $customer_3->get_id(), + ), + 'create' => array( + array( + 'username' => 'newuser', + 'password' => 'test123', + 'email' => 'newuser@woo.local', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'McTest', $data['update'][0]['last_name'] ); + $this->assertEquals( 'newuser', $data['create'][0]['username'] ); + $this->assertEmpty( $data['create'][0]['last_name'] ); + $this->assertEquals( $customer_2->get_id(), $data['delete'][0]['id'] ); + $this->assertEquals( $customer_3->get_id(), $data['delete'][1]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Test customer schema. + * + * @since 3.5.0 + */ + public function test_customer_schema() { + wp_set_current_user( 1 ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/customers' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 16, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_created_gmt', $properties ); + $this->assertArrayHasKey( 'date_modified', $properties ); + $this->assertArrayHasKey( 'date_modified_gmt', $properties ); + $this->assertArrayHasKey( 'email', $properties ); + $this->assertArrayHasKey( 'first_name', $properties ); + $this->assertArrayHasKey( 'last_name', $properties ); + $this->assertArrayHasKey( 'role', $properties ); + $this->assertArrayHasKey( 'username', $properties ); + $this->assertArrayHasKey( 'password', $properties ); + $this->assertArrayHasKey( 'avatar_url', $properties ); + $this->assertArrayHasKey( 'billing', $properties ); + $this->assertArrayHasKey( 'first_name', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'last_name', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'company', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'address_1', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'address_2', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'city', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'state', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'postcode', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'country', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'email', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'phone', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'shipping', $properties ); + $this->assertArrayHasKey( 'first_name', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'last_name', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'company', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'address_1', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'address_2', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'city', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'state', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'postcode', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'country', $properties['shipping']['properties'] ); + } +} diff --git a/tests/Version3/functions.php b/tests/Version3/functions.php new file mode 100644 index 00000000000..6c079556341 --- /dev/null +++ b/tests/Version3/functions.php @@ -0,0 +1,251 @@ +http_responder = array( $this, 'mock_http_responses' ); + + $upload_dir_info = wp_upload_dir(); + $this->upload_dir_path = $upload_dir_info['path']; + $this->upload_dir_url = $upload_dir_info['url']; + $this->file_name = 'Dr1Bczxq4q.png'; + } + + /** + * Run tear down code for unit tests. + */ + public function tearDown() { + parent::tearDown(); + + // remove files created in the wc_rest_upload_image_from_url() tests. + $file_path = $this->upload_dir_path . '/' . $this->file_name; + + if ( file_exists( $file_path ) ) { + unlink( $file_path ); + } + } + + /** + * Test wc_rest_prepare_date_response(). + * + * @since 2.6.0 + */ + public function test_wc_rest_prepare_date_response() { + $this->assertEquals( '2016-06-06T06:06:06', wc_rest_prepare_date_response( '2016-06-06 06:06:06' ) ); + } + + /** + * Test wc_rest_upload_image_from_url() should return error when unable to download image. + */ + public function test_wc_rest_upload_image_from_url_should_return_error_when_unable_to_download_image() { + $expected_error_message = 'Error getting remote image http://somedomain.com/nonexistent-image.png. Error: Not found.'; + $result = wc_rest_upload_image_from_url( 'http://somedomain.com/nonexistent-image.png' ); + + $this->assertIsWPError( $result ); + $this->assertEquals( $expected_error_message, $result->get_error_message() ); + } + + /** + * Test wc_rest_upload_image_from_url() should return error when invalid image is passed. + * + * @requires PHP 5.4 + */ + public function test_wc_rest_upload_image_from_url_should_return_error_when_invalid_image_is_passed() { + // empty file. + $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; + $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-1.png' ); + + $this->assertIsWPError( $result ); + $this->assertEquals( $expected_error_message, $result->get_error_message() ); + + // unsupported mime type. + $expected_error_message = 'Invalid image: Sorry, this file type is not permitted for security reasons.'; + $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-2.png' ); + + $this->assertIsWPError( $result ); + $this->assertEquals( $expected_error_message, $result->get_error_message() ); + } + + /** + * Test wc_rest_upload_image_from_url() should download image and return an array containing + * information about it. + * + * @requires PHP 5.4 + */ + public function test_wc_rest_upload_image_from_url_should_download_image_and_return_array() { + $expected_result = array( + 'file' => $this->upload_dir_path . '/' . $this->file_name, + 'url' => $this->upload_dir_url . '/' . $this->file_name, + 'type' => 'image/png', + ); + $result = wc_rest_upload_image_from_url( 'http://somedomain.com/' . $this->file_name ); + + $this->assertEquals( $expected_result, $result ); + } + + /** + * Test wc_rest_set_uploaded_image_as_attachment(). + * + * @since 2.6.0 + */ + public function test_wc_rest_set_uploaded_image_as_attachment() { + $this->assertInternalType( + 'int', + wc_rest_set_uploaded_image_as_attachment( + array( + 'file' => '', + 'url' => '', + ) + ) + ); + } + + /** + * Test wc_rest_validate_reports_request_arg(). + * + * @since 2.6.0 + */ + public function test_wc_rest_validate_reports_request_arg() { + $request = new WP_REST_Request( + 'GET', + '/wc/v3/foo', + array( + 'args' => array( + 'date' => array( + 'type' => 'string', + 'format' => 'date', + ), + ), + ) + ); + + // Success. + $this->assertTrue( wc_rest_validate_reports_request_arg( '2016-06-06', $request, 'date' ) ); + + // Error. + $error = wc_rest_validate_reports_request_arg( 'foo', $request, 'date' ); + $this->assertEquals( 'The date you provided is invalid.', $error->get_error_message() ); + } + + /** + * Test wc_rest_urlencode_rfc3986(). + * + * @since 2.6.0 + */ + public function test_wc_rest_urlencode_rfc3986() { + $this->assertEquals( 'https%3A%2F%2Fwoocommerce.com%2F', wc_rest_urlencode_rfc3986( 'https://woocommerce.com/' ) ); + } + + /** + * Test wc_rest_check_post_permissions(). + * + * @since 2.6.0 + */ + public function test_wc_rest_check_post_permissions() { + $this->assertFalse( wc_rest_check_post_permissions( 'shop_order' ) ); + } + + /** + * Test wc_rest_check_user_permissions(). + * + * @since 2.6.0 + */ + public function test_wc_rest_check_user_permissions() { + $this->assertFalse( wc_rest_check_user_permissions() ); + } + + /** + * Test wc_rest_check_product_term_permissions(). + * + * @since 2.6.0 + */ + public function test_wc_rest_check_product_term_permissions() { + $this->assertFalse( wc_rest_check_product_term_permissions( 'product_cat' ) ); + } + + /** + * Test wc_rest_check_manager_permissions(). + * + * @since 2.6.0 + */ + public function test_wc_rest_check_manager_permissions() { + $this->assertFalse( wc_rest_check_manager_permissions( 'reports' ) ); + } + + /** + * Helper method to define mocked HTTP responses using WP_HTTP_TestCase. + * Thanks to WP_HTTP_TestCase, it is not necessary to perform a regular request + * to an external server which would significantly slow down the tests. + * + * This function is called by WP_HTTP_TestCase::http_request_listner(). + * + * @param array $request Request arguments. + * @param string $url URL of the request. + * + * @return array|false mocked response or false to let WP perform a regular request. + */ + protected function mock_http_responses( $request, $url ) { + $mocked_response = false; + + if ( 'http://somedomain.com/nonexistent-image.png' === $url ) { + $mocked_response = array( + 'response' => array( + 'code' => 404, + 'message' => 'Not found.', + ), + ); + } elseif ( 'http://somedomain.com/invalid-image-1.png' === $url ) { + // empty image. + $mocked_response = array( + 'response' => array( 'code' => 200 ), + ); + } elseif ( 'http://somedomain.com/invalid-image-2.png' === $url ) { + // image with an unsupported mime type. + // we need to manually copy the file as we are mocking the request. without this an empty file is created. + copy( WC_Unit_Tests_Bootstrap::instance()->tests_dir . '/data/file.txt', $request['filename'] ); + + $mocked_response = array( + 'response' => array( 'code' => 200 ), + ); + } elseif ( 'http://somedomain.com/' . $this->file_name === $url ) { + // we need to manually copy the file as we are mocking the request. without this an empty file is created. + copy( WC_Unit_Tests_Bootstrap::instance()->tests_dir . '/data/Dr1Bczxq4q.png', $request['filename'] ); + + $mocked_response = array( + 'response' => array( 'code' => 200 ), + ); + } + + return $mocked_response; + } +} diff --git a/tests/Version3/orders.php b/tests/Version3/orders.php new file mode 100644 index 00000000000..d34a97bb80d --- /dev/null +++ b/tests/Version3/orders.php @@ -0,0 +1,665 @@ +endpoint = new WC_REST_Orders_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/orders', $routes ); + $this->assertArrayHasKey( '/wc/v3/orders/batch', $routes ); + $this->assertArrayHasKey( '/wc/v3/orders/(?P[\d]+)', $routes ); + } + + /** + * Test getting all orders. + * @since 3.5.0 + */ + public function test_get_items() { + wp_set_current_user( $this->user ); + + // Create 10 orders. + for ( $i = 0; $i < 10; $i++ ) { + $this->orders[] = WC_Helper_Order::create_order( $this->user ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders' ) ); + $orders = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 10, count( $orders ) ); + } + + /** + * Tests to make sure orders cannot be viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_items_without_permission() { + wp_set_current_user( 0 ); + $this->orders[] = WC_Helper_Order::create_order(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a single order. + * @since 3.5.0 + */ + public function test_get_item() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $order->add_meta_data( 'key', 'value' ); + $order->add_meta_data( 'key2', 'value2' ); + $order->save(); + $this->orders[] = $order; + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $order->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $order->get_id(), $data['id'] ); + + // Test meta data is set. + $this->assertEquals( 'key', $data['meta_data'][0]->key ); + $this->assertEquals( 'value', $data['meta_data'][0]->value ); + $this->assertEquals( 'key2', $data['meta_data'][1]->key ); + $this->assertEquals( 'value2', $data['meta_data'][1]->value ); + } + + /** + * Tests getting a single order without the correct permissions. + * @since 3.5.0 + */ + public function test_get_item_without_permission() { + wp_set_current_user( 0 ); + $order = WC_Helper_Order::create_order(); + $this->orders[] = $order; + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $order->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting an order with an invalid ID. + * @since 3.5.0 + */ + public function test_get_item_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/99999999' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests getting an order with an invalid ID. + * @since 3.5.0 + */ + public function test_get_item_refund_id() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $refund = wc_create_refund( + array( + 'order_id' => $order->get_id(), + ) + ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $refund->get_id() ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests creating an order. + * @since 3.5.0 + */ + public function test_create_order() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); + $request->set_body_params( + array( + 'payment_method' => 'bacs', + 'payment_method_title' => 'Direct Bank Transfer', + 'set_paid' => true, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => '10', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $order = wc_get_order( $data['id'] ); + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); + $this->assertEquals( $order->get_payment_method_title(), $data['payment_method_title'] ); + $this->assertEquals( $order->get_billing_first_name(), $data['billing']['first_name'] ); + $this->assertEquals( $order->get_billing_last_name(), $data['billing']['last_name'] ); + $this->assertEquals( '', $data['billing']['company'] ); + $this->assertEquals( $order->get_billing_address_1(), $data['billing']['address_1'] ); + $this->assertEquals( $order->get_billing_address_2(), $data['billing']['address_2'] ); + $this->assertEquals( $order->get_billing_city(), $data['billing']['city'] ); + $this->assertEquals( $order->get_billing_state(), $data['billing']['state'] ); + $this->assertEquals( $order->get_billing_postcode(), $data['billing']['postcode'] ); + $this->assertEquals( $order->get_billing_country(), $data['billing']['country'] ); + $this->assertEquals( $order->get_billing_email(), $data['billing']['email'] ); + $this->assertEquals( $order->get_billing_phone(), $data['billing']['phone'] ); + $this->assertEquals( $order->get_shipping_first_name(), $data['shipping']['first_name'] ); + $this->assertEquals( $order->get_shipping_last_name(), $data['shipping']['last_name'] ); + $this->assertEquals( '', $data['shipping']['company'] ); + $this->assertEquals( $order->get_shipping_address_1(), $data['shipping']['address_1'] ); + $this->assertEquals( $order->get_shipping_address_2(), $data['shipping']['address_2'] ); + $this->assertEquals( $order->get_shipping_city(), $data['shipping']['city'] ); + $this->assertEquals( $order->get_shipping_state(), $data['shipping']['state'] ); + $this->assertEquals( $order->get_shipping_postcode(), $data['shipping']['postcode'] ); + $this->assertEquals( $order->get_shipping_country(), $data['shipping']['country'] ); + $this->assertEquals( 1, count( $data['line_items'] ) ); + $this->assertEquals( 1, count( $data['shipping_lines'] ) ); + } + + /** + * Test the sanitization of the payment_method_title field through the API. + * + * @since 3.5.2 + */ + public function test_create_update_order_payment_method_title_sanitize() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + // Test when creating order. + $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); + $request->set_body_params( + array( + 'payment_method' => 'bacs', + 'payment_method_title' => '

Sanitize this

', + 'set_paid' => true, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => '10', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $order = wc_get_order( $data['id'] ); + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); + $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this' ); + + // Test when updating order. + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $data['id'] ); + $request->set_body_params( + array( + 'payment_method' => 'bacs', + 'payment_method_title' => '

Sanitize this too

', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $order = wc_get_order( $data['id'] ); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); + $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this too' ); + } + + /** + * Tests creating an order without required fields. + * @since 3.5.0 + */ + public function test_create_order_invalid_fields() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + // Non-existent customer. + $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); + $request->set_body_params( + array( + 'payment_method' => 'bacs', + 'payment_method_title' => 'Direct Bank Transfer', + 'set_paid' => true, + 'customer_id' => 99999, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => 10, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Tests updating an order. + * + * @since 3.5.0 + */ + public function test_update_order() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); + $request->set_body_params( + array( + 'payment_method' => 'test-update', + 'billing' => array( + 'first_name' => 'Fish', + 'last_name' => 'Face', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'test-update', $data['payment_method'] ); + $this->assertEquals( 'Fish', $data['billing']['first_name'] ); + $this->assertEquals( 'Face', $data['billing']['last_name'] ); + } + + /** + * Tests updating an order and removing items. + * + * @since 3.5.0 + */ + public function test_update_order_remove_items() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $fee = new WC_Order_Item_Fee(); + $fee->set_props( + array( + 'name' => 'Some Fee', + 'tax_status' => 'taxable', + 'total' => '100', + 'tax_class' => '', + ) + ); + $order->add_item( $fee ); + $order->save(); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); + $fee_data = current( $order->get_items( 'fee' ) ); + + $request->set_body_params( + array( + 'fee_lines' => array( + array( + 'id' => $fee_data->get_id(), + 'name' => null, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertTrue( empty( $data['fee_lines'] ) ); + } + + /** + * Tests updating an order and adding a coupon. + * + * @since 3.5.0 + */ + public function test_update_order_add_coupons() { + wp_set_current_user( $this->user ); + + $order = WC_Helper_Order::create_order(); + $order_item = current( $order->get_items() ); + $coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon->set_amount( 5 ); + $coupon->save(); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); + $request->set_body_params( + array( + 'coupon_lines' => array( + array( + 'code' => 'fake-coupon', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $data['coupon_lines'] ); + $this->assertEquals( '45.00', $data['total'] ); + } + + /** + * Tests updating an order and removing a coupon. + * + * @since 3.5.0 + */ + public function test_update_order_remove_coupons() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $order_item = current( $order->get_items() ); + $coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon->set_amount( 5 ); + $coupon->save(); + + $order->apply_coupon( $coupon ); + $order->save(); + + // Check that the coupon is applied. + $this->assertEquals( '45.00', $order->get_total() ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); + $coupon_data = current( $order->get_items( 'coupon' ) ); + + $request->set_body_params( + array( + 'coupon_lines' => array( + array( + 'id' => $coupon_data->get_id(), + 'code' => null, + ), + ), + 'line_items' => array( + array( + 'id' => $order_item->get_id(), + 'product_id' => $order_item->get_product_id(), + 'total' => '40.00', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertTrue( empty( $data['coupon_lines'] ) ); + $this->assertEquals( '50.00', $data['total'] ); + } + + /** + * Tests updating an order with an invalid coupon. + * + * @since 3.5.0 + */ + public function test_invalid_coupon() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); + + $request->set_body_params( + array( + 'coupon_lines' => array( + array( + 'code' => 'NON_EXISTING_COUPON', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + $this->assertEquals( 'woocommerce_rest_invalid_coupon', $data['code'] ); + $this->assertEquals( 'Coupon "non_existing_coupon" does not exist!', $data['message'] ); + } + + /** + * Tests updating an order without the correct permissions. + * + * @since 3.5.0 + */ + public function test_update_order_without_permission() { + wp_set_current_user( 0 ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); + $request->set_body_params( + array( + 'payment_method' => 'test-update', + 'billing' => array( + 'first_name' => 'Fish', + 'last_name' => 'Face', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests that updating an order with an invalid id fails. + * + * @since 3.5.0 + */ + public function test_update_order_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'POST', '/wc/v3/orders/999999' ); + $request->set_body_params( + array( + 'payment_method' => 'test-update', + 'billing' => array( + 'first_name' => 'Fish', + 'last_name' => 'Face', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test deleting an order. + * + * @since 3.5.0 + */ + public function test_delete_order() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/' . $order->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( null, get_post( $order->get_id() ) ); + } + + /** + * Test deleting an order without permission/creds. + * + * @since 3.5.0 + */ + public function test_delete_order_without_permission() { + wp_set_current_user( 0 ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/' . $order->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting an order with an invalid id. + * + * @since 3.5.0 + */ + public function test_delete_order_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/9999999' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test batch managing product reviews. + * + * @since 3.5.0 + */ + public function test_orders_batch() { + wp_set_current_user( $this->user ); + + $order1 = WC_Helper_Order::create_order(); + $order2 = WC_Helper_Order::create_order(); + $order3 = WC_Helper_Order::create_order(); + + $request = new WP_REST_Request( 'POST', '/wc/v3/orders/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $order1->get_id(), + 'payment_method' => 'updated', + ), + ), + 'delete' => array( + $order2->get_id(), + $order3->get_id(), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'updated', $data['update'][0]['payment_method'] ); + $this->assertEquals( $order2->get_id(), $data['delete'][0]['id'] ); + $this->assertEquals( $order3->get_id(), $data['delete'][1]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/orders' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 1, count( $data ) ); + } + + /** + * Test the order schema. + * + * @since 3.5.0 + */ + public function test_order_schema() { + wp_set_current_user( $this->user ); + $order = WC_Helper_Order::create_order(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/orders/' . $order->get_id() ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 42, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + } +} diff --git a/tests/Version3/payment-gateways.php b/tests/Version3/payment-gateways.php new file mode 100644 index 00000000000..f9a43b64e5f --- /dev/null +++ b/tests/Version3/payment-gateways.php @@ -0,0 +1,345 @@ +endpoint = new WC_REST_Payment_Gateways_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/payment_gateways', $routes ); + $this->assertArrayHasKey( '/wc/v3/payment_gateways/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all payment gateways. + * + * @since 3.5.0 + */ + public function test_get_payment_gateways() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways' ) ); + $gateways = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( + array( + 'id' => 'cheque', + 'title' => 'Check payments', + 'description' => 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', + 'order' => '', + 'enabled' => false, + 'method_title' => 'Check payments', + 'method_description' => 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', + 'method_supports' => array( + 'products', + ), + 'settings' => array_diff_key( + $this->get_settings( 'WC_Gateway_Cheque' ), + array( + 'enabled' => false, + 'description' => false, + ) + ), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/payment_gateways/cheque' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/payment_gateways' ), + ), + ), + ), + ), + $gateways + ); + } + + /** + * Tests to make sure payment gateways cannot viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_payment_gateways_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single payment gateway. + * + * @since 3.5.0 + */ + public function test_get_payment_gateway() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/paypal' ) ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => 'paypal', + 'title' => 'PayPal', + 'description' => "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account.", + 'order' => '', + 'enabled' => false, + 'method_title' => 'PayPal', + 'method_description' => 'PayPal Standard redirects customers to PayPal to enter their payment information.', + 'method_supports' => array( + 'products', + 'refunds', + ), + 'settings' => array_diff_key( + $this->get_settings( 'WC_Gateway_Paypal' ), + array( + 'enabled' => false, + 'description' => false, + ) + ), + ), + $paypal + ); + } + + /** + * Test getting a payment gateway without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_payment_gateway_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/paypal' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a payment gateway with an invalid id. + * + * @since 3.5.0 + */ + public function test_get_payment_gateway_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/totally_fake_method' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a single payment gateway. + * + * @since 3.5.0 + */ + public function test_update_payment_gateway() { + wp_set_current_user( $this->user ); + + // Test defaults + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/paypal' ) ); + $paypal = $response->get_data(); + + $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'admin@example.org', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); + + // test updating single setting + $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'email' => 'woo@woo.local', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); + + // test updating multiple settings + $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'testmode' => 'yes', + 'title' => 'PayPal - New Title', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); + + // Test other parameters, and recheck settings + $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertFalse( $paypal['enabled'] ); + $this->assertEquals( 2, $paypal['order'] ); + $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); + + // test bogus + $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'paymentaction' => 'afasfasf', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'paymentaction' => 'authorization', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + $this->assertEquals( 'authorization', $paypal['settings']['paymentaction']['value'] ); + } + + /** + * Test updating a payment gateway without valid permissions. + * + * @since 3.5.0 + */ + public function test_update_payment_gateway_without_permission() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'testmode' => 'yes', + 'title' => 'PayPal - New Title', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a payment gateway with an invalid id. + * + * @since 3.5.0 + */ + public function test_update_payment_gateway_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/totally_fake_method' ); + $request->set_body_params( + array( + 'enabled' => true, + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test the payment gateway schema. + * + * @since 3.5.0 + */ + public function test_payment_gateway_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/payment_gateways' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 9, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'title', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'order', $properties ); + $this->assertArrayHasKey( 'enabled', $properties ); + $this->assertArrayHasKey( 'method_title', $properties ); + $this->assertArrayHasKey( 'method_description', $properties ); + $this->assertArrayHasKey( 'method_supports', $properties ); + $this->assertArrayHasKey( 'settings', $properties ); + } + + /** + * Loads a particular gateway's settings so we can correctly test API output. + * + * @since 3.5.0 + * @param string $gateway_class Name of WC_Payment_Gateway class. + */ + private function get_settings( $gateway_class ) { + $gateway = new $gateway_class(); + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + // Ignore 'enabled' and 'description', to be in line with \WC_REST_Payment_Gateways_Controller::get_settings. + if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { + continue; + } + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + +} diff --git a/tests/Version3/product-reviews.php b/tests/Version3/product-reviews.php new file mode 100644 index 00000000000..f34fd15626c --- /dev/null +++ b/tests/Version3/product-reviews.php @@ -0,0 +1,470 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/products/reviews', $routes ); + $this->assertArrayHasKey( '/wc/v3/products/reviews/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/products/reviews/batch', $routes ); + } + + /** + * Test getting all product reviews. + * + * @since 3.5.0 + */ + public function test_get_product_reviews() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + // Create 10 products reviews for the product + for ( $i = 0; $i < 10; $i++ ) { + $review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); + $product_reviews = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 10, count( $product_reviews ) ); + $this->assertContains( + array( + 'id' => $review_id, + 'date_created' => $product_reviews[0]['date_created'], + 'date_created_gmt' => $product_reviews[0]['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => "

Review content here

\n", + 'rating' => 0, + 'verified' => false, + 'reviewer_avatar_urls' => $product_reviews[0]['reviewer_avatar_urls'], + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/products/reviews/' . $review_id ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/products/reviews' ), + ), + ), + 'up' => array( + array( + 'href' => rest_url( '/wc/v3/products/' . $product->get_id() ), + ), + ), + ), + ), + $product_reviews + ); + } + + /** + * Tests to make sure product reviews cannot be viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_product_reviews_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests to make sure an error is returned when an invalid product is loaded. + * + * @since 3.5.0 + */ + public function test_get_product_reviews_invalid_product() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/0/reviews' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests getting a single product review. + * + * @since 3.5.0 + */ + public function test_get_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $product_review_id, + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => "

Review content here

\n", + 'rating' => 0, + 'verified' => false, + 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], + ), + $data + ); + } + + /** + * Tests getting a single product review without the correct permissions. + * + * @since 3.5.0 + */ + public function test_get_product_review_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a product review with an invalid ID. + * + * @since 3.5.0 + */ + public function test_get_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests creating a product review. + * + * @since 3.5.0 + */ + public function test_create_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + 'rating' => '5', + 'product_id' => $product->get_id(), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => 'Hello world.', + 'rating' => 5, + 'verified' => false, + 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], + ), + $data + ); + } + + /** + * Tests creating a product review without required fields. + * + * @since 3.5.0 + */ + public function test_create_product_review_invalid_fields() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + // missing review + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); + $request->set_body_params( + array( + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + + // Missing reviewer. + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer_email' => 'woo@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + + // missing reviewer_email + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Tests updating a product review. + * + * @since 3.5.0 + */ + public function test_update_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); + $data = $response->get_data(); + $this->assertEquals( "

Review content here

\n", $data['review'] ); + $this->assertEquals( 'admin', $data['reviewer'] ); + $this->assertEquals( 'woo@woo.local', $data['reviewer_email'] ); + $this->assertEquals( 0, $data['rating'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); + $request->set_body_params( + array( + 'review' => 'Hello world - updated.', + 'reviewer' => 'Justin', + 'reviewer_email' => 'woo2@woo.local', + 'rating' => 3, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'Hello world - updated.', $data['review'] ); + $this->assertEquals( 'Justin', $data['reviewer'] ); + $this->assertEquals( 'woo2@woo.local', $data['reviewer_email'] ); + $this->assertEquals( 3, $data['rating'] ); + } + + /** + * Tests updating a product review without the correct permissions. + * + * @since 3.5.0 + */ + public function test_update_product_review_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.dev', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests that updating a product review with an invalid id fails. + * + * @since 3.5.0 + */ + public function test_update_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/0' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.dev', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test deleting a product review. + * + * @since 3.5.0 + */ + public function test_delete_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test deleting a product review without permission/creds. + * + * @since 3.5.0 + */ + public function test_delete_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a product review with an invalid id. + * + * @since 3.5.0 + */ + public function test_delete_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test batch managing product reviews. + * + * @since 3.5.0 + */ + public function test_product_reviews_batch() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $review_1_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_2_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_3_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_4_id = WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $review_1_id, + 'review' => 'Updated review.', + ), + ), + 'delete' => array( + $review_2_id, + $review_3_id, + ), + 'create' => array( + array( + 'review' => 'New review.', + 'reviewer' => 'Justin', + 'reviewer_email' => 'woo3@woo.local', + 'product_id' => $product->get_id(), + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'Updated review.', $data['update'][0]['review'] ); + $this->assertEquals( 'New review.', $data['create'][0]['review'] ); + $this->assertEquals( $review_2_id, $data['delete'][0]['previous']['id'] ); + $this->assertEquals( $review_3_id, $data['delete'][1]['previous']['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ); + $request->set_param( 'product', $product->get_id() ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Test the product review schema. + * + * @since 3.5.0 + */ + public function test_product_review_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/reviews' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 11, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_created_gmt', $properties ); + $this->assertArrayHasKey( 'product_id', $properties ); + $this->assertArrayHasKey( 'status', $properties ); + $this->assertArrayHasKey( 'reviewer', $properties ); + $this->assertArrayHasKey( 'reviewer_email', $properties ); + $this->assertArrayHasKey( 'review', $properties ); + $this->assertArrayHasKey( 'rating', $properties ); + $this->assertArrayHasKey( 'verified', $properties ); + + if ( get_option( 'show_avatars' ) ) { + $this->assertArrayHasKey( 'reviewer_avatar_urls', $properties ); + } + } +} diff --git a/tests/Version3/product-variations.php b/tests/Version3/product-variations.php new file mode 100644 index 00000000000..ab1b810be43 --- /dev/null +++ b/tests/Version3/product-variations.php @@ -0,0 +1,474 @@ +endpoint = new WC_REST_Product_Variations_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/products/(?P[\d]+)/variations', $routes ); + $this->assertArrayHasKey( '/wc/v3/products/(?P[\d]+)/variations/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/products/(?P[\d]+)/variations/batch', $routes ); + } + + /** + * Test getting variations. + * + * @since 3.5.0 + */ + public function test_get_variations() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $variations ) ); + $this->assertEquals( 'DUMMY SKU VARIABLE LARGE', $variations[0]['sku'] ); + $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); + } + + /** + * Test getting variations without permission. + * + * @since 3.5.0 + */ + public function test_get_variations_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single variation. + * + * @since 3.5.0 + */ + public function test_get_variation() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $variation_id, $variation['id'] ); + $this->assertEquals( 'size', $variation['attributes'][0]['name'] ); + } + + /** + * Test getting single variation without permission. + * + * @since 3.5.0 + */ + public function test_get_variation_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single variation. + * + * @since 3.5.0 + */ + public function test_delete_variation() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 1, count( $variations ) ); + } + + /** + * Test deleting a single variation without permission. + * + * @since 3.5.0 + */ + public function test_delete_variation_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single variation with an invalid ID. + * + * @since 3.5.0 + */ + public function test_delete_variation_with_invalid_id() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() . '/variations/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test editing a single variation. + * + * @since 3.5.0 + */ + public function test_update_variation() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $variation = $response->get_data(); + + $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variation['sku'] ); + $this->assertEquals( 10, $variation['regular_price'] ); + $this->assertEmpty( $variation['sale_price'] ); + $this->assertEquals( 'small', $variation['attributes'][0]['option'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'sku' => 'FIXED-\'SKU', + 'sale_price' => '8', + 'description' => 'O_O', + 'image' => array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertTrue( isset( $variation['description'] ), print_r( $variation, true ) ); + $this->assertContains( 'O_O', $variation['description'], print_r( $variation, true ) ); + $this->assertEquals( '8', $variation['price'], print_r( $variation, true ) ); + $this->assertEquals( '8', $variation['sale_price'], print_r( $variation, true ) ); + $this->assertEquals( '10', $variation['regular_price'], print_r( $variation, true ) ); + $this->assertEquals( 'FIXED-\'SKU', $variation['sku'], print_r( $variation, true ) ); + $this->assertEquals( 'medium', $variation['attributes'][0]['option'], print_r( $variation, true ) ); + $this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'], print_r( $variation, true ) ); + $this->assertContains( 'test upload image', $variation['image']['alt'], print_r( $variation, true ) ); + } + + /** + * Test updating a single variation without permission. + * + * @since 3.5.0 + */ + public function test_update_variation_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single variation with an invalid ID. + * + * @since 3.5.0 + */ + public function test_update_variation_with_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/0' ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating a single variation. + * + * @since 3.5.0 + */ + public function test_create_variation() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 2, count( $variations ) ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations' ); + $request->set_body_params( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertContains( 'A medium size.', $variation['description'] ); + $this->assertEquals( '12', $variation['price'] ); + $this->assertEquals( '12', $variation['regular_price'] ); + $this->assertTrue( $variation['purchasable'] ); + $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $variation['sku'] ); + $this->assertEquals( 'medium', $variation['attributes'][0]['option'] ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 3, count( $variations ) ); + } + + /** + * Test creating a single variation without permission. + * + * @since 3.5.0 + */ + public function test_create_variation_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_variation_product(); + + $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations' ); + $request->set_body_params( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch managing product variations. + * + * @since 3.5.0 + */ + public function test_product_variations_batch() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_variation_product(); + $children = $product->get_children(); + $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $children[0], + 'description' => 'Updated description.', + 'image' => array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + ), + ), + 'delete' => array( + $children[1], + ), + 'create' => array( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); + $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $data['create'][0]['sku'] ); + $this->assertEquals( 'medium', $data['create'][0]['attributes'][0]['option'] ); + $this->assertEquals( $children[1], $data['delete'][0]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 2, count( $data ) ); + } + + /** + * Test variation schema. + * + * @since 3.5.0 + */ + public function test_variation_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() . '/variations' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 37, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_modified', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'permalink', $properties ); + $this->assertArrayHasKey( 'sku', $properties ); + $this->assertArrayHasKey( 'price', $properties ); + $this->assertArrayHasKey( 'regular_price', $properties ); + $this->assertArrayHasKey( 'sale_price', $properties ); + $this->assertArrayHasKey( 'date_on_sale_from', $properties ); + $this->assertArrayHasKey( 'date_on_sale_to', $properties ); + $this->assertArrayHasKey( 'on_sale', $properties ); + $this->assertArrayHasKey( 'purchasable', $properties ); + $this->assertArrayHasKey( 'virtual', $properties ); + $this->assertArrayHasKey( 'downloadable', $properties ); + $this->assertArrayHasKey( 'downloads', $properties ); + $this->assertArrayHasKey( 'download_limit', $properties ); + $this->assertArrayHasKey( 'download_expiry', $properties ); + $this->assertArrayHasKey( 'tax_status', $properties ); + $this->assertArrayHasKey( 'tax_class', $properties ); + $this->assertArrayHasKey( 'manage_stock', $properties ); + $this->assertArrayHasKey( 'stock_quantity', $properties ); + $this->assertArrayHasKey( 'stock_status', $properties ); + $this->assertArrayHasKey( 'backorders', $properties ); + $this->assertArrayHasKey( 'backorders_allowed', $properties ); + $this->assertArrayHasKey( 'backordered', $properties ); + $this->assertArrayHasKey( 'weight', $properties ); + $this->assertArrayHasKey( 'dimensions', $properties ); + $this->assertArrayHasKey( 'shipping_class', $properties ); + $this->assertArrayHasKey( 'shipping_class_id', $properties ); + $this->assertArrayHasKey( 'image', $properties ); + $this->assertArrayHasKey( 'attributes', $properties ); + $this->assertArrayHasKey( 'menu_order', $properties ); + $this->assertArrayHasKey( 'meta_data', $properties ); + } + + /** + * Test updating a variation stock. + * + * @since 3.5.0 + */ + public function test_update_variation_manage_stock() { + wp_set_current_user( $this->user ); + + $product = WC_Helper_Product::create_variation_product(); + $product->set_manage_stock( false ); + $product->save(); + + $children = $product->get_children(); + $variation_id = $children[0]; + + // Set stock to true. + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => true, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( true, $variation['manage_stock'] ); + + // Set stock to false. + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => false, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( false, $variation['manage_stock'] ); + + // Set stock to false but parent is managing stock. + $product->set_manage_stock( true ); + $product->save(); + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => false, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'parent', $variation['manage_stock'] ); + } +} diff --git a/tests/Version3/products.php b/tests/Version3/products.php new file mode 100644 index 00000000000..6b8cff59db2 --- /dev/null +++ b/tests/Version3/products.php @@ -0,0 +1,807 @@ +endpoint = new WC_REST_Products_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/products', $routes ); + $this->assertArrayHasKey( '/wc/v3/products/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/products/batch', $routes ); + } + + /** + * Test getting products. + * + * @since 3.5.0 + */ + public function test_get_products() { + wp_set_current_user( $this->user ); + WC_Helper_Product::create_external_product(); + sleep( 1 ); // So both products have different timestamps. + WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 2, count( $products ) ); + $this->assertEquals( 'Dummy Product', $products[0]['name'] ); + $this->assertEquals( 'DUMMY SKU', $products[0]['sku'] ); + $this->assertEquals( 'Dummy External Product', $products[1]['name'] ); + $this->assertEquals( 'DUMMY EXTERNAL SKU', $products[1]['sku'] ); + } + + /** + * Test getting products without permission. + * + * @since 3.5.0 + */ + public function test_get_products_without_permission() { + wp_set_current_user( 0 ); + WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single product. + * + * @since 3.5.0 + */ + public function test_get_product() { + wp_set_current_user( $this->user ); + $simple = WC_Helper_Product::create_external_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $simple->get_id() ) ); + $product = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( + array( + 'id' => $simple->get_id(), + 'name' => 'Dummy External Product', + 'type' => 'simple', + 'status' => 'publish', + 'sku' => 'DUMMY EXTERNAL SKU', + 'regular_price' => 10, + ), + $product + ); + } + + /** + * Test getting single product without permission. + * + * @since 3.5.0 + */ + public function test_get_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single product. + * + * @since 3.5.0 + */ + public function test_delete_product() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); + $variations = $response->get_data(); + $this->assertEquals( 0, count( $variations ) ); + } + + /** + * Test deleting a single product without permission. + * + * @since 3.5.0 + */ + public function test_delete_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single product with an invalid ID. + * + * @since 3.5.0 + */ + public function test_delete_product_with_invalid_id() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test editing a single product. Tests multiple product types. + * + * @since 3.5.0 + */ + public function test_update_product() { + wp_set_current_user( $this->user ); + + // test simple products. + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); + $data = $response->get_data(); + $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); + + $this->assertEquals( 'DUMMY SKU', $data['sku'] ); + $this->assertEquals( 10, $data['regular_price'] ); + $this->assertEmpty( $data['sale_price'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU', + 'sale_price' => '8', + 'description' => 'Testing', + 'date_created' => $date_created, + 'images' => array( + array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Testing', $data['description'] ); + $this->assertEquals( '8', $data['price'] ); + $this->assertEquals( '8', $data['sale_price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertEquals( 'FIXED-SKU', $data['sku'] ); + $this->assertEquals( $date_created, $data['date_created'] ); + $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); + $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); + $product->delete( true ); + + // test variable product (variations are tested in product-variations.php). + $product = WC_Helper_Product::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); + $data = $response->get_data(); + + foreach ( array( 'small', 'large' ) as $term_name ) { + $this->assertContains( $term_name, $data['attributes'][0]['options'] ); + } + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'attributes' => array( + array( + 'id' => 0, + 'name' => 'pa_color', + 'options' => array( + 'red', + 'yellow', + ), + 'visible' => false, + 'variation' => 1, + ), + array( + 'id' => 0, + 'name' => 'pa_size', + 'options' => array( + 'small', + ), + 'visible' => false, + 'variation' => 1, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( array( 'small' ), $data['attributes'][0]['options'] ); + + foreach ( array( 'red', 'yellow' ) as $term_name ) { + $this->assertContains( $term_name, $data['attributes'][1]['options'] ); + } + + $product->delete( true ); + + // test external product. + $product = WC_Helper_Product::create_external_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 'Buy external product', $data['button_text'] ); + $this->assertEquals( 'http://woocommerce.com', $data['external_url'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'button_text' => 'Test API Update', + 'external_url' => 'http://automattic.com', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'Test API Update', $data['button_text'] ); + $this->assertEquals( 'http://automattic.com', $data['external_url'] ); + } + + /** + * Test updating a single product without permission. + * + * @since 3.5.0 + */ + public function test_update_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single product with an invalid ID. + * + * @since 3.5.0 + */ + public function test_update_product_with_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-INVALID-ID', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating a single product. + * + * @since 3.5.0 + */ + public function test_create_product() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/products/shipping_classes' ); + $request->set_body_params( + array( + 'name' => 'Test', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $shipping_class_id = $data['id']; + + // Create simple. + $request = new WP_REST_Request( 'POST', '/wc/v3/products' ); + $request->set_body_params( + array( + 'type' => 'simple', + 'name' => 'Test Simple Product', + 'sku' => 'DUMMY SKU SIMPLE API', + 'regular_price' => '10', + 'shipping_class' => 'test', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '10', $data['price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertTrue( $data['purchasable'] ); + $this->assertEquals( 'DUMMY SKU SIMPLE API', $data['sku'] ); + $this->assertEquals( 'Test Simple Product', $data['name'] ); + $this->assertEquals( 'simple', $data['type'] ); + $this->assertEquals( $shipping_class_id, $data['shipping_class_id'] ); + + // Create external. + $request = new WP_REST_Request( 'POST', '/wc/v3/products' ); + $request->set_body_params( + array( + 'type' => 'external', + 'name' => 'Test External Product', + 'sku' => 'DUMMY SKU EXTERNAL API', + 'regular_price' => '10', + 'button_text' => 'Test Button', + 'external_url' => 'https://wordpress.org', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '10', $data['price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertFalse( $data['purchasable'] ); + $this->assertEquals( 'DUMMY SKU EXTERNAL API', $data['sku'] ); + $this->assertEquals( 'Test External Product', $data['name'] ); + $this->assertEquals( 'external', $data['type'] ); + $this->assertEquals( 'Test Button', $data['button_text'] ); + $this->assertEquals( 'https://wordpress.org', $data['external_url'] ); + + // Create variable. + $request = new WP_REST_Request( 'POST', '/wc/v3/products' ); + $request->set_body_params( + array( + 'type' => 'variable', + 'name' => 'Test Variable Product', + 'sku' => 'DUMMY SKU VARIABLE API', + 'attributes' => array( + array( + 'id' => 0, + 'name' => 'pa_size', + 'options' => array( + 'small', + 'medium', + ), + 'visible' => false, + 'variation' => 1, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'DUMMY SKU VARIABLE API', $data['sku'] ); + $this->assertEquals( 'Test Variable Product', $data['name'] ); + $this->assertEquals( 'variable', $data['type'] ); + $this->assertEquals( array( 'small', 'medium' ), $data['attributes'][0]['options'] ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); + $products = $response->get_data(); + $this->assertEquals( 3, count( $products ) ); + } + + /** + * Test creating a single product without permission. + * + * @since 3.5.0 + */ + public function test_create_product_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/products' ); + $request->set_body_params( + array( + 'name' => 'Test Product', + 'regular_price' => '12', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch managing products. + * + * @since 3.5.0 + */ + public function test_products_batch() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_2 = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'POST', '/wc/v3/products/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $product->get_id(), + 'description' => 'Updated description.', + ), + ), + 'delete' => array( + $product_2->get_id(), + ), + 'create' => array( + array( + 'sku' => 'DUMMY SKU BATCH TEST 1', + 'regular_price' => '10', + 'name' => 'Test Batch Create 1', + 'type' => 'external', + 'button_text' => 'Test Button', + ), + array( + 'sku' => 'DUMMY SKU BATCH TEST 2', + 'regular_price' => '20', + 'name' => 'Test Batch Create 2', + 'type' => 'simple', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); + $this->assertEquals( 'DUMMY SKU BATCH TEST 1', $data['create'][0]['sku'] ); + $this->assertEquals( 'DUMMY SKU BATCH TEST 2', $data['create'][1]['sku'] ); + $this->assertEquals( 'Test Button', $data['create'][0]['button_text'] ); + $this->assertEquals( 'external', $data['create'][0]['type'] ); + $this->assertEquals( 'simple', $data['create'][1]['type'] ); + $this->assertEquals( $product_2->get_id(), $data['delete'][0]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Tests to make sure you can filter products post statuses by both + * the status query arg and WP_Query. + * + * @since 3.5.0 + */ + public function test_products_filter_post_status() { + wp_set_current_user( $this->user ); + for ( $i = 0; $i < 8; $i++ ) { + $product = WC_Helper_Product::create_simple_product(); + if ( 0 === $i % 2 ) { + wp_update_post( + array( + 'ID' => $product->get_id(), + 'post_status' => 'draft', + ) + ); + } + } + + // Test filtering with status=publish. + $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); + $request->set_param( 'status', 'publish' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 4, count( $products ) ); + foreach ( $products as $product ) { + $this->assertEquals( 'publish', $product['status'] ); + } + + // Test filtering with status=draft. + $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); + $request->set_param( 'status', 'draft' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 4, count( $products ) ); + foreach ( $products as $product ) { + $this->assertEquals( 'draft', $product['status'] ); + } + + // Test filtering with no filters - which should return 'any' (all 8). + $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 8, count( $products ) ); + } + + /** + * Test product schema. + * + * @since 3.5.0 + */ + public function test_product_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 65, count( $properties ) ); + } + + /** + * Test product category. + * + * @since 3.5.0 + */ + public function test_get_products_by_category() { + wp_set_current_user( $this->user ); + + // Create one product with a category. + $category = wp_insert_term( 'Some Category', 'product_cat' ); + + $product = new WC_Product_Simple(); + $product->set_category_ids( array( $category['term_id'] ) ); + $product->save(); + + // Create one product without category, i.e. Uncategorized. + $product_2 = new WC_Product_Simple(); + $product_2->save(); + + // Test product assigned to a single category. + $query_params = array( + 'category' => (string) $category['term_id'], + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $product->get_id(), $response_product['id'] ); + $this->assertEquals( $product->get_category_ids(), wp_list_pluck( $response_product['categories'], 'id' ) ); + } + + // Test product without categories. + $request = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product_2->get_id() ); + $response = $this->server->dispatch( $request ); + $response_product = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $response_product['categories'], print_r( $response_product, true ) ); + $this->assertEquals( 'uncategorized', $response_product['categories'][0]['slug'] ); + + } + + /** + * Test getting products by product type. + * + * @since 3.5.0 + */ + public function test_get_products_by_type() { + wp_set_current_user( $this->user ); + + $simple = WC_Helper_Product::create_simple_product(); + $external = WC_Helper_Product::create_external_product(); + $grouped = WC_Helper_Product::create_grouped_product(); + $variable = WC_Helper_Product::create_variation_product(); + + $product_ids_for_type = array( + 'simple' => array( $simple->get_id() ), + 'external' => array( $external->get_id() ), + 'grouped' => array( $grouped->get_id() ), + 'variable' => array( $variable->get_id() ), + ); + + foreach ( $grouped->get_children() as $additional_product ) { + $product_ids_for_type['simple'][] = $additional_product; + } + + foreach ( $product_ids_for_type as $product_type => $product_ids ) { + $query_params = array( + 'type' => $product_type, + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $product_ids ), count( $response_products ) ); + foreach ( $response_products as $response_product ) { + $this->assertContains( $response_product['id'], $product_ids_for_type[ $product_type ], 'REST API: ' . $product_type . ' not found correctly' ); + } + } + } + + /** + * Test getting products by featured property. + * + * @since 3.5.0 + */ + public function test_get_featured_products() { + wp_set_current_user( $this->user ); + + // Create a featured product. + $feat_product = WC_Helper_Product::create_simple_product(); + $feat_product->set_featured( true ); + $feat_product->save(); + + // Create a non-featured product. + $nonfeat_product = WC_Helper_Product::create_simple_product(); + $nonfeat_product->save(); + + $query_params = array( + 'featured' => 'true', + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $feat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' ); + } + + $query_params = array( + 'featured' => 'false', + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $nonfeat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' ); + } + } + + /** + * Test getting products by shipping class property. + * + * @since 3.5.0 + */ + public function test_get_products_by_shipping_class() { + wp_set_current_user( $this->user ); + + $shipping_class_1 = wp_insert_term( 'Bulky', 'product_shipping_class' ); + + $product_1 = new WC_Product_Simple(); + $product_1->set_shipping_class_id( $shipping_class_1['term_id'] ); + $product_1->save(); + + $query_params = array( + 'shipping_class' => (string) $shipping_class_1['term_id'], + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $product_1->get_id(), $response_product['id'] ); + } + } + + /** + * Test getting products by tag. + * + * @since 3.5.0 + */ + public function test_get_products_by_tag() { + wp_set_current_user( $this->user ); + + $test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' ); + + // Product with a tag. + $product = WC_Helper_Product::create_simple_product(); + $product->set_tag_ids( array( $test_tag_1['term_id'] ) ); + $product->save(); + + // Product without a tag. + $product_2 = WC_Helper_Product::create_simple_product(); + + $query_params = array( + 'tag' => (string) $test_tag_1['term_id'], + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $product->get_id(), $response_product['id'] ); + } + } + + /** + * Test getting products by global attribute. + * + * @since 3.5.0 + */ + public function test_get_products_by_attribute() { + global $wpdb; + wp_set_current_user( $this->user ); + + // Variable product with 2 different variations. + $variable_product = WC_Helper_Product::create_variation_product(); + + // Terms created by variable product. + $term_large = get_term_by( 'slug', 'large', 'pa_size' ); + $term_small = get_term_by( 'slug', 'small', 'pa_size' ); + + // Simple product without attribute. + $product_1 = WC_Helper_Product::create_simple_product(); + + // Simple product with attribute size = large. + $product_2 = WC_Helper_Product::create_simple_product(); + $product_2->set_attributes( array( 'pa_size' => 'large' ) ); + $product_2->save(); + + // Link the product to the term. + $wpdb->insert( + $wpdb->prefix . 'term_relationships', + array( + 'object_id' => $product_2->get_id(), + 'term_taxonomy_id' => $term_large->term_id, + 'term_order' => 0, + ) + ); + + // Products with attribute size == large. + $expected_product_ids = array( + $variable_product->get_id(), + $product_2->get_id(), + ); + $query_params = array( + 'attribute' => 'pa_size', + 'attribute_term' => (string) $term_large->term_id, + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $expected_product_ids ), count( $response_products ) ); + foreach ( $response_products as $response_product ) { + $this->assertContains( $response_product['id'], $expected_product_ids ); + } + + // Products with attribute size == small. + $expected_product_ids = array( + $variable_product->get_id(), + ); + $query_params = array( + 'attribute' => 'pa_size', + 'attribute_term' => (string) $term_small->term_id, + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $expected_product_ids ), count( $response_products ) ); + foreach ( $response_products as $response_product ) { + $this->assertContains( $response_product['id'], $expected_product_ids ); + } + } +} diff --git a/tests/Version3/reports-coupons-totals.php b/tests/Version3/reports-coupons-totals.php new file mode 100644 index 00000000000..cc4e1ef2de0 --- /dev/null +++ b/tests/Version3/reports-coupons-totals.php @@ -0,0 +1,103 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/reports/coupons/totals', $routes ); + } + + /** + * Test getting all product reviews. + * + * @since 3.5.0 + */ + public function test_get_reports() { + global $wpdb; + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/coupons/totals' ) ); + $report = $response->get_data(); + $types = wc_get_coupon_types(); + $data = array(); + + foreach ( $types as $slug => $name ) { + $results = $wpdb->get_results( + $wpdb->prepare( + " + SELECT count(meta_id) AS total + FROM $wpdb->postmeta + WHERE meta_key = 'discount_type' + AND meta_value = %s + ", + $slug + ) + ); + + $total = isset( $results[0] ) ? (int) $results[0]->total : 0; + + $data[] = array( + 'slug' => $slug, + 'name' => $name, + 'total' => $total, + ); + } + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $types ), count( $report ) ); + $this->assertEquals( $data, $report ); + } + + /** + * Tests to make sure product reviews cannot be viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/coupons/totals' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test the product review schema. + * + * @since 3.5.0 + */ + public function test_product_review_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/coupons/totals' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'slug', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'total', $properties ); + } +} diff --git a/tests/Version3/reports-customers-totals.php b/tests/Version3/reports-customers-totals.php new file mode 100644 index 00000000000..5b58d995d57 --- /dev/null +++ b/tests/Version3/reports-customers-totals.php @@ -0,0 +1,119 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/reports/customers/totals', $routes ); + } + + /** + * Test getting all product reviews. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/customers/totals' ) ); + $report = $response->get_data(); + $users_count = count_users(); + $total_customers = 0; + + foreach ( $users_count['avail_roles'] as $role => $total ) { + if ( in_array( $role, array( 'administrator', 'shop_manager' ), true ) ) { + continue; + } + + $total_customers += (int) $total; + } + + $customers_query = new WP_User_Query( + array( + 'role__not_in' => array( 'administrator', 'shop_manager' ), + 'number' => 0, + 'fields' => 'ID', + 'count_total' => true, + 'meta_query' => array( // WPCS: slow query ok. + array( + 'key' => 'paying_customer', + 'value' => 1, + 'compare' => '=', + ), + ), + ) + ); + + $total_paying = (int) $customers_query->get_total(); + + $data = array( + array( + 'slug' => 'paying', + 'name' => __( 'Paying customer', 'woocommerce' ), + 'total' => $total_paying, + ), + array( + 'slug' => 'non_paying', + 'name' => __( 'Non-paying customer', 'woocommerce' ), + 'total' => $total_customers - $total_paying, + ), + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $report ) ); + $this->assertEquals( $data, $report ); + } + + /** + * Tests to make sure product reviews cannot be viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/customers/totals' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test the product review schema. + * + * @since 3.5.0 + */ + public function test_product_review_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/customers/totals' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'slug', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'total', $properties ); + } +} diff --git a/tests/Version3/reports-orders-totals.php b/tests/Version3/reports-orders-totals.php new file mode 100644 index 00000000000..51508045e54 --- /dev/null +++ b/tests/Version3/reports-orders-totals.php @@ -0,0 +1,92 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/reports/orders/totals', $routes ); + } + + /** + * Test getting all product reviews. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/orders/totals' ) ); + $report = $response->get_data(); + $totals = wp_count_posts( 'shop_order' ); + $data = array(); + + foreach ( wc_get_order_statuses() as $slug => $name ) { + if ( ! isset( $totals->$slug ) ) { + continue; + } + + $data[] = array( + 'slug' => str_replace( 'wc-', '', $slug ), + 'name' => $name, + 'total' => (int) $totals->$slug, + ); + } + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( wc_get_order_statuses() ), count( $report ) ); + $this->assertEquals( $data, $report ); + } + + /** + * Tests to make sure product reviews cannot be viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/orders/totals' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test the product review schema. + * + * @since 3.5.0 + */ + public function test_product_review_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/orders/totals' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'slug', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'total', $properties ); + } +} diff --git a/tests/Version3/reports-products-totals.php b/tests/Version3/reports-products-totals.php new file mode 100644 index 00000000000..30e6c34c865 --- /dev/null +++ b/tests/Version3/reports-products-totals.php @@ -0,0 +1,99 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/reports/products/totals', $routes ); + } + + /** + * Test getting all product reviews. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Install::create_terms(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/products/totals' ) ); + $report = $response->get_data(); + $types = wc_get_product_types(); + $terms = get_terms( + array( + 'taxonomy' => 'product_type', + 'hide_empty' => false, + ) + ); + $data = array(); + + foreach ( $terms as $product_type ) { + if ( ! isset( $types[ $product_type->name ] ) ) { + continue; + } + + $data[] = array( + 'slug' => $product_type->name, + 'name' => $types[ $product_type->name ], + 'total' => (int) $product_type->count, + ); + } + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $types ), count( $report ) ); + $this->assertEquals( $data, $report ); + } + + /** + * Tests to make sure product reviews cannot be viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/products/totals' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test the product review schema. + * + * @since 3.5.0 + */ + public function test_product_review_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/products/totals' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'slug', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'total', $properties ); + } +} diff --git a/tests/Version3/reports-reviews-totals.php b/tests/Version3/reports-reviews-totals.php new file mode 100644 index 00000000000..ab5f7a4bd33 --- /dev/null +++ b/tests/Version3/reports-reviews-totals.php @@ -0,0 +1,98 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/reports/reviews/totals', $routes ); + } + + /** + * Test getting all product reviews. + * + * @since 3.5.0 + */ + public function test_get_reports() { + global $wpdb; + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/reviews/totals' ) ); + $report = $response->get_data(); + $data = array(); + + $query_data = array( + 'count' => true, + 'post_type' => 'product', + 'meta_key' => 'rating', // WPCS: slow query ok. + 'meta_value' => '', // WPCS: slow query ok. + ); + + for ( $i = 1; $i <= 5; $i++ ) { + $query_data['meta_value'] = $i; + + $data[] = array( + 'slug' => 'rated_' . $i . '_out_of_5', + /* translators: %s: average rating */ + 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $i ), + 'total' => (int) get_comments( $query_data ), + ); + } + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), count( $report ) ); + $this->assertEquals( $data, $report ); + } + + /** + * Tests to make sure product reviews cannot be viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/reviews/totals' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test the product review schema. + * + * @since 3.5.0 + */ + public function test_product_review_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/reviews/totals' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'slug', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'total', $properties ); + } +} diff --git a/tests/Version3/settings.php b/tests/Version3/settings.php new file mode 100644 index 00000000000..aa4f67cd02e --- /dev/null +++ b/tests/Version3/settings.php @@ -0,0 +1,895 @@ +endpoint = new WC_REST_Setting_Options_Controller(); + WC_Helper_Settings::register(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/settings', $routes ); + $this->assertArrayHasKey( '/wc/v3/settings/(?P[\w-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all groups. + * + * @since 3.5.0 + */ + public function test_get_groups() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertContains( + array( + 'id' => 'test', + 'label' => 'Test extension', + 'parent_id' => '', + 'description' => 'My awesome test settings.', + 'sub_groups' => array( 'sub-test' ), + '_links' => array( + 'options' => array( + array( + 'href' => rest_url( '/wc/v3/settings/test' ), + ), + ), + ), + ), + $data + ); + + $this->assertContains( + array( + 'id' => 'sub-test', + 'label' => 'Sub test', + 'parent_id' => 'test', + 'description' => '', + 'sub_groups' => array(), + '_links' => array( + 'options' => array( + array( + 'href' => rest_url( '/wc/v3/settings/sub-test' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test /settings without valid permissions/creds. + * + * @since 3.5.0 + */ + public function test_get_groups_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test /settings without valid permissions/creds. + * + * @since 3.5.0 + * @covers WC_Rest_Settings_Controller::get_items + */ + public function test_get_groups_none_registered() { + wp_set_current_user( $this->user ); + + remove_all_filters( 'woocommerce_settings_groups' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings' ) ); + $this->assertEquals( 500, $response->get_status() ); + + WC_Helper_Settings::register(); + } + + /** + * Test groups schema. + * + * @since 3.5.0 + */ + public function test_get_group_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/settings' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 5, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'parent_id', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'sub_groups', $properties ); + } + + /** + * Test settings schema. + * + * @since 3.5.0 + */ + public function test_get_setting_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/settings/test/woocommerce_shop_page_display' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 10, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'value', $properties ); + $this->assertArrayHasKey( 'default', $properties ); + $this->assertArrayHasKey( 'tip', $properties ); + $this->assertArrayHasKey( 'placeholder', $properties ); + $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'options', $properties ); + $this->assertArrayHasKey( 'group_id', $properties ); + } + + /** + * Test getting a single group. + * + * @since 3.5.0 + */ + public function test_get_group() { + wp_set_current_user( $this->user ); + + // test route callback receiving an empty group id + $result = $this->endpoint->get_group_settings( '' ); + $this->assertIsWPError( $result ); + + // test getting a group that does not exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/not-real' ) ); + $this->assertEquals( 404, $response->get_status() ); + + // test getting the 'invalid' group + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/invalid' ) ); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid group with settings attached to it + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( 1, count( $data ) ); + $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); + $this->assertEmpty( $data[0]['value'] ); + } + + /** + * Test getting a single group without permission. + * + * @since 3.5.0 + */ + public function test_get_group_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/coupon-data' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single setting. + * + * @since 3.5.0 + */ + public function test_update_setting() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data['value'] ); + + // test updating shop display setting + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'both', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'both', $data['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'subcategories', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'subcategories', $data['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => '', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '', $data['value'] ); + $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); + } + + /** + * Test updating multiple settings at once. + * + * @since 3.5.0 + */ + public function test_update_settings() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data[0]['value'] ); + + // test setting both at once + $request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'both', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'both', $data['update'][0]['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + + // test updating one, but making sure the other value stays the same + $request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + } + + /** + * Test getting a single setting. + * + * @since 3.5.0 + */ + public function test_get_setting() { + wp_set_current_user( $this->user ); + + // test getting an invalid setting from a group that does not exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/not-real/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting an invalid setting from a group that does exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/invalid/invalid' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid setting + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'woocommerce_shop_page_display', $data['id'] ); + $this->assertEquals( 'Shop page display', $data['label'] ); + $this->assertEquals( '', $data['default'] ); + $this->assertEquals( 'select', $data['type'] ); + $this->assertEquals( '', $data['value'] ); + } + + /** + * Test getting a single setting without valid user permissions. + * + * @since 3.5.0 + */ + public function test_get_setting_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test/woocommerce_shop_page_display' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests the GET single setting route handler receiving an empty setting ID. + * + * @since 3.5.0 + */ + public function test_get_setting_empty_setting_id() { + $result = $this->endpoint->get_setting( 'test', '' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler receiving an invalid setting ID. + * + * @since 3.5.0 + */ + public function test_get_setting_invalid_setting_id() { + $result = $this->endpoint->get_setting( 'test', 'invalid' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler encountering an invalid setting type. + * + * @since 3.5.0 + */ + public function test_get_setting_invalid_setting_type() { + // $controller = $this->getMock( 'WC_Rest_Setting_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); + $controller = $this->getMockBuilder( 'WC_Rest_Setting_Options_Controller' )->setMethods( array( 'get_group_settings', 'is_setting_type_valid' ) )->getMock(); + + $controller + ->expects( $this->any() ) + ->method( 'get_group_settings' ) + ->will( $this->returnValue( WC_Helper_Settings::register_test_settings( array() ) ) ); + + $controller + ->expects( $this->any() ) + ->method( 'is_setting_type_valid' ) + ->will( $this->returnValue( false ) ); + + $result = $controller->get_setting( 'test', 'woocommerce_shop_page_display' ); + + $this->assertIsWPError( $result ); + } + + /** + * Test updating a single setting without valid user permissions. + * + * @since 3.5.0 + */ + public function test_update_setting_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'subcategories', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + + /** + * Test updating multiple settings without valid user permissions. + * + * @since 3.5.0 + */ + public function test_update_settings_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a bad setting ID. + * + * @since 3.5.0 + * @covers WC_Rest_Setting_Options_Controller::update_item + */ + public function test_update_setting_bad_setting_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/test/invalid' ); + $request->set_body_params( + array( + 'value' => 'test', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. + * + * @since 3.5.0 + */ + public function test_classic_settings() { + wp_set_current_user( $this->user ); + + // Make sure the group is properly registered + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/products' ) ); + $data = $response->get_data(); + $this->assertTrue( is_array( $data ) ); + $this->assertContains( + array( + 'id' => 'woocommerce_downloads_require_login', + 'label' => 'Access restriction', + 'description' => 'Downloads require login', + 'type' => 'checkbox', + 'default' => 'no', + 'tip' => 'This setting does not apply to guest purchases.', + 'value' => 'no', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/settings/products/woocommerce_downloads_require_login' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/settings/products' ), + ), + ), + ), + ), + $data + ); + + // test get single + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/products/woocommerce_dimension_unit' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'cm', $data['default'] ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); + $request->set_body_params( + array( + 'value' => 'yd', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'yd', $data['value'] ); + $this->assertEquals( 'yd', get_option( 'woocommerce_dimension_unit' ) ); + } + + /** + * Tests our email etting registration to make sure settings added for WP-Admin are available over the API. + * + * @since 3.5.0 + */ + public function test_email_settings() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/email_new_order' ) ); + $settings = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertContains( + array( + 'id' => 'recipient', + 'label' => 'Recipient(s)', + 'description' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', + 'type' => 'text', + 'default' => '', + 'tip' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', + 'value' => '', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/settings/email_new_order/recipient' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/settings/email_new_order' ), + ), + ), + ), + ), + $settings + ); + + // test get single + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/email_new_order/subject' ) ); + $setting = $response->get_data(); + + $this->assertEquals( + array( + 'id' => 'subject', + 'label' => 'Subject', + 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'type' => 'text', + 'default' => '', + 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'value' => '', + 'group_id' => 'email_new_order', + ), + $setting + ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_new_order', 'subject' ) ); + $request->set_body_params( + array( + 'value' => 'This is my subject', + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEquals( + array( + 'id' => 'subject', + 'label' => 'Subject', + 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'type' => 'text', + 'default' => '', + 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'value' => 'This is my subject', + 'group_id' => 'email_new_order', + ), + $setting + ); + + // test updating another subject and making sure it works with a "similar" id + $request = new WP_REST_Request( 'GET', sprintf( '/wc/v3/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEmpty( $setting['value'] ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); + $request->set_body_params( + array( + 'value' => 'This is my new subject', + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEquals( 'This is my new subject', $setting['value'] ); + + // make sure the other is what we left it + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/email_new_order/subject' ) ); + $setting = $response->get_data(); + + $this->assertEquals( 'This is my subject', $setting['value'] ); + } + + /** + * Test validation of checkbox settings. + * + * @since 3.5.0 + */ + public function test_validation_checkbox() { + wp_set_current_user( $this->user ); + + // test bogus value + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'not_yes_or_no', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // test yes + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'yes', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + // test no + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'no', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test validation of radio settings. + * + * @since 3.5.0 + */ + public function test_validation_radio() { + wp_set_current_user( $this->user ); + + // not a valid option + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); + $request->set_body_params( + array( + 'value' => 'billing2', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // valid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); + $request->set_body_params( + array( + 'value' => 'billing', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test validation of multiselect. + * + * @since 3.5.0 + */ + public function test_validation_multiselect() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v3/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ) ); + $setting = $response->get_data(); + $this->assertEmpty( $setting['value'] ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ); + $request->set_body_params( + array( + 'value' => array( 'AX', 'DZ', 'MMM' ), + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( array( 'AX', 'DZ' ), $setting['value'] ); + } + + /** + * Test validation of select. + * + * @since 3.5.0 + */ + public function test_validation_select() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ) ); + $setting = $response->get_data(); + $this->assertEquals( 'kg', $setting['value'] ); + + // invalid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); + $request->set_body_params( + array( + 'value' => 'pounds', // invalid, should be lbs + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // valid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); + $request->set_body_params( + array( + 'value' => 'lbs', // invalid, should be lbs + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( 'lbs', $setting['value'] ); + } + + /** + * Test to make sure the 'base location' setting is present in the response. + * That it is returned as 'select' and not 'single_select_country', + * and that both state and country options are returned. + * + * @since 3.5.0 + */ + public function test_woocommerce_default_country() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_default_country' ) ); + $setting = $response->get_data(); + + $this->assertEquals( 'select', $setting['type'] ); + $this->assertArrayHasKey( 'GB', $setting['options'] ); + $this->assertArrayHasKey( 'US:OR', $setting['options'] ); + } + + /** + * Test to make sure the store address setting can be fetched and updated. + * + * @since 3.5.0 + */ + public function test_woocommerce_store_address() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_address' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store address 2 (line 2) setting can be fetched and updated. + * + * @since 3.5.0 + */ + public function test_woocommerce_store_address_2() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_address_2' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address_2' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address_2' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store city setting can be fetched and updated. + * + * @since 3.5.0 + */ + public function test_woocommerce_store_city() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_city' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_city' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_city' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store postcode setting can be fetched and updated. + * + * @since 3.5.0 + */ + public function test_woocommerce_store_postcode() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_postcode' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_postcode' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_postcode' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } +} diff --git a/tests/Version3/shipping-methods.php b/tests/Version3/shipping-methods.php new file mode 100644 index 00000000000..ad139c427af --- /dev/null +++ b/tests/Version3/shipping-methods.php @@ -0,0 +1,143 @@ +endpoint = new WC_REST_Shipping_Methods_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/shipping_methods', $routes ); + $this->assertArrayHasKey( '/wc/v3/shipping_methods/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all shipping methods. + * + * @since 3.5.0 + */ + public function test_get_shipping_methods() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods' ) ); + $methods = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( + array( + 'id' => 'free_shipping', + 'title' => 'Free shipping', + 'description' => 'Free shipping is a special method which can be triggered with coupons and minimum spends.', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/shipping_methods/free_shipping' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping_methods' ), + ), + ), + ), + ), + $methods + ); + } + + /** + * Tests to make sure shipping methods cannot viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_shipping_methods_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a single shipping method. + * + * @since 3.5.0 + */ + public function test_get_shipping_method() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods/local_pickup' ) ); + $method = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => 'local_pickup', + 'title' => 'Local pickup', + 'description' => 'Allow customers to pick up orders themselves. By default, when using local pickup store base taxes will apply regardless of customer address.', + ), + $method + ); + } + + /** + * Tests getting a single shipping method without the correct permissions. + * + * @since 3.5.0 + */ + public function test_get_shipping_method_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods/local_pickup' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a shipping method with an invalid ID. + * + * @since 3.5.0 + */ + public function test_get_shipping_method_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods/fake_method' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test the shipping method schema. + * + * @since 3.5.0 + */ + public function test_shipping_method_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/shipping_methods' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'title', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + } +} diff --git a/tests/Version3/shipping-zones.php b/tests/Version3/shipping-zones.php new file mode 100644 index 00000000000..580391d1b33 --- /dev/null +++ b/tests/Version3/shipping-zones.php @@ -0,0 +1,825 @@ +endpoint = new WC_REST_Shipping_Zones_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + $this->zones = array(); + } + + /** + * Helper method to create a Shipping Zone. + * + * @param string $name Zone name. + * @param int $order Optional. Zone sort order. + * @return WC_Shipping_Zone + */ + protected function create_shipping_zone( $name, $order = 0, $locations = array() ) { + $zone = new WC_Shipping_Zone( null ); + $zone->set_zone_name( $name ); + $zone->set_zone_order( $order ); + $zone->set_locations( $locations ); + $zone->save(); + + $this->zones[] = $zone; + + return $zone; + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/shipping/zones', $routes ); + $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/locations', $routes ); + $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/methods', $routes ); + $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/methods/(?P[\d]+)', $routes ); + } + + /** + * Test getting all Shipping Zones. + * + * @since 3.5.0 + */ + public function test_get_zones() { + wp_set_current_user( $this->user ); + + // "Rest of the World" zone exists by default + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( + array( + 'id' => $data[0]['id'], + 'name' => 'Locations not covered by your other zones', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $data[0]['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $data[0]['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + + // Create a zone and make sure it's in the response + $this->create_shipping_zone( 'Zone 1' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 2 ); + $this->assertContains( + array( + 'id' => $data[1]['id'], + 'name' => 'Zone 1', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $data[1]['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $data[1]['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test /shipping/zones without valid permissions/creds. + * + * @since 3.5.0 + */ + public function test_get_shipping_zones_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test /shipping/zones while Shipping is disabled in WooCommerce. + * + * @since 3.5.0 + */ + public function test_get_shipping_zones_disabled_shipping() { + wp_set_current_user( $this->user ); + + add_filter( 'wc_shipping_enabled', '__return_false' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones' ) ); + $this->assertEquals( 404, $response->get_status() ); + + remove_filter( 'wc_shipping_enabled', '__return_false' ); + } + + /** + * Test Shipping Zone schema. + * + * @since 3.5.0 + */ + public function test_get_shipping_zone_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/shipping/zones' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertTrue( $properties['id']['readonly'] ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'order', $properties ); + } + + /** + * Test Shipping Zone create endpoint. + * + * @since 3.5.0 + */ + public function test_create_shipping_zone() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones' ); + $request->set_body_params( + array( + 'name' => 'Test Zone', + 'order' => 1, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'name' => 'Test Zone', + 'order' => 1, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $data['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $data['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test Shipping Zone create endpoint. + * + * @since 3.5.0 + */ + public function test_create_shipping_zone_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones' ); + $request->set_body_params( + array( + 'name' => 'Test Zone', + 'order' => 1, + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test Shipping Zone update endpoint. + * + * @since 3.5.0 + */ + public function test_update_shipping_zone() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/shipping/zones/' . $zone->get_id() ); + $request->set_body_params( + array( + 'name' => 'Zone Test', + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $zone->get_id(), + 'name' => 'Zone Test', + 'order' => 2, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test Shipping Zone update endpoint with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_update_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/shipping/zones/555555' ); + $request->set_body_params( + array( + 'name' => 'Zone Test', + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint. + * + * @since 3.5.0 + */ + public function test_delete_shipping_zone() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/shipping/zones/' . $zone->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint without permissions. + * + * @since 3.5.0 + */ + public function test_delete_shipping_zone_without_permission() { + wp_set_current_user( 0 ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v3/shipping/zones/' . $zone->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_delete_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'DELETE', '/wc/v3/shipping/zones/555555' ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single Shipping Zone. + * + * @since 3.5.0 + */ + public function test_get_single_shipping_zone() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $zone->get_id(), + 'name' => 'Test Zone', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test getting a single Shipping Zone with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_get_single_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting Shipping Zone Locations. + * + * @since 3.5.0 + */ + public function test_get_locations() { + wp_set_current_user( $this->user ); + + // Create a zone + $zone = $this->create_shipping_zone( + 'Zone 1', + 0, + array( + array( + 'code' => 'US', + 'type' => 'country', + ), + ) + ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertEquals( + array( + array( + 'code' => 'US', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test getting Shipping Zone Locations with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_get_locations_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/1/locations' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test Shipping Zone Locations update endpoint. + * + * @since 3.5.0 + */ + public function test_update_locations() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + + $request = new WP_REST_Request( 'PUT', '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + json_encode( + array( + array( + 'code' => 'UK', + 'type' => 'country', + ), + array( + 'code' => 'US', // test that locations missing "type" treated as country. + ), + array( + 'code' => 'SW1A0AA', + 'type' => 'postcode', + ), + array( + 'type' => 'continent', // test that locations missing "code" aren't saved + ), + ) + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + $this->assertEquals( + array( + array( + 'code' => 'UK', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + array( + 'code' => 'US', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + array( + 'code' => 'SW1A0AA', + 'type' => 'postcode', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test updating Shipping Zone Locations with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_update_locations_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'PUT', '/wc/v3/shipping/zones/1/locations' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting all Shipping Zone Methods and getting a single Shipping Zone Method. + * + * @since 3.5.0 + */ + public function test_get_methods() { + wp_set_current_user( $this->user ); + + // Create a shipping method and make sure it's in the response + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + + $settings = array(); + $method->init_instance_settings(); + foreach ( $method->get_instance_form_fields() as $id => $field ) { + $data = array( + 'id' => $id, + 'label' => $field['title'], + 'description' => ( empty( $field['description'] ) ? '' : $field['description'] ), + 'type' => $field['type'], + 'value' => $method->instance_settings[ $id ], + 'default' => ( empty( $field['default'] ) ? '' : $field['default'] ), + 'tip' => ( empty( $field['description'] ) ? '' : $field['description'] ), + 'placeholder' => ( empty( $field['placeholder'] ) ? '' : $field['placeholder'] ), + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods' ) ); + $data = $response->get_data(); + $expected = array( + 'id' => $instance_id, + 'instance_id' => $instance_id, + 'title' => $method->instance_settings['title'], + 'order' => $method->method_order, + 'enabled' => ( 'yes' === $method->enabled ), + 'method_id' => $method->id, + 'method_title' => $method->method_title, + 'method_description' => $method->method_description, + 'settings' => $settings, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( $expected, $data ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $expected, $data ); + } + + /** + * Test getting all Shipping Zone Methods with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_get_methods_invalid_zone_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/1/methods' ) ); + + $this->assertEquals( 404, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/1/methods/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single Shipping Zone Method with a bad ID. + * + * @since 3.5.0 + */ + public function test_get_methods_invalid_method_id() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Zone 1' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a Shipping Zone Method. + * + * @since 3.5.0 + */ + public function test_update_methods() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + + // Test defaults + $request = new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '0', $data['settings']['cost']['value'] ); + + // Update a single value + $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 5, + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '5', $data['settings']['cost']['value'] ); + + // Test multiple settings + $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 10, + 'tax_status' => 'none', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'none', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '10', $data['settings']['cost']['value'] ); + + // Test bogus + $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 10, + 'tax_status' => 'this_is_not_a_valid_option', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // Test other parameters + $this->assertTrue( $data['enabled'] ); + $this->assertEquals( 1, $data['order'] ); + + $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertFalse( $data['enabled'] ); + $this->assertEquals( 2, $data['order'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '10', $data['settings']['cost']['value'] ); + } + + /** + * Test creating a Shipping Zone Method. + * + * @since 3.5.0 + */ + public function test_create_method() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods' ); + $request->set_body_params( + array( + 'method_id' => 'flat_rate', + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertFalse( $data['enabled'] ); + $this->assertEquals( 2, $data['order'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '0', $data['settings']['cost']['value'] ); + } + + /** + * Test deleting a Shipping Zone Method. + * + * @since 3.5.0 + */ + public function test_delete_method() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + $request = new WP_REST_Request( 'DELETE', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } +} diff --git a/tests/Version3/system-status.php b/tests/Version3/system-status.php new file mode 100644 index 00000000000..51f3016bcab --- /dev/null +++ b/tests/Version3/system-status.php @@ -0,0 +1,467 @@ +endpoint = new WC_REST_System_Status_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + + // Callback used by WP_HTTP_TestCase to decide whether to perform HTTP requests or to provide a mocked response. + $this->http_responder = array( $this, 'mock_http_responses' ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v3/system_status', $routes ); + $this->assertArrayHasKey( '/wc/v3/system_status/tools', $routes ); + $this->assertArrayHasKey( '/wc/v3/system_status/tools/(?P[\w-]+)', $routes ); + } + + /** + * Test to make sure system status cannot be accessed without valid creds + * + * @since 3.5.0 + */ + public function test_get_system_status_info_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure root properties are present. + * (environment, theme, database, etc). + * + * @since 3.5.0 + */ + public function test_get_system_status_info_returns_root_properties() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'environment', $data ); + $this->assertArrayHasKey( 'database', $data ); + $this->assertArrayHasKey( 'active_plugins', $data ); + $this->assertArrayHasKey( 'theme', $data ); + $this->assertArrayHasKey( 'settings', $data ); + $this->assertArrayHasKey( 'security', $data ); + $this->assertArrayHasKey( 'pages', $data ); + } + + /** + * Test to make sure environment response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_environment() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + $data = $response->get_data(); + $environment = (array) $data['environment']; + + // Make sure all expected data is present. + $this->assertEquals( 32, count( $environment ) ); + + // Test some responses to make sure they match up. + $this->assertEquals( get_option( 'home' ), $environment['home_url'] ); + $this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] ); + $this->assertEquals( WC()->version, $environment['version'] ); + } + + /** + * Test to make sure database response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_database() { + global $wpdb; + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + $data = $response->get_data(); + $database = (array) $data['database']; + + $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); + $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); + $this->assertEquals( WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); + $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], wc_print_r( $database, true ) ); + $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], wc_print_r( $database, true ) ); + } + + /** + * Test to make sure active plugins response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_active_plugins() { + wp_set_current_user( $this->user ); + + $actual_plugins = array( 'hello.php' ); + update_option( 'active_plugins', $actual_plugins ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + update_option( 'active_plugins', array() ); + + $data = $response->get_data(); + $plugins = (array) $data['active_plugins']; + + $this->assertEquals( 1, count( $plugins ) ); + $this->assertEquals( 'Hello Dolly', $plugins[0]['name'] ); + } + + /** + * Test to make sure theme response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_theme() { + wp_set_current_user( $this->user ); + $active_theme = wp_get_theme(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + $data = $response->get_data(); + $theme = (array) $data['theme']; + + $this->assertEquals( 13, count( $theme ) ); + $this->assertEquals( $active_theme->Name, $theme['name'] ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar + } + + /** + * Test to make sure settings response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_settings() { + wp_set_current_user( $this->user ); + + $term_response = array(); + $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + $data = $response->get_data(); + $settings = (array) $data['settings']; + + $this->assertEquals( 12, count( $settings ) ); + $this->assertEquals( ( 'yes' === get_option( 'woocommerce_api_enabled' ) ), $settings['api_enabled'] ); + $this->assertEquals( get_woocommerce_currency(), $settings['currency'] ); + $this->assertEquals( $term_response, $settings['taxonomies'] ); + } + + /** + * Test to make sure security response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_security() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + $data = $response->get_data(); + $settings = (array) $data['security']; + + $this->assertEquals( 2, count( $settings ) ); + $this->assertEquals( 'https' === substr( wc_get_page_permalink( 'shop' ), 0, 5 ), $settings['secure_connection'] ); + $this->assertEquals( ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), $settings['hide_errors'] ); + } + + /** + * Test to make sure pages response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_pages() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); + $data = $response->get_data(); + $pages = $data['pages']; + $this->assertEquals( 5, count( $pages ) ); + } + + /** + * Test system status schema. + * + * @since 3.5.0 + */ + public function test_system_status_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/system_status' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 9, count( $properties ) ); + $this->assertArrayHasKey( 'environment', $properties ); + $this->assertArrayHasKey( 'database', $properties ); + $this->assertArrayHasKey( 'active_plugins', $properties ); + $this->assertArrayHasKey( 'theme', $properties ); + $this->assertArrayHasKey( 'settings', $properties ); + $this->assertArrayHasKey( 'security', $properties ); + $this->assertArrayHasKey( 'pages', $properties ); + } + + /** + * Test to make sure get_items (all tools) response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_tools() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status/tools' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $raw_tools ), count( $data ) ); + $this->assertContains( + array( + 'id' => 'regenerate_thumbnails', + 'name' => 'Regenerate shop thumbnails', + 'action' => 'Regenerate', + 'description' => 'This will regenerate all shop thumbnails to match your theme and/or image settings.', + '_links' => array( + 'item' => array( + array( + 'href' => rest_url( '/wc/v3/system_status/tools/regenerate_thumbnails' ), + 'embeddable' => 1, + ), + ), + ), + ), + $data + ); + + $query_params = array( + '_fields' => 'id,name,nonexisting', + ); + $request = new WP_REST_Request( 'GET', '/wc/v3/system_status/tools' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $raw_tools ), count( $data ) ); + $this->assertContains( + array( + 'id' => 'regenerate_thumbnails', + 'name' => 'Regenerate shop thumbnails', + ), + $data + ); + foreach ( $data as $item ) { + // Fields that are not requested are not returned in response. + $this->assertArrayNotHasKey( 'action', $item ); + $this->assertArrayNotHasKey( 'description', $item ); + // Links are part of data in collections, so excluded if not explicitly requested. + $this->assertArrayNotHasKey( '_links', $item ); + // Non existing field is ignored. + $this->assertArrayNotHasKey( 'nonexisting', $item ); + } + + // Links are part of data, not links in collections. + $links = $response->get_links(); + $this->assertEquals( 0, count( $links ) ); + } + + /** + * Test to make sure system status tools cannot be accessed without valid creds + * + * @since 3.5.0 + */ + public function test_get_system_status_tools_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status/tools' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure we can load a single tool correctly. + * + * @since 3.5.0 + */ + public function test_get_system_tool() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + $raw_tool = $raw_tools['recount_terms']; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status/tools/recount_terms' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertEquals( 'Recount terms', $data['action'] ); + $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); + + // Test for _fields query parameter. + $query_params = array( + '_fields' => 'id,name,nonexisting', + ); + $request = new WP_REST_Request( 'GET', '/wc/v3/system_status/tools/recount_terms' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertArrayNotHasKey( 'action', $data ); + $this->assertArrayNotHasKey( 'description', $data ); + // Links are part of links, not data in single items. + $this->assertArrayNotHasKey( '_links', $data ); + + // Links are part of links, not data in single item response. + $links = $response->get_links(); + $this->assertEquals( 1, count( $links ) ); + } + + /** + * Test to make sure a single system status toolscannot be accessed without valid creds. + * + * @since 3.5.0 + */ + public function test_get_system_status_tool_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status/tools/recount_terms' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure we can RUN a tool correctly. + * + * @since 3.5.0 + */ + public function test_execute_system_tool() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + $raw_tool = $raw_tools['recount_terms']; + + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v3/system_status/tools/recount_terms' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertEquals( 'Recount terms', $data['action'] ); + $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); + $this->assertTrue( $data['success'] ); + $this->assertEquals( 1, did_action( 'woocommerce_rest_insert_system_status_tool' ) ); + + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v3/system_status/tools/not_a_real_tool' ) ); + $this->assertEquals( 404, $response->get_status() ); + + // Test _fields for execute system tool request. + $query_params = array( + '_fields' => 'id,success,nonexisting', + ); + $request = new WP_REST_Request( 'PUT', '/wc/v3/system_status/tools/recount_terms' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertTrue( $data['success'] ); + + // Fields that are not requested are not returned in response. + $this->assertArrayNotHasKey( 'action', $data ); + $this->assertArrayNotHasKey( 'name', $data ); + $this->assertArrayNotHasKey( 'description', $data ); + // Links are part of links, not data in single item response. + $this->assertArrayNotHasKey( '_links', $data ); + // Non existing field is ignored. + $this->assertArrayNotHasKey( 'nonexisting', $data ); + + // Links are part of links, not data in single item response. + $links = $response->get_links(); + $this->assertEquals( 1, count( $links ) ); + } + + /** + * Test to make sure a tool cannot be run without valid creds. + * + * @since 3.5.0 + */ + public function test_execute_system_status_tool_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v3/system_status/tools/recount_terms' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test system status schema. + * + * @since 3.5.0 + */ + public function test_system_status_tool_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/system_status/tools' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 6, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'action', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'success', $properties ); + $this->assertArrayHasKey( 'message', $properties ); + } + + /** + * Provides a mocked response for external requests performed by WC_REST_System_Status_Controller. + * This way it is not necessary to perform a regular request to an external server which would + * significantly slow down the tests. + * + * This function is called by WP_HTTP_TestCase::http_request_listner(). + * + * @param array $request Request arguments. + * @param string $url URL of the request. + * + * @return array|false mocked response or false to let WP perform a regular request. + */ + protected function mock_http_responses( $request, $url ) { + $mocked_response = false; + + if ( in_array( $url, array( 'https://www.paypal.com/cgi-bin/webscr', 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=0' ), true ) ) { + $mocked_response = array( + 'response' => array( 'code' => 200 ), + ); + } elseif ( 'https://api.wordpress.org/themes/info/1.0/' === $url ) { + $mocked_response = array( + 'body' => 'O:8:"stdClass":12:{s:4:"name";s:7:"Default";s:4:"slug";s:7:"default";s:7:"version";s:5:"1.7.2";s:11:"preview_url";s:29:"https://wp-themes.com/default";s:6:"author";s:15:"wordpressdotorg";s:14:"screenshot_url";s:61:"//ts.w.org/wp-content/themes/default/screenshot.png?ver=1.7.2";s:6:"rating";d:100;s:11:"num_ratings";s:1:"3";s:10:"downloaded";i:296618;s:12:"last_updated";s:10:"2010-06-14";s:8:"homepage";s:37:"https://wordpress.org/themes/default/";s:13:"download_link";s:55:"https://downloads.wordpress.org/theme/default.1.7.2.zip";}', + 'response' => array( 'code' => 200 ), + ); + } + + return $mocked_response; + } +} diff --git a/tests/Version4/Coupons.php b/tests/Version4/Coupons.php index e3fb86edce3..7c6d65cc0dd 100644 --- a/tests/Version4/Coupons.php +++ b/tests/Version4/Coupons.php @@ -31,140 +31,232 @@ class Coupons extends AbstractRestApiTest { /** * The endpoint schema. * - * @var array + * @var array Keys are property names, values are supported context. */ protected $properties = [ - 'id', - 'code', - 'amount', - 'date_created', - 'date_created_gmt', - 'date_modified', - 'date_modified_gmt', - 'discount_type', - 'description', - 'date_expires', - 'date_expires_gmt', - 'usage_count', - 'individual_use', - 'product_ids', - 'excluded_product_ids', - 'usage_limit', - 'usage_limit_per_user', - 'limit_usage_to_x_items', - 'free_shipping', - 'product_categories', - 'excluded_product_categories', - 'exclude_sale_items', - 'minimum_amount', - 'maximum_amount', - 'email_restrictions', - 'used_by', - 'meta_data', + 'id' => array( 'view', 'edit' ), + 'code' => array( 'view', 'edit' ), + 'amount' => array( 'view', 'edit' ), + 'date_created' => array( 'view', 'edit' ), + 'date_created_gmt' => array( 'view', 'edit' ), + 'date_modified' => array( 'view', 'edit' ), + 'date_modified_gmt' => array( 'view', 'edit' ), + 'discount_type' => array( 'view', 'edit' ), + 'description' => array( 'view', 'edit' ), + 'date_expires' => array( 'view', 'edit' ), + 'date_expires_gmt' => array( 'view', 'edit' ), + 'usage_count' => array( 'view', 'edit' ), + 'individual_use' => array( 'view', 'edit' ), + 'product_ids' => array( 'view', 'edit' ), + 'excluded_product_ids' => array( 'view', 'edit' ), + 'usage_limit' => array( 'view', 'edit' ), + 'usage_limit_per_user' => array( 'view', 'edit' ), + 'limit_usage_to_x_items' => array( 'view', 'edit' ), + 'free_shipping' => array( 'view', 'edit' ), + 'product_categories' => array( 'view', 'edit' ), + 'excluded_product_categories' => array( 'view', 'edit' ), + 'exclude_sale_items' => array( 'view', 'edit' ), + 'minimum_amount' => array( 'view', 'edit' ), + 'maximum_amount' => array( 'view', 'edit' ), + 'email_restrictions' => array( 'view', 'edit' ), + 'used_by' => array( 'view', 'edit' ), + 'meta_data' => array( 'view', 'edit' ), ]; /** - * Test delete. - * - * @return void + * Test create. */ - public function test_delete() { - $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); - $result = $this->do_request( - '/wc/v4/coupons/' . $coupon->get_id(), - 'DELETE', - [ 'force' => false ] - ); - $this->assertEquals( 200, $result->status ); - $this->assertEquals( 'trash', get_post_status( $coupon->get_id() ) ); + public function test_create() { + $valid_data = [ + 'code' => 'test-coupon', + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + 'description' => 'Test description.', + 'date_expires' => date( 'Y-m-d\T00:00:00', strtotime( '+1 day' ) ), + 'individual_use' => true, + 'product_ids' => [ 1, 2, 3 ], + 'excluded_product_ids' => [ 3, 4, 5 ], + 'usage_limit' => 10, + 'usage_limit_per_user' => 10, + 'limit_usage_to_x_items' => 10, + 'free_shipping' => false, + 'product_categories' => [ 1, 2, 3 ], + 'excluded_product_categories' => [ 3, 4, 5 ], + 'exclude_sale_items' => true, + 'minimum_amount' => '100', + 'maximum_amount' => '200', + 'email_restrictions' => [ 'test@test.com' ], + 'meta_data' => [ + [ + 'key' => 'test_key', + 'value' => 'test_value', + ] + ] + ]; + $response = $this->do_request( '/wc/v4/coupons', 'POST', $valid_data ); + $this->assertExpectedResponse( $response, 201, $valid_data ); } /** - * Test force delete. - * - * @return void + * Test read. */ - public function test_force_delete() { - $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); - $result = $this->do_request( + public function test_read() { + $coupon1 = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $coupon2 = \WC_Helper_Coupon::create_coupon( 'testcoupon-2' ); + $coupon3 = \WC_Helper_Coupon::create_coupon( 'anothertestcoupon-3' ); + $coupon4 = \WC_Helper_Coupon::create_coupon( 'anothertestcoupon-4' ); + + // Collection. + $response = $this->do_request( '/wc/v4/coupons', 'GET' ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 4, count( $response->data ) ); + + // Collection args. + $response = $this->do_request( '/wc/v4/coupons', 'GET', [ 'code' => 'testcoupon-1' ] ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 1, count( $response->data ) ); + + $response = $this->do_request( '/wc/v4/coupons', 'GET', [ 'search' => 'anothertestcoupon' ] ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 2, count( $response->data ) ); + + // Single. + $response = $this->do_request( '/wc/v4/coupons/' . $coupon1->get_id(), 'GET' ); + $this->assertExpectedResponse( $response, 200 ); + + foreach ( $this->get_properties( 'view' ) as $property ) { + $this->assertArrayHasKey( $property, $response->data ); + } + + // Invalid. + $response = $this->do_request( '/wc/v4/coupons/0', 'GET' ); + $this->assertExpectedResponse( $response, 404 ); + } + + /** + * Test update. + */ + public function test_update() { + // Invalid. + $response = $this->do_request( '/wc/v4/coupons/0', 'POST', [ 'code' => 'test' ] ); + $this->assertExpectedResponse( $response, 404 ); + + // Update existing. + $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $response = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), - 'DELETE', - [ 'force' => true ] + 'POST', + [ + 'code' => 'new-code', + 'description' => 'new description', + ] ); + $this->assertExpectedResponse( $response, 200 ); + + foreach ( $this->get_properties( 'view' ) as $property ) { + $this->assertArrayHasKey( $property, $response->data ); + } + + $this->assertEquals( $coupon->get_id(), $response->data['id'] ); + $this->assertEquals( 'new-code', $response->data['code'] ); + $this->assertEquals( 'new description', $response->data['description'] ); + } + + /** + * Test delete. + */ + public function test_delete() { + // Invalid. + $result = $this->do_request( '/wc/v4/coupons/0', 'DELETE', [ 'force' => false ] ); + $this->assertEquals( 404, $result->status ); + + // Trash. + $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + + $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); + $this->assertEquals( 200, $result->status ); + $this->assertEquals( 'trash', get_post_status( $coupon->get_id() ) ); + + // Force. + $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-2' ); + + $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => true ] ); $this->assertEquals( 200, $result->status ); $this->assertEquals( false, get_post( $coupon->get_id() ) ); } /** - * Test delete. - * - * @return void + * Test read. */ - public function test_delete_without_permission() { - $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); - $result = $this->do_request( + public function test_guest_create() { + parent::test_guest_create(); + + $valid_data = [ + 'code' => 'test-coupon', + 'amount' => '5.00', + 'discount_type' => 'fixed_product', + 'description' => 'Test description.', + 'date_expires' => date( 'Y-m-d\T00:00:00', strtotime( '+1 day' ) ), + 'individual_use' => true, + 'product_ids' => [ 1, 2, 3 ], + 'excluded_product_ids' => [ 3, 4, 5 ], + 'usage_limit' => 10, + 'usage_limit_per_user' => 10, + 'limit_usage_to_x_items' => 10, + 'free_shipping' => false, + 'product_categories' => [ 1, 2, 3 ], + 'excluded_product_categories' => [ 3, 4, 5 ], + 'exclude_sale_items' => true, + 'minimum_amount' => '100', + 'maximum_amount' => '200', + 'email_restrictions' => [ 'test@test.com' ], + 'meta_data' => [ + [ + 'key' => 'test_key', + 'value' => 'test_value', + ] + ] + ]; + $response = $this->do_request( '/wc/v4/coupons', 'POST', $valid_data ); + $this->assertExpectedResponse( $response, 401 ); + } + + /** + * Test read. + */ + public function test_guest_read() { + parent::test_guest_read(); + + $response = $this->do_request( '/wc/v4/coupons', 'GET' ); + $this->assertExpectedResponse( $response, 401 ); + } + + /** + * Test update. + */ + public function test_guest_update() { + parent::test_guest_update(); + + $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $response = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), - 'DELETE', - [ 'force' => false ], - false - ); - $this->assertEquals( 401, $result->status ); - $this->assertNotEquals( 'trash', get_post_status( $coupon->get_id() ) ); - } - - /** - * Test delete. - * - * @return void - */ - public function test_delete_non_existing() { - $result = $this->do_request( - '/wc/v4/coupons/0', - 'DELETE', - [ 'force' => false ] - ); - $this->assertEquals( 404, $result->status ); - } - - /** - * Test creation. - */ - public function test_create() { - $result = $this->do_request( - '/wc/v4/coupons', 'POST', [ - 'code' => 'test', - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - 'description' => 'Test', - 'usage_limit' => 10, + 'code' => 'new-code', + 'description' => 'new description', ] ); - $this->assertEquals( 201, $result->status ); - $this->assertEquals( 'test', $result->data['code'] ); - $this->assertEquals( '5.00', $result->data['amount'] ); - $this->assertEquals( 'fixed_product', $result->data['discount_type'] ); - $this->assertEquals( 'Test', $result->data['description'] ); - $this->assertEquals( 10, $result->data['usage_limit'] ); + $this->assertExpectedResponse( $response, 401 ); } /** - * Test creation. + * Test delete. */ - public function test_create_without_permission() { - $result = $this->do_request( - '/wc/v4/coupons', - 'POST', - [ - 'code' => 'test', - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - 'description' => 'Test', - 'usage_limit' => 10, - ], - false - ); + public function test_guest_delete() { + parent::test_guest_delete(); + + $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); $this->assertEquals( 401, $result->status ); } @@ -179,8 +271,6 @@ class Coupons extends AbstractRestApiTest { 'code' => 'test', 'amount' => '5.00', 'discount_type' => 'fake', - 'description' => 'Test', - 'usage_limit' => 10, ] ); @@ -223,12 +313,10 @@ class Coupons extends AbstractRestApiTest { $this->assertEquals( '5.15', $result->data['update'][0]['amount'] ); $this->assertEquals( '11.00', $result->data['create'][0]['amount'] ); $this->assertEquals( 'new-coupon', $result->data['create'][0]['code'] ); - $this->assertEquals( $coupon_2->get_id(), $result->data['delete'][0]['id'] ); - $this->assertEquals( $coupon_3->get_id(), $result->data['delete'][1]['id'] ); + $this->assertEquals( $coupon_2->get_id(), $result->data['delete'][0]['previous']['id'] ); + $this->assertEquals( $coupon_3->get_id(), $result->data['delete'][1]['previous']['id'] ); - $result = $this->do_request( - '/wc/v4/coupons' - ); + $result = $this->do_request( '/wc/v4/coupons' ); $this->assertEquals( 3, count( $result->data ) ); } } diff --git a/tests/Version4/Onboarding/onboarding-levels.php b/tests/Version4/Onboarding/onboarding-levels.php new file mode 100644 index 00000000000..e7c52b05e22 --- /dev/null +++ b/tests/Version4/Onboarding/onboarding-levels.php @@ -0,0 +1,107 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test that levels are returned by the endpoint. + */ + public function test_get_level_items() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'account', $data[0]['id'] ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 2, $properties ); + $this->assert_item_schema( $properties ); + } + + /** + * Asserts the item schema is correct. + * + * @param array $schema Item to check schema. + */ + public function assert_item_schema( $schema ) { + $this->assertArrayHasKey( 'id', $schema ); + $this->assertArrayHasKey( 'tasks', $schema ); + + $task_properties = $schema['tasks']['items']['properties']; + $this->assertCount( 5, $task_properties ); + $this->assertArrayHasKey( 'id', $task_properties ); + $this->assertArrayHasKey( 'label', $task_properties ); + $this->assertArrayHasKey( 'description', $task_properties ); + $this->assertArrayHasKey( 'illustration', $task_properties ); + $this->assertArrayHasKey( 'status', $task_properties ); + } + + /** + * Test that levels response changes based on applied filters. + */ + public function test_filter_levels() { + wp_set_current_user( $this->user ); + + add_filter( + 'woocommerce_onboarding_levels', + function( $levels ) { + $levels['test_level'] = array( + 'id' => 'test_level', + 'tasks' => array(), + ); + return $levels; + } + ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'test_level', end( $data )['id'] ); + + } +} diff --git a/tests/Version4/Onboarding/onboarding-profile.php b/tests/Version4/Onboarding/onboarding-profile.php new file mode 100644 index 00000000000..5338f51c015 --- /dev/null +++ b/tests/Version4/Onboarding/onboarding-profile.php @@ -0,0 +1,150 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test that profile data is returned by the endpoint. + */ + public function test_get_profile_items() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $properties = WC_Admin_REST_Onboarding_Profile_Controller::get_profile_properties(); + foreach ( $properties as $key => $property ) { + $this->assertArrayHasKey( $key, $properties ); + } + } + + /** + * Test that profile date is updated by the endpoint. + */ + public function test_update_profile_items() { + wp_set_current_user( $this->user ); + + // Test updating 2 fields separately. + $request = new WP_REST_Request( 'POST', $this->endpoint ); + $request->set_headers( array( 'content-type' => 'application/json' ) ); + $request->set_body( wp_json_encode( array( 'industry' => 'health-beauty' ) ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'success', $data['status'] ); + + // Test that the update works. + $request = new WP_REST_Request( 'POST', $this->endpoint ); + $request->set_headers( array( 'content-type' => 'application/json' ) ); + $request->set_body( wp_json_encode( array( 'theme' => 'Storefront' ) ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'success', $data['status'] ); + + // Make sure the original field value wasn't overwritten. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'health-beauty', $data['industry'][0] ); + $this->assertEquals( 'storefront', $data['theme'] ); + } + + /** + * Test schema. + * + * @since 3.5.0 + */ + public function test_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 10, $properties ); + $this->assertArrayHasKey( 'completed', $properties ); + $this->assertArrayHasKey( 'skipped', $properties ); + $this->assertArrayHasKey( 'account_type', $properties ); + $this->assertArrayHasKey( 'industry', $properties ); + $this->assertArrayHasKey( 'product_types', $properties ); + $this->assertArrayHasKey( 'product_count', $properties ); + $this->assertArrayHasKey( 'selling_venues', $properties ); + $this->assertArrayHasKey( 'other_platform', $properties ); + $this->assertArrayHasKey( 'theme', $properties ); + $this->assertArrayHasKey( 'items_purchased', $properties ); + } + + /** + * Test that profiles response changes based on applied filters. + */ + public function test_profile_extensibility() { + wp_set_current_user( $this->user ); + + add_filter( + 'woocommerce_onboarding_profile_properties', + function( $properties ) { + $properties['test_profile_datum'] = array( + 'type' => 'array', + 'description' => __( 'Test onboarding profile extensibility.', 'woocommerce-admin' ), + 'context' => array( 'view' ), + 'readonly' => true, + ); + return $properties; + } + ); + + // Test that the update works. + $request = new WP_REST_Request( 'POST', $this->endpoint ); + $request->set_headers( array( 'content-type' => 'application/json' ) ); + $request->set_body( wp_json_encode( array( 'test_profile_datum' => 'woo' ) ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'success', $data['status'] ); + + // Test that the new field is retrieved. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'woo', $data['test_profile_datum'] ); + } +} diff --git a/tests/Version4/Orders.php b/tests/Version4/Orders.php new file mode 100644 index 00000000000..15ee8e399a3 --- /dev/null +++ b/tests/Version4/Orders.php @@ -0,0 +1,657 @@ +[\d]+)', + '/wc/v4/orders/batch', + ]; + + /** + * The endpoint schema. + * + * @var array Keys are property names, values are supported context. + */ + protected $properties = [ + 'id' => array( 'view', 'edit' ), + 'parent_id' => array( 'view', 'edit' ), + 'number' => array( 'view', 'edit' ), + 'order_key' => array( 'view', 'edit' ), + 'created_via' => array( 'view', 'edit' ), + 'version' => array( 'view', 'edit' ), + 'status' => array( 'view', 'edit' ), + 'currency' => array( 'view', 'edit' ), + 'currency_symbol' => array( 'view', 'edit' ), + 'date_created' => array( 'view', 'edit' ), + 'date_created_gmt' => array( 'view', 'edit' ), + 'date_modified' => array( 'view', 'edit' ), + 'date_modified_gmt' => array( 'view', 'edit' ), + 'discount_total' => array( 'view', 'edit' ), + 'discount_tax' => array( 'view', 'edit' ), + 'shipping_total' => array( 'view', 'edit' ), + 'shipping_tax' => array( 'view', 'edit' ), + 'cart_tax' => array( 'view', 'edit' ), + 'total' => array( 'view', 'edit' ), + 'total_tax' => array( 'view', 'edit' ), + 'prices_include_tax' => array( 'view', 'edit' ), + 'customer_id' => array( 'view', 'edit' ), + 'customer_ip_address' => array( 'view', 'edit' ), + 'customer_user_agent' => array( 'view', 'edit' ), + 'customer_note' => array( 'view', 'edit' ), + 'billing' => array( 'view', 'edit' ), + 'shipping' => array( 'view', 'edit' ), + 'payment_method' => array( 'view', 'edit' ), + 'payment_method_title' => array( 'view', 'edit' ), + 'transaction_id' => array( 'view', 'edit' ), + 'date_paid' => array( 'view', 'edit' ), + 'date_paid_gmt' => array( 'view', 'edit' ), + 'date_completed' => array( 'view', 'edit' ), + 'date_completed_gmt' => array( 'view', 'edit' ), + 'cart_hash' => array( 'view', 'edit' ), + 'meta_data' => array( 'view', 'edit' ), + 'line_items' => array( 'view', 'edit' ), + 'tax_lines' => array( 'view', 'edit' ), + 'shipping_lines' => array( 'view', 'edit' ), + 'fee_lines' => array( 'view', 'edit' ), + 'coupon_lines' => array( 'view', 'edit' ), + 'refunds' => array( 'view', 'edit' ), + 'set_paid' => array( 'edit' ), + ]; + + /** + * Test create. + */ + public function test_create() { + $product = \WC_Helper_Product::create_simple_product(); + $data = [ + 'currency' => 'ZAR', + 'customer_id' => 1, + 'customer_note' => 'I am a note', + 'transaction_id' => 'test', + 'payment_method' => 'bacs', + 'payment_method_title' => 'Direct Bank Transfer', + 'set_paid' => true, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'company' => '', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'company' => '', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => '10', + ), + ), + ]; + $response = $this->do_request( '/wc/v4/orders', 'POST', $data ); + $this->assertExpectedResponse( $response, 201, $data ); + } + + /** + * Test the sanitization of the payment_method_title field through the API. + * + * @since 3.5.2 + */ + public function test_create_update_order_payment_method_title_sanitize() { + $product = \WC_Helper_Product::create_simple_product(); + $data = [ + 'payment_method' => 'bacs', + 'payment_method_title' => '

Sanitize this

', + 'set_paid' => true, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => '10', + ), + ), + ]; + $response = $this->do_request( '/wc/v4/orders', 'POST', $data ); + $order = wc_get_order( $response->data['id'] ); + $this->assertExpectedResponse( $response, 201 ); + $this->assertEquals( $order->get_payment_method(), $response->data['payment_method'] ); + $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this' ); + + // Test when updating order. + $response = $this->do_request( + '/wc/v4/orders/' . $response->data['id'], + 'POST', [ + 'payment_method' => 'bacs', + 'payment_method_title' => '

Sanitize this too

', + ] + ); + $order = wc_get_order( $response->data['id'] ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( $order->get_payment_method(), $response->data['payment_method'] ); + $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this too' ); + } + + /** + * Tests creating an order without required fields. + * @since 3.5.0 + */ + public function test_create_order_invalid_fields() { + $product = \WC_Helper_Product::create_simple_product(); + $data = [ + 'payment_method' => 'bacs', + 'payment_method_title' => 'Direct Bank Transfer', + 'set_paid' => true, + 'customer_id' => 99999, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => 10, + ), + ), + ]; + $response = $this->do_request( '/wc/v4/orders', 'POST', $data ); + $this->assertExpectedResponse( $response, 400 ); + } + + /** + * Test read. + */ + public function test_read() { + $product = \WC_Helper_Product::create_simple_product(); + $product->set_regular_price( 10.95 ); + $product->set_sale_price( false ); + $product->save(); + $customer = \WC_Helper_Customer::create_customer(); + $orders = []; + $orders[] = \WC_Helper_Order::create_order( $customer->get_id(), $product ); + + // Create orders. + for ( $i = 0; $i < 9; $i++ ) { + $orders[] = \WC_Helper_Order::create_order( $this->user ); + } + + $orders[5]->set_status( 'on-hold' ); + $orders[5]->save(); + $orders[6]->set_status( 'on-hold' ); + $orders[6]->save(); + $orders[0]->calculate_totals(); + $orders[0]->save(); + + // Collection. + $response = $this->do_request( '/wc/v4/orders', 'GET' ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 10, count( $response->data ) ); + + // Collection args. + $response = $this->do_request( '/wc/v4/orders', 'GET', [ 'status' => 'on-hold' ] ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 2, count( $response->data ) ); + + $response = $this->do_request( '/wc/v4/orders', 'GET', [ 'number' => (string) $orders[0]->get_id() ] ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 1, count( $response->data ) ); + + $response = $this->do_request( '/wc/v4/orders', 'GET', [ 'customer' => $customer->get_id() ] ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 1, count( $response->data ) ); + + $response = $this->do_request( '/wc/v4/orders', 'GET', [ 'product' => $product->get_id() ] ); + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 1, count( $response->data ) ); + + // Single collection args. + $response = $this->do_request( '/wc/v4/orders/' . $orders[0]->get_id(), 'GET', [ 'dp' => 0 ] ); + $this->assertEquals( '54', $response->data['total'] ); + $response = $this->do_request( '/wc/v4/orders/' . $orders[0]->get_id(), 'GET', [ 'dp' => 2 ] ); + $this->assertEquals( '53.80', $response->data['total'] ); + + // Single. + $response = $this->do_request( '/wc/v4/orders/' . $orders[0]->get_id(), 'GET' ); + $this->assertExpectedResponse( $response, 200 ); + + foreach ( $this->get_properties( 'view' ) as $property ) { + $this->assertArrayHasKey( $property, $response->data ); + } + + // Invalid. + $response = $this->do_request( '/wc/v4/orders/0', 'GET' ); + $this->assertExpectedResponse( $response, 404 ); + } + + /** + * Test update. + */ + public function test_update() { + // Invalid. + $response = $this->do_request( '/wc/v4/orders/0', 'POST', [ 'payment_method' => 'test' ] ); + $this->assertExpectedResponse( $response, 404 ); + + // Update existing. + $order = \WC_Helper_Order::create_order(); + $data = [ + 'payment_method' => 'test-update', + 'billing' => array( + 'first_name' => 'Fish', + 'last_name' => 'Face', + ), + ]; + $response = $this->do_request( + '/wc/v4/orders/' . $order->get_id(), + 'POST', + $data + ); + $this->assertExpectedResponse( $response, 200, $data ); + + foreach ( $this->get_properties( 'view' ) as $property ) { + $this->assertArrayHasKey( $property, $response->data ); + } + } + + /** + * Test delete. + */ + public function test_delete() { + // Invalid. + $result = $this->do_request( '/wc/v4/orders/0', 'DELETE', [ 'force' => false ] ); + $this->assertEquals( 404, $result->status ); + + // Trash. + $order = \WC_Helper_Order::create_order(); + $result = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => false ] ); + $this->assertEquals( 200, $result->status ); + $this->assertEquals( 'trash', get_post_status( $order->get_id() ) ); + + // Force. + $order = \WC_Helper_Order::create_order(); + $result = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => true ] ); + $this->assertEquals( 200, $result->status ); + $this->assertEquals( false, get_post( $order->get_id() ) ); + } + + /** + * Test read. + */ + public function test_guest_create() { + parent::test_guest_create(); + + $product = \WC_Helper_Product::create_simple_product(); + $data = [ + 'currency' => 'ZAR', + 'customer_id' => 1, + 'customer_note' => 'I am a note', + 'transaction_id' => 'test', + 'payment_method' => 'bacs', + 'payment_method_title' => 'Direct Bank Transfer', + 'set_paid' => true, + 'billing' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'company' => '', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + 'email' => 'john.doe@example.com', + 'phone' => '(555) 555-5555', + ), + 'shipping' => array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'company' => '', + 'address_1' => '969 Market', + 'address_2' => '', + 'city' => 'San Francisco', + 'state' => 'CA', + 'postcode' => '94103', + 'country' => 'US', + ), + 'line_items' => array( + array( + 'product_id' => $product->get_id(), + 'quantity' => 2, + ), + ), + 'shipping_lines' => array( + array( + 'method_id' => 'flat_rate', + 'method_title' => 'Flat rate', + 'total' => '10', + ), + ), + ]; + $response = $this->do_request( '/wc/v4/orders', 'POST', $data ); + $this->assertExpectedResponse( $response, 401, $data ); + } + + /** + * Test read. + */ + public function test_guest_read() { + parent::test_guest_read(); + + $response = $this->do_request( '/wc/v4/orders', 'GET' ); + $this->assertExpectedResponse( $response, 401 ); + } + + /** + * Test update. + */ + public function test_guest_update() { + parent::test_guest_update(); + + $order = \WC_Helper_Order::create_order(); + $data = [ + 'payment_method' => 'test-update', + 'billing' => array( + 'first_name' => 'Fish', + 'last_name' => 'Face', + ), + ]; + $response = $this->do_request( + '/wc/v4/orders/' . $order->get_id(), + 'POST', + $data + ); + $this->assertExpectedResponse( $response, 401 ); + } + + /** + * Test delete. + */ + public function test_guest_delete() { + parent::test_guest_delete(); + + $order = \WC_Helper_Order::create_order(); + $response = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => true ] ); + $this->assertEquals( 401, $response->status ); + } + + /** + * Test validation. + */ + public function test_enums() { + $order = \WC_Helper_Order::create_order(); + + $response = $this->do_request( + '/wc/v4/orders/' . $order->get_id(), + 'POST', + [ + 'status' => 'invalid', + ] + ); + $this->assertEquals( 400, $response->status ); + $this->assertEquals( 'Invalid parameter(s): status', $response->data['message'] ); + + $response = $this->do_request( + '/wc/v4/orders/' . $order->get_id(), + 'POST', + [ + 'currency' => 'invalid', + ] + ); + $this->assertEquals( 400, $response->status ); + $this->assertEquals( 'Invalid parameter(s): currency', $response->data['message'] ); + } + + /** + * Test a batch update. + */ + public function test_batch() { + $order1 = \WC_Helper_Order::create_order(); + $order2 = \WC_Helper_Order::create_order(); + $order3 = \WC_Helper_Order::create_order(); + + $result = $this->do_request( + '/wc/v4/orders/batch', + 'POST', + array( + 'update' => array( + array( + 'id' => $order1->get_id(), + 'payment_method' => 'updated', + ), + ), + 'delete' => array( + $order2->get_id(), + $order3->get_id(), + ), + ) + ); + $this->assertEquals( 'updated', $result->data['update'][0]['payment_method'] ); + $this->assertEquals( $order2->get_id(), $result->data['delete'][0]['previous']['id'] ); + $this->assertEquals( $order3->get_id(), $result->data['delete'][1]['previous']['id'] ); + + $result = $this->do_request( '/wc/v4/orders' ); + $this->assertEquals( 1, count( $result->data ) ); + } + + /** + * Tests updating an order and removing items. + * + * @since 3.5.0 + */ + public function test_update_order_remove_items() { + $order = \WC_Helper_Order::create_order(); + $fee = new \WC_Order_Item_Fee(); + $fee->set_props( + array( + 'name' => 'Some Fee', + 'tax_status' => 'taxable', + 'total' => '100', + 'tax_class' => '', + ) + ); + $order->add_item( $fee ); + $order->save(); + + $fee_data = current( $order->get_items( 'fee' ) ); + $response = $this->do_request( + '/wc/v3/orders/' . $order->get_id(), + 'PUT', + [ + 'fee_lines' => array( + array( + 'id' => $fee_data->get_id(), + 'name' => null, + ), + ), + ] + ); + $this->assertEquals( 200, $response->status ); + $this->assertTrue( empty( $response->data['fee_lines'] ) ); + } + + /** + * Tests updating an order and adding a coupon. + * + * @since 3.5.0 + */ + public function test_update_order_add_coupons() { + $order = \WC_Helper_Order::create_order(); + $order_item = current( $order->get_items() ); + $coupon = \WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon->set_amount( 5 ); + $coupon->save(); + + $response = $this->do_request( + '/wc/v3/orders/' . $order->get_id(), + 'PUT', + [ + 'coupon_lines' => array( + array( + 'code' => 'fake-coupon', + ), + ), + ] + ); + $this->assertEquals( 200, $response->status ); + $this->assertCount( 1, $response->data['coupon_lines'] ); + $this->assertEquals( '45.00', $response->data['total'] ); + } + + /** + * Tests updating an order and removing a coupon. + * + * @since 3.5.0 + */ + public function test_update_order_remove_coupons() { + $order = \WC_Helper_Order::create_order(); + $order_item = current( $order->get_items() ); + $coupon = \WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon->set_amount( 5 ); + $coupon->save(); + $order->apply_coupon( $coupon ); + $order->save(); + + // Check that the coupon is applied. + $this->assertEquals( '45.00', $order->get_total() ); + + $coupon_data = current( $order->get_items( 'coupon' ) ); + $response = $this->do_request( + '/wc/v3/orders/' . $order->get_id(), + 'PUT', + [ + 'coupon_lines' => array( + array( + 'id' => $coupon_data->get_id(), + 'code' => null, + ), + ), + 'line_items' => array( + array( + 'id' => $order_item->get_id(), + 'product_id' => $order_item->get_product_id(), + 'total' => '40.00', + ), + ), + ] + ); + $this->assertEquals( 200, $response->status ); + $this->assertTrue( empty( $response->data['coupon_lines'] ) ); + $this->assertEquals( '50.00', $response->data['total'] ); + } + + /** + * Tests updating an order with an invalid coupon. + * + * @since 3.5.0 + */ + public function test_invalid_coupon() { + $order = \WC_Helper_Order::create_order(); + $response = $this->do_request( + '/wc/v3/orders/' . $order->get_id(), + 'PUT', + [ + 'coupon_lines' => array( + array( + 'code' => 'NON_EXISTING_COUPON', + ), + ), + ] + ); + $this->assertEquals( 400, $response->status ); + $this->assertEquals( 'woocommerce_rest_invalid_coupon', $response->data['code'] ); + $this->assertEquals( 'Coupon "non_existing_coupon" does not exist!', $response->data['message'] ); + } +} diff --git a/tests/Version4/Reports/reports-categories.php b/tests/Version4/Reports/reports-categories.php new file mode 100644 index 00000000000..f1a72528768 --- /dev/null +++ b/tests/Version4/Reports/reports-categories.php @@ -0,0 +1,182 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + WC_Helper_Reports::reset_stats_dbs(); + wp_set_current_user( $this->user ); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + + $category_report = reset( $reports ); + + $this->assertEquals( $uncategorized_term->term_id, $category_report['category_id'] ); + $this->assertEquals( 4, $category_report['items_sold'] ); + $this->assertEquals( 1, $category_report['orders_count'] ); + $this->assertEquals( 1, $category_report['products_count'] ); + $this->assertArrayHasKey( '_links', $category_report ); + $this->assertArrayHasKey( 'category', $category_report['_links'] ); + } + + /** + * Test getting reports with the `categories` param. + * + * @since 3.5.0 + */ + public function test_get_reports_categories_param() { + WC_Helper_Reports::reset_stats_dbs(); + wp_set_current_user( $this->user ); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product 2' ); + $product->set_regular_price( 100 ); + $second_category_id = wp_create_category( 'Second Category' ); + $product->set_category_ids( array( $second_category_id ) ); + $product->save(); + + WC_Helper_Queue::run_all_pending(); + + $uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'categories' => $uncategorized_term->term_id . ',' . $second_category_id, + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $category_report = reset( $reports ); + + $this->assertEquals( $second_category_id, $category_report['category_id'] ); + $this->assertEquals( 0, $category_report['items_sold'] ); + $this->assertEquals( 0, $category_report['orders_count'] ); + $this->assertEquals( 0, $category_report['products_count'] ); + $this->assertArrayHasKey( '_links', $category_report ); + $this->assertArrayHasKey( 'category', $category_report['_links'] ); + + $category_report = next( $reports ); + + $this->assertEquals( $uncategorized_term->term_id, $category_report['category_id'] ); + $this->assertEquals( 4, $category_report['items_sold'] ); + $this->assertEquals( 1, $category_report['orders_count'] ); + $this->assertEquals( 1, $category_report['products_count'] ); + $this->assertArrayHasKey( '_links', $category_report ); + $this->assertArrayHasKey( 'category', $category_report['_links'] ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 6, count( $properties ) ); + $this->assertArrayHasKey( 'category_id', $properties ); + $this->assertArrayHasKey( 'items_sold', $properties ); + $this->assertArrayHasKey( 'net_revenue', $properties ); + $this->assertArrayHasKey( 'orders_count', $properties ); + $this->assertArrayHasKey( 'products_count', $properties ); + $this->assertArrayHasKey( 'extended_info', $properties ); + } +} diff --git a/tests/Version4/Reports/reports-coupons-stats.php b/tests/Version4/Reports/reports-coupons-stats.php new file mode 100644 index 00000000000..a17f10a37db --- /dev/null +++ b/tests/Version4/Reports/reports-coupons-stats.php @@ -0,0 +1,180 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + */ + public function test_get_reports() { + WC_Helper_Reports::reset_stats_dbs(); + wp_set_current_user( $this->user ); + + // Populate all of the data. + // Simple product. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + // Coupons. + $coupon_1_amount = 1; // by default in create_coupon. + $coupon_1 = WC_Helper_Coupon::create_coupon( 'coupon_1' ); + + $coupon_2_amount = 2; + $coupon_2 = WC_Helper_Coupon::create_coupon( 'coupon_2' ); + $coupon_2->set_amount( $coupon_2_amount ); + $coupon_2->save(); + + // Order without coupon. + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + $time = time(); + + // Order with 1 coupon. + $order_1c = WC_Helper_Order::create_order( 1, $product ); + $order_1c->set_status( 'completed' ); + $order_1c->apply_coupon( $coupon_1 ); + $order_1c->calculate_totals(); + $order_1c->set_date_created( $time ); + $order_1c->save(); + + // Order with 2 coupons. + $order_2c = WC_Helper_Order::create_order( 1, $product ); + $order_2c->set_status( 'completed' ); + $order_2c->apply_coupon( $coupon_1 ); + $order_2c->apply_coupon( $coupon_2 ); + $order_2c->calculate_totals(); + $order_2c->set_date_created( $time ); + $order_2c->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d 00:00:00', $time ), + 'interval' => 'day', + ) + ); + + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $expected_reports = array( + 'totals' => array( + 'amount' => 4.0, + 'coupons_count' => 2, + 'orders_count' => 2, + 'segments' => array(), + ), + 'intervals' => array( + array( + 'interval' => date( 'Y-m-d', $time ), + 'date_start' => date( 'Y-m-d 00:00:00', $time ), + 'date_start_gmt' => date( 'Y-m-d 00:00:00', $time ), + 'date_end' => date( 'Y-m-d 23:59:59', $time ), + 'date_end_gmt' => date( 'Y-m-d 23:59:59', $time ), + 'subtotals' => (object) array( + 'amount' => 4.0, + 'coupons_count' => 2, + 'orders_count' => 2, + 'segments' => array(), + ), + ), + ), + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $expected_reports, $reports ); + } + + /** + * Test getting reports without valid permissions. + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 2, count( $properties ) ); + $this->assertArrayHasKey( 'totals', $properties ); + $this->assertArrayHasKey( 'intervals', $properties ); + + $totals = $properties['totals']['properties']; + $this->assertEquals( 4, count( $totals ) ); + $this->assertArrayHasKey( 'amount', $totals ); + $this->assertArrayHasKey( 'coupons_count', $totals ); + $this->assertArrayHasKey( 'orders_count', $totals ); + $this->assertArrayHasKey( 'segments', $totals ); + + $intervals = $properties['intervals']['items']['properties']; + $this->assertEquals( 6, count( $intervals ) ); + $this->assertArrayHasKey( 'interval', $intervals ); + $this->assertArrayHasKey( 'date_start', $intervals ); + $this->assertArrayHasKey( 'date_start_gmt', $intervals ); + $this->assertArrayHasKey( 'date_end', $intervals ); + $this->assertArrayHasKey( 'date_end_gmt', $intervals ); + $this->assertArrayHasKey( 'subtotals', $intervals ); + + $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; + $this->assertEquals( 4, count( $subtotals ) ); + $this->assertArrayHasKey( 'amount', $subtotals ); + $this->assertArrayHasKey( 'coupons_count', $subtotals ); + $this->assertArrayHasKey( 'orders_count', $subtotals ); + $this->assertArrayHasKey( 'segments', $subtotals ); + + } +} diff --git a/tests/Version4/Reports/reports-coupons.php b/tests/Version4/Reports/reports-coupons.php new file mode 100644 index 00000000000..5e9ee2675d1 --- /dev/null +++ b/tests/Version4/Reports/reports-coupons.php @@ -0,0 +1,188 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting basic reports. + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Simple product. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + // Coupons. + $coupon_1_amount = 1; // by default in create_coupon. + $coupon_1 = WC_Helper_Coupon::create_coupon( 'coupon_1' ); + + $coupon_2_amount = 2; + $coupon_2 = WC_Helper_Coupon::create_coupon( 'coupon_2' ); + $coupon_2->set_amount( $coupon_2_amount ); + $coupon_2->save(); + + // Order without coupon. + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + // Order with 1 coupon. + $order_1c = WC_Helper_Order::create_order( 1, $product ); + $order_1c->set_status( 'completed' ); + $order_1c->apply_coupon( $coupon_1 ); + $order_1c->calculate_totals(); + $order_1c->save(); + + // Order with 2 coupons. + $order_2c = WC_Helper_Order::create_order( 1, $product ); + $order_2c->set_status( 'completed' ); + $order_2c->apply_coupon( $coupon_1 ); + $order_2c->apply_coupon( $coupon_2 ); + $order_2c->calculate_totals(); + $order_2c->save(); + + WC_Helper_Queue::run_all_pending(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $coupon_reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $coupon_reports ) ); + + $this->assertEquals( $coupon_2->get_id(), $coupon_reports[0]['coupon_id'] ); + $this->assertEquals( 1 * $coupon_2_amount, $coupon_reports[0]['amount'] ); + $this->assertEquals( 1, $coupon_reports[0]['orders_count'] ); + $this->assertArrayHasKey( '_links', $coupon_reports[0] ); + $this->assertArrayHasKey( 'coupon', $coupon_reports[0]['_links'] ); + + $this->assertEquals( $coupon_1->get_id(), $coupon_reports[1]['coupon_id'] ); + $this->assertEquals( 2 * $coupon_1_amount, $coupon_reports[1]['amount'] ); + $this->assertEquals( 2, $coupon_reports[1]['orders_count'] ); + $this->assertArrayHasKey( '_links', $coupon_reports[1] ); + $this->assertArrayHasKey( 'coupon', $coupon_reports[1]['_links'] ); + } + + /** + * Test getting basic reports with the `coupons` param. + */ + public function test_get_reports_coupons_param() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Simple product. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + // Coupons. + $coupon_1_amount = 1; // by default in create_coupon. + $coupon_1 = WC_Helper_Coupon::create_coupon( 'coupon_1' ); + + $coupon_2_amount = 2; + $coupon_2 = WC_Helper_Coupon::create_coupon( 'coupon_2' ); + $coupon_2->set_amount( $coupon_2_amount ); + $coupon_2->save(); + + // Order with 1 coupon. + $order_1c = WC_Helper_Order::create_order( 1, $product ); + $order_1c->set_status( 'completed' ); + $order_1c->apply_coupon( $coupon_1 ); + $order_1c->calculate_totals(); + $order_1c->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'coupons' => $coupon_1->get_id() . ',' . $coupon_2->get_id(), + ) + ); + $response = $this->server->dispatch( $request ); + $coupon_reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $coupon_reports ) ); + + $this->assertEquals( $coupon_2->get_id(), $coupon_reports[0]['coupon_id'] ); + $this->assertEquals( 0, $coupon_reports[0]['amount'] ); + $this->assertEquals( 0, $coupon_reports[0]['orders_count'] ); + $this->assertArrayHasKey( '_links', $coupon_reports[0] ); + $this->assertArrayHasKey( 'coupon', $coupon_reports[0]['_links'] ); + + $this->assertEquals( $coupon_1->get_id(), $coupon_reports[1]['coupon_id'] ); + $this->assertEquals( $coupon_1_amount, $coupon_reports[1]['amount'] ); + $this->assertEquals( 1, $coupon_reports[1]['orders_count'] ); + $this->assertArrayHasKey( '_links', $coupon_reports[1] ); + $this->assertArrayHasKey( 'coupon', $coupon_reports[1]['_links'] ); + } + + /** + * Test getting reports without valid permissions. + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 4, count( $properties ) ); + $this->assertArrayHasKey( 'coupon_id', $properties ); + $this->assertArrayHasKey( 'amount', $properties ); + $this->assertArrayHasKey( 'orders_count', $properties ); + $this->assertArrayHasKey( 'extended_info', $properties ); + } +} diff --git a/tests/Version4/Reports/reports-customers-stats.php b/tests/Version4/Reports/reports-customers-stats.php new file mode 100644 index 00000000000..e31805ce5b4 --- /dev/null +++ b/tests/Version4/Reports/reports-customers-stats.php @@ -0,0 +1,172 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 1, $properties ); + $this->assertArrayHasKey( 'totals', $properties ); + $this->assertCount( 4, $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'customers_count', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'avg_orders_count', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'avg_total_spend', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'avg_avg_order_value', $properties['totals']['properties'] ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + $test_customers = array(); + + // Create 10 test customers. + for ( $i = 1; $i <= 10; $i++ ) { + $test_customers[] = WC_Helper_Customer::create_customer( "customer{$i}", 'password', "customer{$i}@example.com" ); + } + // One differing name. + $test_customers[2]->set_first_name( 'Jeff' ); + $test_customers[2]->save(); + + // Create a test product for use in an order. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + // Place some test orders. + $order = WC_Helper_Order::create_order( $test_customers[0]->get_id(), $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); + $order->save(); + + $order = WC_Helper_Order::create_order( $test_customers[0]->get_id(), $product ); + $order->set_status( 'completed' ); + $order->set_total( 234 ); + $order->save(); + + $order = WC_Helper_Order::create_order( $test_customers[1]->get_id(), $product ); + $order->set_status( 'completed' ); + $order->set_total( 55 ); + $order->save(); + + $order = WC_Helper_Order::create_order( $test_customers[2]->get_id(), $product ); + $order->set_status( 'completed' ); + $order->set_total( 9.12 ); + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 10, $reports['totals']->customers_count ); + $this->assertEquals( 1.333, round( $reports['totals']->avg_orders_count, 3 ) ); + $this->assertEquals( 132.707, round( $reports['totals']->avg_total_spend, 3 ) ); + $this->assertEquals( 77.04, $reports['totals']->avg_avg_order_value ); + + // Test name parameter (case with no matches). + $request->set_query_params( + array( + 'search' => 'Nota Customername', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 0, $reports['totals']->customers_count ); + $this->assertEquals( 0, $reports['totals']->avg_orders_count ); + $this->assertEquals( 0, $reports['totals']->avg_total_spend ); + $this->assertEquals( 0, $reports['totals']->avg_avg_order_value ); + + // Test name and last_order parameters. + $request->set_query_params( + array( + 'search' => 'Jeff', + 'last_order_after' => date( 'Y-m-d' ) . 'T00:00:00Z', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, $reports['totals']->customers_count ); + $this->assertEquals( 1, $reports['totals']->avg_orders_count ); + $this->assertEquals( 9.12, $reports['totals']->avg_total_spend ); + $this->assertEquals( 9.12, $reports['totals']->avg_avg_order_value ); + } +} diff --git a/tests/Version4/Reports/reports-customers.php b/tests/Version4/Reports/reports-customers.php new file mode 100644 index 00000000000..9cc62060cbc --- /dev/null +++ b/tests/Version4/Reports/reports-customers.php @@ -0,0 +1,405 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Asserts the report item schema is correct. + * + * @param array $schema Item to check schema. + */ + public function assert_report_item_schema( $schema ) { + $this->assertArrayHasKey( 'id', $schema ); + $this->assertArrayHasKey( 'user_id', $schema ); + $this->assertArrayHasKey( 'name', $schema ); + $this->assertArrayHasKey( 'username', $schema ); + $this->assertArrayHasKey( 'country', $schema ); + $this->assertArrayHasKey( 'city', $schema ); + $this->assertArrayHasKey( 'postcode', $schema ); + $this->assertArrayHasKey( 'date_registered', $schema ); + $this->assertArrayHasKey( 'date_registered_gmt', $schema ); + $this->assertArrayHasKey( 'date_last_active', $schema ); + $this->assertArrayHasKey( 'date_last_active_gmt', $schema ); + $this->assertArrayHasKey( 'orders_count', $schema ); + $this->assertArrayHasKey( 'total_spend', $schema ); + $this->assertArrayHasKey( 'avg_order_value', $schema ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 14, $properties ); + $this->assert_report_item_schema( $properties ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test calling update_registered_customer() with a bad user id. + * + * @since 3.5.0 + */ + public function test_update_registered_customer_with_bad_user_id() { + $result = WC_Admin_Reports_Customers_Data_Store::update_registered_customer( 2 ); + $this->assertFalse( $result ); + } + + /** + * Test creation of various user roles + * + * @since 3.5.0 + */ + public function test_user_creation() { + wp_set_current_user( $this->user ); + $admin_id = wp_insert_user( + array( + 'user_login' => 'testadmin', + 'user_pass' => null, + 'role' => 'administrator', + ) + ); + + // Admin user without orders should not be shown. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'per_page' => 10 ) ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 0, $reports ); + + // Creating an order with admin should return the admin. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( $admin_id, $product ); + $order->set_status( 'processing' ); + $order->set_total( 100 ); + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'per_page' => 10 ) ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + $this->assertEquals( $admin_id, $reports[0]['user_id'] ); + + // Creating a customer should show up regardless of orders. + $customer = WC_Helper_Customer::create_customer( 'customer', 'password', 'customer@example.com' ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'per_page' => 10, + 'order' => 'asc', + 'orderby' => 'username', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 2, $reports ); + $this->assertEquals( $customer->get_id(), $reports[0]['user_id'] ); + $this->assertEquals( $admin_id, $reports[1]['user_id'] ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + global $wpdb; + + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + $test_customers = array(); + + $customer_names = array( 'Alice', 'Betty', 'Catherine', 'Dan', 'Eric', 'Fred', 'Greg', 'Henry', 'Ivan', 'Justin' ); + + // Create 10 test customers. + for ( $i = 1; $i <= 10; $i++ ) { + $name = $customer_names[ $i - 1 ]; + $email = 'customer+' . strtolower( $name ) . '@example.com'; + $customer = WC_Helper_Customer::create_customer( "customer{$i}", 'password', $email ); + $customer->set_first_name( $name ); + $customer->save(); + $test_customers[] = $customer; + } + + // Create a test product for use in an order. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + // Place an order for the first test customer. + $order = WC_Helper_Order::create_order( $test_customers[0]->get_id(), $product ); + $order->set_status( 'processing' ); + $order->set_total( 100 ); + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'per_page' => 5, + 'order' => 'asc', + 'orderby' => 'username', + ) + ); + + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 5, $reports ); + $this->assertArrayHasKey( 'X-WP-Total', $headers ); + $this->assertEquals( 10, $headers['X-WP-Total'] ); + $this->assertArrayHasKey( 'X-WP-TotalPages', $headers ); + $this->assertEquals( 2, $headers['X-WP-TotalPages'] ); + $this->assertEquals( $test_customers[0]->get_id(), $reports[0]['user_id'] ); + $this->assertEquals( 1, $reports[0]['orders_count'] ); + $this->assertEquals( 100, $reports[0]['total_spend'] ); + $this->assert_report_item_schema( $reports[0] ); + + // Test name parameter (case with no matches). + $request->set_query_params( + array( + 'search' => 'Nota Customername', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 0, $reports ); + + // Test name parameter (partial match). + $request->set_query_params( + array( + 'search' => 're', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 2, $reports ); + + // Test email search. + $request->set_query_params( + array( + 'search' => 'customer+justin', + 'searchby' => 'email', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + + // Test username search. + $request->set_query_params( + array( + 'search' => 'customer1', + 'searchby' => 'username', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + // customer1 and customer10. + $this->assertCount( 2, $reports ); + + // Test name and last_order parameters. + $request->set_query_params( + array( + 'search' => 'Alice', + 'last_order_after' => date( 'Y-m-d' ) . 'T00:00:00Z', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + + $this->assertEquals( $test_customers[0]->get_id(), $reports[0]['user_id'] ); + $this->assertEquals( 1, $reports[0]['orders_count'] ); + $this->assertEquals( 100, $reports[0]['total_spend'] ); + + $customer_id = $wpdb->get_col( + $wpdb->prepare( + "SELECT customer_id FROM {$wpdb->prefix}wc_customer_lookup WHERE user_id = %d", + $reports[0]['user_id'] + ) + ); + + // Test customers param. + $request->set_query_params( + array( + 'customers' => $customer_id, + ) + ); + + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + $this->assertEquals( $test_customers[0]->get_id(), $reports[0]['user_id'] ); + } + + /** + * Test customer first and last name. + */ + public function test_customer_name() { + wp_set_current_user( $this->user ); + + $customer = wp_insert_user( + array( + 'user_login' => 'daenerys', + 'user_pass' => null, + 'role' => 'customer', + ) + ); + + // Test shipping name and empty billing name. + $order = WC_Helper_Order::create_order( $customer ); + $order->set_billing_first_name( '' ); + $order->set_billing_last_name( '' ); + $order->set_shipping_first_name( 'Daenerys' ); + $order->set_shipping_last_name( 'Targaryen' ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + $this->assertEquals( 'Daenerys Targaryen', $reports[0]['name'] ); + + // Test billing name. + $order->set_billing_first_name( 'Jon' ); + $order->set_billing_last_name( 'Snow' ); + $order->save(); + do_action( 'woocommerce_update_customer', $customer ); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'orderby' => 'username' ) ); // Cache busting. + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + $this->assertEquals( 'Jon Snow', $reports[0]['name'] ); + + // Test user profile name. + wp_update_user( + array( + 'ID' => $customer, + 'first_name' => 'Tyrion', + 'last_name' => 'Lanister', + ) + ); + do_action( 'woocommerce_update_customer', $customer ); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'orderby' => 'name' ) ); // Cache busting. + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + $this->assertEquals( 'Tyrion Lanister', $reports[0]['name'] ); + } +} diff --git a/tests/Version4/Reports/reports-downloads-stats.php b/tests/Version4/Reports/reports-downloads-stats.php new file mode 100644 index 00000000000..660057b24b0 --- /dev/null +++ b/tests/Version4/Reports/reports-downloads-stats.php @@ -0,0 +1,365 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting report. + */ + public function test_get_report() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $prod_download = new WC_Product_Download(); + $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); + $prod_download->set_id( 1 ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_downloadable( 'yes' ); + $product->set_downloads( array( $prod_download ) ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); + $order->save(); + + $download = new WC_Customer_Download(); + $download->set_user_id( $this->user ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $id = $object->save(); + + $time = time(); + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d H:00:00', $time - ( 7 * DAY_IN_SECONDS ) ), + 'interval' => 'day', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $totals = array( + 'download_count' => 1, + ); + $this->assertEquals( $totals, $reports['totals'] ); + + $today_interval = array( + 'interval' => date( 'Y-m-d', $time ), + 'date_start' => date( 'Y-m-d 00:00:00', $time ), + 'date_start_gmt' => date( 'Y-m-d 00:00:00', $time ), + 'date_end' => date( 'Y-m-d 23:59:59', $time ), + 'date_end_gmt' => date( 'Y-m-d 23:59:59', $time ), + 'subtotals' => (object) array( + 'download_count' => 1, + ), + ); + $this->assertEquals( $today_interval, $reports['intervals'][0] ); + + $this->assertEquals( 8, count( $reports['intervals'] ) ); + $this->assertEquals( 0, $reports['intervals'][1]['subtotals']->download_count ); + + // Test sorting by download_count. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d H:00:00', $time - ( 7 * DAY_IN_SECONDS ) ), + 'interval' => 'day', + 'orderby' => 'download_count', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + } + + /** + * Test getting report with user filter. + */ + public function test_get_report_with_user_filter() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + $time = time(); + + // First set of data. + $prod_download = new WC_Product_Download(); + $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); + $prod_download->set_id( 1 ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_downloadable( 'yes' ); + $product->set_downloads( array( $prod_download ) ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 25 ); + $order->save(); + $order_1 = $order->get_id(); + + $download = new WC_Customer_Download(); + $download->set_user_id( 1 ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + for ( $i = 1; $i < 3; $i++ ) { + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( 1 ); + $object->set_user_ip_address( '1.2.3.4' ); + $id = $object->save(); + } + + $order = WC_Helper_Order::create_order( 2, $product ); + $order->set_status( 'completed' ); + $order->set_total( 10 ); + $order->save(); + + $download = new WC_Customer_Download(); + $download->set_user_id( 2 ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( 2 ); + $object->set_user_ip_address( '5.4.3.2.1' ); + $object->save(); + + $customer_id = $wpdb->get_col( + $wpdb->prepare( + "SELECT customer_id FROM {$wpdb->prefix}wc_customer_lookup WHERE user_id = %d", + 1 + ) + ); + + // Test includes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'customer_includes' => $customer_id, + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, $reports['totals']['download_count'] ); + + // Test excludes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'customer_excludes' => $customer_id, + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, $reports['totals']['download_count'] ); + } + + /** + * Test getting report ordering. + */ + public function test_get_report_orderby() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $prod_download = new WC_Product_Download(); + $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); + $prod_download->set_id( 1 ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_downloadable( 'yes' ); + $product->set_downloads( array( $prod_download ) ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); + $order->save(); + + $download = new WC_Customer_Download(); + $download->set_user_id( $this->user ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $object->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $object->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $object->save(); + + $three_days_from_now = current_time( 'timestamp', true ) - ( 3 * DAY_IN_SECONDS ); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $object->set_timestamp( $three_days_from_now ); + $object->save(); + + $time = time(); + $seven_days_ago = $time - ( 7 * DAY_IN_SECONDS ); + + // Test sorting by download_count. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d H:00:00', $seven_days_ago ), + 'interval' => 'day', + 'orderby' => 'download_count', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 3, $reports['intervals'][0]['subtotals']->download_count ); + $this->assertEquals( date( 'Y-m-d', $time ), $reports['intervals'][0]['interval'] ); + + $this->assertEquals( 1, $reports['intervals'][1]['subtotals']->download_count ); + $this->assertEquals( date( 'Y-m-d', $three_days_from_now ), $reports['intervals'][1]['interval'] ); + + // Test sorting by date. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d H:00:00', $seven_days_ago ), + 'interval' => 'day', + 'orderby' => 'date', + 'order' => 'asc', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 0, $reports['intervals'][0]['subtotals']->download_count ); + $this->assertEquals( date( 'Y-m-d', $seven_days_ago ), $reports['intervals'][0]['interval'] ); + + $this->assertEquals( 3, $reports['intervals'][7]['subtotals']->download_count ); + $this->assertEquals( date( 'Y-m-d', $time ), $reports['intervals'][7]['interval'] ); + } + + /** + * Test getting reports without valid permissions. + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 2, count( $properties ) ); + $this->assertArrayHasKey( 'totals', $properties ); + $this->assertArrayHasKey( 'intervals', $properties ); + + $totals = $properties['totals']['properties']; + $this->assertEquals( 1, count( $totals ) ); + $this->assertArrayHasKey( 'download_count', $totals ); + + $intervals = $properties['intervals']['items']['properties']; + $this->assertEquals( 6, count( $intervals ) ); + $this->assertArrayHasKey( 'interval', $intervals ); + $this->assertArrayHasKey( 'date_start', $intervals ); + $this->assertArrayHasKey( 'date_start_gmt', $intervals ); + $this->assertArrayHasKey( 'date_end', $intervals ); + $this->assertArrayHasKey( 'date_end_gmt', $intervals ); + $this->assertArrayHasKey( 'subtotals', $intervals ); + + $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; + $this->assertEquals( 1, count( $subtotals ) ); + $this->assertArrayHasKey( 'download_count', $subtotals ); + } +} diff --git a/tests/Version4/Reports/reports-downloads.php b/tests/Version4/Reports/reports-downloads.php new file mode 100644 index 00000000000..8410dd56352 --- /dev/null +++ b/tests/Version4/Reports/reports-downloads.php @@ -0,0 +1,414 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting report. + */ + public function test_get_report() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $prod_download = new WC_Product_Download(); + $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); + $prod_download->set_id( 1 ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_downloadable( 'yes' ); + $product->set_downloads( array( $prod_download ) ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); + $order->save(); + + $download = new WC_Customer_Download(); + $download->set_user_id( $this->user ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $id = $object->save(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + + $download_report = reset( $reports ); + + $this->assertEquals( 1, $download_report['download_id'] ); + $this->assertEquals( $product->get_id(), $download_report['product_id'] ); + $this->assertEquals( $order->get_id(), $download_report['order_id'] ); + $this->assertEquals( $order->get_order_number(), $download_report['order_number'] ); + $this->assertEquals( $this->user, $download_report['user_id'] ); + $this->assertEquals( '1.2.3.4', $download_report['ip_address'] ); + $this->assertEquals( 'help.png', $download_report['file_name'] ); + $this->assertEquals( plugin_dir_url( __FILE__ ) . '/assets/images/help.png', $download_report['file_path'] ); + } + + /** + * Does some test setup so we can filter with different options in later tests. + */ + public function filter_setup() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + $time = time(); + + // First set of data. + $prod_download = new WC_Product_Download(); + $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); + $prod_download->set_id( 1 ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_downloadable( 'yes' ); + $product->set_downloads( array( $prod_download ) ); + $product->set_regular_price( 25 ); + $product->save(); + $product_1 = $product->get_id(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 25 ); + $order->save(); + $order_1 = $order->get_id(); + + $download = new WC_Customer_Download(); + $download->set_user_id( 1 ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( 1 ); + $object->set_user_ip_address( '1.2.3.4' ); + $id = $object->save(); + + // Second set of data. + $prod_download = new WC_Product_Download(); + $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/test.png' ); + $prod_download->set_id( 2 ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product 2' ); + $product->set_downloadable( 'yes' ); + $product->set_downloads( array( $prod_download ) ); + $product->set_regular_price( 10 ); + $product->save(); + $product_2 = $product->get_id(); + + $order = WC_Helper_Order::create_order( 2, $product ); + $order->set_status( 'completed' ); + $order->set_total( 10 ); + $order->save(); + $order_2 = $order->get_id(); + + $download = new WC_Customer_Download(); + $download->set_user_id( 2 ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( 2 ); + $object->set_user_ip_address( '5.4.3.2.1' ); + $object->set_timestamp( date( 'Y-m-d H:00:00', $time - ( 2 * DAY_IN_SECONDS ) ) ); + $id = $object->save(); + + return array( + 'time' => $time, + 'product_1' => $product_1, + 'product_2' => $product_2, + 'order_1' => $order_1, + 'order_2' => $order_2, + ); + } + + /** + * Test getting report with date filter. + */ + public function test_get_report_with_date_filter() { + $test_info = $this->filter_setup(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + // Test date filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d H:00:00', $test_info['time'] + DAY_IN_SECONDS ), + 'after' => date( 'Y-m-d H:00:00', $test_info['time'] - DAY_IN_SECONDS ), + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'help.png', $download_report['file_name'] ); + } + + /** + * Test getting report with product filter. + */ + public function test_get_report_with_product_filter() { + $test_info = $this->filter_setup(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + // Test includes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'product_includes' => $test_info['product_1'], + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'help.png', $download_report['file_name'] ); + + // Test excludes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'product_excludes' => $test_info['product_1'], + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'test.png', $download_report['file_name'] ); + } + + /** + * Test getting report with order filter. + */ + public function test_get_report_with_order_filter() { + $test_info = $this->filter_setup(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + // Test includes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'order_includes' => $test_info['order_1'], + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'help.png', $download_report['file_name'] ); + + // Test excludes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'order_excludes' => $test_info['order_1'], + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'test.png', $download_report['file_name'] ); + } + + /** + * Test getting report with user filter. + */ + public function test_get_report_with_user_filter() { + $test_info = $this->filter_setup(); + global $wpdb; + + $customer_id = $wpdb->get_col( + $wpdb->prepare( + "SELECT customer_id FROM {$wpdb->prefix}wc_customer_lookup WHERE user_id = %d", + 1 + ) + ); + + // Test includes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'customer_includes' => $customer_id, + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'help.png', $download_report['file_name'] ); + $this->assertEquals( 1, $download_report['user_id'] ); + + // Test excludes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'customer_excludes' => $customer_id, + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'test.png', $download_report['file_name'] ); + $this->assertEquals( 2, $download_report['user_id'] ); + } + + /** + * Test getting report with ip address filter. + */ + public function test_get_report_with_ip_address_filter() { + $test_info = $this->filter_setup(); + + // Test includes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'ip_address_includes' => '1.2.3.4', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'help.png', $download_report['file_name'] ); + + // Test excludes filtering. + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'ip_address_excludes' => '1.2.3.4', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $download_report = reset( $reports ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + $this->assertEquals( 'test.png', $download_report['file_name'] ); + } + + /** + * Test getting reports without valid permissions. + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 12, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'product_id', $properties ); + $this->assertArrayHasKey( 'date', $properties ); + $this->assertArrayHasKey( 'date_gmt', $properties ); + $this->assertArrayHasKey( 'download_id', $properties ); + $this->assertArrayHasKey( 'file_name', $properties ); + $this->assertArrayHasKey( 'file_path', $properties ); + $this->assertArrayHasKey( 'order_id', $properties ); + $this->assertArrayHasKey( 'order_number', $properties ); + $this->assertArrayHasKey( 'user_id', $properties ); + $this->assertArrayHasKey( 'username', $properties ); + $this->assertArrayHasKey( 'ip_address', $properties ); + } +} diff --git a/tests/Version4/Reports/reports-import.php b/tests/Version4/Reports/reports-import.php new file mode 100644 index 00000000000..846ea5e21d8 --- /dev/null +++ b/tests/Version4/Reports/reports-import.php @@ -0,0 +1,397 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + + $this->customer = $this->factory->user->create( + array( + 'first_name' => 'Steve', + 'last_name' => 'User', + 'role' => 'customer', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Asserts the report item schema is correct. + * + * @param array $schema Item to check schema. + */ + public function assert_report_item_schema( $schema ) { + $this->assertArrayHasKey( 'status', $schema ); + $this->assertArrayHasKey( 'message', $schema ); + } + + /** + * Test reports schema. + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 2, $properties ); + $this->assert_report_item_schema( $properties ); + } + + /** + * Test getting reports without valid permissions. + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'POST', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test the import paramaters. + */ + public function test_import_params() { + global $wpdb; + wp_set_current_user( $this->user ); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $order_1 = WC_Helper_Order::create_order( 1, $product ); + $order_1->set_status( 'completed' ); + $order_1->set_date_created( time() - ( 3 * DAY_IN_SECONDS ) ); + $order_1->save(); + $order_2 = WC_Helper_Order::create_order( 1, $product ); + $order_2->set_total( 100 ); + $order_2->set_status( 'completed' ); + $order_2->save(); + + // Delete order stats so we can test import API. + $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE post_type = 'scheduled-action'" ); + $wpdb->query( "DELETE FROM {$wpdb->prefix}wc_order_stats" ); + + // Use the days param to only process orders in the last day. + $request = new WP_REST_Request( 'POST', $this->endpoint ); + $request->set_query_params( array( 'days' => '1' ) ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'success', $report['status'] ); + + // Run pending thrice to process batch and order. + WC_Helper_Queue::run_all_pending(); + WC_Helper_Queue::run_all_pending(); + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 2, $reports ); + $this->assertEquals( $this->customer, $reports[0]['user_id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + $this->assertEquals( $order_2->get_id(), $reports[0]['order_id'] ); + + // Use the skip existing params to skip processing customers/orders. + // Compare against order status to make sure previously imported order was skipped. + $order_2->set_status( 'processing' ); + $order_2->save(); + + // Compare against name to make sure previously imported customer was skipped. + wp_update_user( + array( + 'ID' => $this->customer, + 'first_name' => 'Changed', + ) + ); + + // Delete scheduled actions to avoid default order processing. + $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE post_type = 'scheduled-action'" ); + + $request = new WP_REST_Request( 'POST', $this->endpoint ); + $request->set_query_params( array( 'skip_existing' => '1' ) ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'success', $report['status'] ); + + // Run pending thrice to process batch and order. + WC_Helper_Queue::run_all_pending(); + WC_Helper_Queue::run_all_pending(); + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 2, $reports ); + $this->assertEquals( 'Steve User', $reports[0]['name'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); + $request->set_query_params( array( 'per_page' => 5 ) ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 2, $reports ); + $this->assertEquals( 'completed', $reports[0]['status'] ); + } + + /** + * Test cancelling import actions. + */ + public function test_cancel_import() { + wp_set_current_user( $this->user ); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_date_created( time() - ( 3 * DAY_IN_SECONDS ) ); + $order->save(); + + // Verify there are actions to cancel. + $pending_actions = WC_Helper_Queue::get_all_pending(); + $this->assertCount( 1, $pending_actions ); + + // Cancel outstanding actions. + $request = new WP_REST_Request( 'POST', $this->endpoint . '/cancel' ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'success', $report['status'] ); + + // Verify there are no pending actions. + $pending_actions = WC_Helper_Queue::get_all_pending(); + $this->assertCount( 0, $pending_actions ); + } + + /** + * Test import deletion. + */ + public function test_delete_stats() { + global $wpdb; + wp_set_current_user( $this->user ); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + for ( $i = 0; $i < 25; $i++ ) { + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->save(); + } + + // Check that stats exist before deleting. + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); + $request->set_query_params( array( 'per_page' => 25 ) ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 25, $reports ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); + $request->set_query_params( array( 'per_page' => 25 ) ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $reports ); + + // Delete all stats. + $request = new WP_REST_Request( 'POST', $this->endpoint . '/delete' ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'success', $report['status'] ); + + // Run pending three times to process batches and dependent actions. + WC_Helper_Queue::run_all_pending(); + WC_Helper_Queue::run_all_pending(); + WC_Helper_Queue::run_all_pending(); + + // Check that stats have been deleted. + $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 0, $reports ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 0, $reports ); + } + + /** + * Test import status and totals query. + */ + public function test_import_status() { + // Delete any pending actions that weren't fully run. + WC_Admin_Reports_Sync::clear_queued_actions(); + + wp_set_current_user( $this->user ); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + // Create 5 completed orders. + for ( $i = 0; $i < 5; $i++ ) { + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_date_created( time() - ( ( $i + 1 ) * DAY_IN_SECONDS ) ); + $order->save(); + } + + // Trash one test order - excludes it from totals. + $order->set_status( 'trash' ); + $order->save(); + + // Create 1 draft order - to be excluded from totals. + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_date_created( time() - ( 5 * DAY_IN_SECONDS ) ); + $order->save(); + wp_update_post( + array( + 'ID' => $order->get_id(), + 'post_status' => 'auto-draft', + ) + ); + + // Test totals and total params. + $request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + $user_query = new WP_User_Query( + array( + 'fields' => 'ID', + 'number' => 1, + ) + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 4, $report['orders'] ); + $this->assertEquals( $user_query->get_total(), $report['customers'] ); + + // Test totals with days param. + $request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' ); + $request->set_query_params( array( 'days' => 2 ) ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, $report['orders'] ); + + // Test import status. + $request = new WP_REST_Request( 'POST', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'success', $report['status'] ); + + $request = new WP_REST_Request( 'GET', $this->endpoint . '/status' ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( true, $report['is_importing'] ); + $this->assertEquals( 0, $report['customers_count'] ); + $this->assertEquals( 3, $report['customers_total'] ); + $this->assertEquals( 0, $report['orders_count'] ); + $this->assertEquals( 4, $report['orders_total'] ); + + // Run pending thrice to process batch and order. + WC_Helper_Queue::process_pending(); + WC_Helper_Queue::process_pending(); + WC_Helper_Queue::process_pending(); + + // Test import status after processing. + $request = new WP_REST_Request( 'GET', $this->endpoint . '/status' ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( false, $report['is_importing'] ); + $this->assertEquals( 1, $report['customers_count'] ); + $this->assertEquals( 3, $report['customers_total'] ); + $this->assertEquals( 4, $report['orders_count'] ); + $this->assertEquals( 4, $report['orders_total'] ); + + // Test totals with skip existing param. + $request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' ); + $request->set_query_params( array( 'skip_existing' => 1 ) ); + $response = $this->server->dispatch( $request ); + $report = $response->get_data(); + + // @todo The following line should be uncommented when https://github.com/woocommerce/woocommerce-admin/issues/2195 is resolved. + // $this->assertEquals( 0, $report['customers'] ); + $this->assertEquals( 0, $report['orders'] ); + } +} diff --git a/tests/Version4/Reports/reports-interval.php b/tests/Version4/Reports/reports-interval.php new file mode 100644 index 00000000000..2b08f2b6855 --- /dev/null +++ b/tests/Version4/Reports/reports-interval.php @@ -0,0 +1,925 @@ +assertEquals( 4, WC_Admin_Reports_Interval::quarter( $datetime ) ); + + $datetime = new DateTime( '2018-01-01T00:00:00', self::$local_tz ); + $this->assertEquals( 1, WC_Admin_Reports_Interval::quarter( $datetime ) ); + + $datetime = new DateTime( '2018-03-31T23:59:59', self::$local_tz ); + $this->assertEquals( 1, WC_Admin_Reports_Interval::quarter( $datetime ) ); + + $datetime = new DateTime( '2018-04-01T00:00:00', self::$local_tz ); + $this->assertEquals( 2, WC_Admin_Reports_Interval::quarter( $datetime ) ); + + $datetime = new DateTime( '2018-06-30T23:59:59', self::$local_tz ); + $this->assertEquals( 2, WC_Admin_Reports_Interval::quarter( $datetime ) ); + + $datetime = new DateTime( '2018-07-01T00:00:00', self::$local_tz ); + $this->assertEquals( 3, WC_Admin_Reports_Interval::quarter( $datetime ) ); + + $datetime = new DateTime( '2018-09-30T23:59:59', self::$local_tz ); + $this->assertEquals( 3, WC_Admin_Reports_Interval::quarter( $datetime ) ); + + $datetime = new DateTime( '2018-10-01T00:00:00', self::$local_tz ); + $this->assertEquals( 4, WC_Admin_Reports_Interval::quarter( $datetime ) ); + + $datetime = new DateTime( '2018-12-31T23:59:59', self::$local_tz ); + $this->assertEquals( 4, WC_Admin_Reports_Interval::quarter( $datetime ) ); + } + + /** + * Test simple week number function. + */ + public function test_simple_week_number() { + $expected_week_no = array( + '2010-12-24' => array( + 1 => 52, + 2 => 52, + 3 => 52, + 4 => 52, + 5 => 52, + 6 => 52, + 7 => 52, + ), + '2010-12-25' => array( + 1 => 52, + 2 => 52, + 3 => 52, + 4 => 52, + 5 => 52, + 6 => 53, + 7 => 52, + ), + '2010-12-26' => array( + 1 => 52, + 2 => 52, + 3 => 52, + 4 => 52, + 5 => 52, + 6 => 53, + 7 => 53, + ), + '2010-12-27' => array( + 1 => 53, + 2 => 52, + 3 => 52, + 4 => 52, + 5 => 52, + 6 => 53, + 7 => 53, + ), + '2010-12-28' => array( + 1 => 53, + 2 => 53, + 3 => 52, + 4 => 52, + 5 => 52, + 6 => 53, + 7 => 53, + ), + '2010-12-29' => array( + 1 => 53, + 2 => 53, + 3 => 53, + 4 => 52, + 5 => 52, + 6 => 53, + 7 => 53, + ), + '2010-12-30' => array( + 1 => 53, + 2 => 53, + 3 => 53, + 4 => 53, + 5 => 52, + 6 => 53, + 7 => 53, + ), + '2010-12-31' => array( + 1 => 53, + 2 => 53, + 3 => 53, + 4 => 53, + 5 => 53, + 6 => 53, + 7 => 53, + ), + '2011-01-01' => array( + 1 => 1, + 2 => 1, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + ), + '2011-01-02' => array( + 1 => 1, + 2 => 1, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 2, + ), + '2011-01-03' => array( + 1 => 2, + 2 => 1, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 2, + ), + '2011-01-04' => array( + 1 => 2, + 2 => 2, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 2, + ), + '2011-01-05' => array( + 1 => 2, + 2 => 2, + 3 => 2, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 2, + ), + '2011-01-06' => array( + 1 => 2, + 2 => 2, + 3 => 2, + 4 => 2, + 5 => 1, + 6 => 1, + 7 => 2, + ), + '2011-01-07' => array( + 1 => 2, + 2 => 2, + 3 => 2, + 4 => 2, + 5 => 2, + 6 => 1, + 7 => 2, + ), + '2011-01-08' => array( + 1 => 2, + 2 => 2, + 3 => 2, + 4 => 2, + 5 => 2, + 6 => 2, + 7 => 2, + ), + '2011-01-09' => array( + 1 => 2, + 2 => 2, + 3 => 2, + 4 => 2, + 5 => 2, + 6 => 2, + 7 => 3, + ), + '2011-01-10' => array( + 1 => 3, + 2 => 2, + 3 => 2, + 4 => 2, + 5 => 2, + 6 => 2, + 7 => 3, + ), + '2011-12-26' => array( + 1 => 53, + 2 => 52, + 3 => 52, + 4 => 52, + 5 => 52, + 6 => 52, + 7 => 53, + ), + '2011-12-27' => array( + 1 => 53, + 2 => 53, + 3 => 52, + 4 => 52, + 5 => 52, + 6 => 52, + 7 => 53, + ), + '2011-12-28' => array( + 1 => 53, + 2 => 53, + 3 => 53, + 4 => 52, + 5 => 52, + 6 => 52, + 7 => 53, + ), + '2011-12-29' => array( + 1 => 53, + 2 => 53, + 3 => 53, + 4 => 53, + 5 => 52, + 6 => 52, + 7 => 53, + ), + '2011-12-30' => array( + 1 => 53, + 2 => 53, + 3 => 53, + 4 => 53, + 5 => 53, + 6 => 52, + 7 => 53, + ), + '2011-12-31' => array( + 1 => 53, + 2 => 53, + 3 => 53, + 4 => 53, + 5 => 53, + 6 => 53, + 7 => 53, + ), + '2012-01-01' => array( + 1 => 1, + 2 => 1, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + ), + '2012-01-02' => array( + 1 => 2, + 2 => 1, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + ), + '2012-01-03' => array( + 1 => 2, + 2 => 2, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + ), + '2012-01-04' => array( + 1 => 2, + 2 => 2, + 3 => 2, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + ), + '2012-01-05' => array( + 1 => 2, + 2 => 2, + 3 => 2, + 4 => 2, + 5 => 1, + 6 => 1, + 7 => 1, + ), + '2012-01-06' => array( + 1 => 2, + 2 => 2, + 3 => 2, + 4 => 2, + 5 => 2, + 6 => 1, + 7 => 1, + ), + ); + + foreach ( $expected_week_no as $date => $week_numbers ) { + for ( $first_day_of_week = 1; $first_day_of_week <= 7; $first_day_of_week++ ) { + $datetime = new DateTime( $date, self::$local_tz ); + $this->assertEquals( $expected_week_no[ $date ][ $first_day_of_week ], WC_Admin_Reports_Interval::simple_week_number( $datetime, $first_day_of_week ), "First day of week: $first_day_of_week; Date: $date" ); + } + } + + } + + /** + * Testing ISO week number function. + */ + public function test_ISO_week_no() { + $expected_week_no = array( + '2010-12-24' => 51, + '2010-12-25' => 51, + '2010-12-26' => 51, + '2010-12-27' => 52, + '2010-12-28' => 52, + '2010-12-29' => 52, + '2010-12-30' => 52, + '2010-12-31' => 52, + '2011-01-01' => 52, + '2011-01-02' => 52, + '2011-01-03' => 1, + '2011-01-04' => 1, + '2011-01-05' => 1, + '2011-01-06' => 1, + '2011-01-07' => 1, + '2011-01-08' => 1, + '2011-01-09' => 1, + '2011-01-10' => 2, + '2011-12-26' => 52, + '2011-12-27' => 52, + '2011-12-28' => 52, + '2011-12-29' => 52, + '2011-12-30' => 52, + '2011-12-31' => 52, + '2012-01-01' => 52, + '2012-01-02' => 1, + '2012-01-03' => 1, + '2012-01-04' => 1, + '2012-01-05' => 1, + '2012-01-06' => 1, + ); + foreach ( $expected_week_no as $date => $week_numbers ) { + $datetime = new DateTime( $date, self::$local_tz ); + $this->assertEquals( $expected_week_no[ $date ], WC_Admin_Reports_Interval::week_number( $datetime, 1 ), "ISO week number for date: $date" ); + } + } + + /** + * Test function counting intervals between two datetimes. + */ + public function test_intervals_between() { + // Please note that all intervals are inclusive on both sides. + $test_settings = array( + // 0 interval length, should just return 1. + array( + 'start' => '2017-12-24T11:00:00', + 'end' => '2017-12-24T11:00:00', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 1, + 'day' => 1, + 'week' => 1, + 'month' => 1, + 'quarter' => 1, + 'year' => 1, + ), + ), + // <1 hour interval length -> should return 1 for all + array( + 'start' => '2017-12-24T11:00:00', + 'end' => '2017-12-24T11:40:00', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 1, + 'day' => 1, + 'week' => 1, + 'month' => 1, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 1.66 hour interval length -> 2 hours, 1 for the rest + array( + 'start' => '2017-12-24T11:00:00', + 'end' => '2017-12-24T12:40:00', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 2, + 'day' => 1, + 'week' => 1, + 'month' => 1, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 8.0186111 hours interval length -> 10 hours, 2 days, 1 for the rest + array( + 'start' => '2019-01-16T16:59:00', + 'end' => '2019-01-17T01:00:07', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 10, + 'day' => 2, + 'week' => 1, + 'month' => 1, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 23:59:59 h:m:s interval -> 24 hours, 2 days, 1 for the rest + array( + 'start' => '2017-12-24T11:00:00', + 'end' => '2017-12-25T10:59:59', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 24, + 'day' => 2, + 'week' => 2, + 'month' => 1, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 24 hour inclusive interval -> 25 hours, 2 days, 1 for the rest + array( + 'start' => '2017-12-24T11:00:00', + 'end' => '2017-12-25T11:00:00', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 25, + 'day' => 2, + 'week' => 2, + 'month' => 1, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 1 month interval spanning 1 month -> 720 hours, 30 days, 5 iso weeks, 1 months + array( + 'start' => '2017-11-01T00:00:00', + 'end' => '2017-11-30T23:59:59', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 720, + 'day' => 30, + 'week' => 5, + 'month' => 1, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 1 month interval spanning 2 months, but 1 quarter and 1 year -> 721 hours, 31 days, 5 iso weeks, 2 months + array( + 'start' => '2017-11-24T11:00:00', + 'end' => '2017-12-24T11:00:00', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 30 * 24 + 1, // 30 full days + 1 second from next hour + 'day' => 31, + 'week' => 5, + 'month' => 2, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 1 month + 14 hour interval spanning 2 months in 1 quarter -> 735 hours, 32 days, 6 iso weeks, 2 months + array( + 'start' => '2017-11-24T11:00:00', + 'end' => '2017-12-25T01:00:00', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 30 * 24 + 13 + 2, // 30 full days + 13 full hours on Nov 24 + 2 hours on Dec 25 + 'day' => 32, + 'week' => 6, + 'month' => 2, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 1 month interval spanning 2 months and 2 quarters, 1 year -> 720 hours, 31 days, 6 iso weeks, 2 months, 2 q, 1 y + array( + 'start' => '2017-09-24T11:00:00', + 'end' => '2017-10-24T10:59:59', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 30 * 24, + 'day' => 31, // Sept has 30 days, but need to include interval for half of Sept 24 and interval for half of Oct 24. + 'week' => 6, + 'month' => 2, + 'quarter' => 2, + 'year' => 1, + ), + ), + // 1 month interval spanning 2 months and 2 quarters, 2 years -> 744 hours, 32 days, 6 iso weeks, 2 months, 2 quarters, 2 years + array( + 'start' => '2017-12-24T11:00:00', + 'end' => '2018-01-24T10:59:59', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 31 * 24, + 'day' => 32, // Dec has 31 days, plus 1 interval for half day at the end. + 'week' => 6, + 'month' => 2, + 'quarter' => 2, + 'year' => 2, + ), + ), + // 3 months interval spanning 1 quarter, 1 year -> 2208 hours, 92 days, 14 iso weeks, 3 months, 1 quarters, 1 years + array( + 'start' => '2017-10-01T00:00:00', + 'end' => '2017-12-31T23:59:59', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 92 * 24, // 92 days + 'day' => 92, + 'week' => 14, + 'month' => 3, + 'quarter' => 1, + 'year' => 1, + ), + ), + // 3 months + 1 day interval spanning 2 quarters, 1 year -> 2208 hours, 92 days, 14 iso weeks, 3 months, 2 quarters, 1 years + array( + 'start' => '2017-09-30T00:00:00', + 'end' => '2017-12-30T23:59:59', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 92 * 24, // 92 days + 'day' => 92, + 'week' => 14, + 'month' => 4, + 'quarter' => 2, + 'year' => 1, + ), + ), + // 3 months + 1 day interval spanning 2 quarters, 2 years -> 2232 hours, 93 days, 14 iso weeks, 3 months, 2 quarters, 2 years + array( + 'start' => '2017-10-31T00:00:00', + 'end' => '2018-01-31T23:59:59', + 'week_start' => 1, + 'intervals' => array( + 'hour' => 93 * 24, // 93 days + 'day' => 93, // Jan 31d + Dec 31d + Nov 30d + Oct 1d = 93d. + 'week' => 14, + 'month' => 4, + 'quarter' => 2, + 'year' => 2, + ), + ), + // 9 months + 1 day interval spanning 2 quarters, 2 years. + array( + 'start' => '2017-04-01T00:00:00', + 'end' => '2018-01-01T00:00:00', + 'week_start' => 1, + 'intervals' => array( + 'month' => 9 + 1, + 'quarter' => 3 + 1, + 'year' => 2, + ), + ), + // 9 months + 1 day interval spanning 2 quarters, 2 years. + array( + 'start' => '2015-04-01T00:00:00', + 'end' => '2018-01-01T00:00:00', + 'week_start' => 1, + 'intervals' => array( + 'day' => 1007, // This includes leap year in 2016. + 'month' => 9 + 12 + 12 + 1, // Rest of 2015 + 2016 + 2017 + 1 second in 2018. + 'quarter' => 3 + 4 + 4 + 1, // Rest of 2015 + 2016 + 2017 + 1 second in 2018. + 'year' => 4, + ), + ), + ); + + foreach ( $test_settings as $setting ) { + update_option( 'start_of_week', $setting['week_start'] ); + foreach ( $setting['intervals'] as $interval => $exp_value ) { + $start_datetime = new DateTime( $setting['start'], self::$local_tz ); + $end_datetime = new DateTime( $setting['end'], self::$local_tz ); + $this->assertEquals( $exp_value, WC_Admin_Reports_Interval::intervals_between( $start_datetime, $end_datetime, $interval ), "First Day of Week: {$setting['week_start']}; Start: {$setting['start']}; End: {$setting['end']}; Interval: {$interval}" ); + } + } + } + + /** + * Test function that returns beginning of next hour. + */ + public function test_next_hour_start() { + $settings = array( + '2017-12-30T00:00:00' => array( + 0 => '2017-12-30T01:00:00', + 1 => '2017-12-29T23:59:59', + ), + '2017-12-30T10:00:00' => array( + 0 => '2017-12-30T11:00:00', + 1 => '2017-12-30T09:59:59', + ), + ); + foreach ( $settings as $datetime_s => $setting ) { + $datetime = new DateTime( $datetime_s, self::$local_tz ); + foreach ( $setting as $reversed => $exp_value ) { + $result_dt = WC_Admin_Reports_Interval::next_hour_start( $datetime, $reversed ); + $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); + } + } + } + + /** + * Test function that returns beginning of next day. + */ + public function test_next_day_start() { + $settings = array( + '2017-12-30T00:00:00' => array( + 0 => '2017-12-31T00:00:00', + 1 => '2017-12-29T23:59:59', + ), + '2017-12-30T10:00:00' => array( + 0 => '2017-12-31T00:00:00', + 1 => '2017-12-29T23:59:59', + ), + ); + foreach ( $settings as $datetime_s => $setting ) { + $datetime = new DateTime( $datetime_s, self::$local_tz ); + foreach ( $setting as $reversed => $exp_value ) { + $result_dt = WC_Admin_Reports_Interval::next_day_start( $datetime, $reversed ); + $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); + } + } + } + + /** + * Test function that returns beginning of next week, for weeks starting on Monday. + */ + public function test_next_week_start_ISO_week() { + update_option( 'start_of_week', 1 ); + $settings = array( + '2017-12-30T00:00:00' => array( + 0 => '2018-01-01T00:00:00', + 1 => '2017-12-24T23:59:59', + ), + '2017-12-30T10:00:00' => array( + 0 => '2018-01-01T00:00:00', + 1 => '2017-12-24T23:59:59', + ), + '2010-12-25T10:00:00' => array( + 0 => '2010-12-27T00:00:00', + 1 => '2010-12-19T23:59:59', + ), + '2010-12-26T10:00:00' => array( + 0 => '2010-12-27T00:00:00', + 1 => '2010-12-19T23:59:59', + ), + '2010-12-27T00:00:00' => array( + 0 => '2011-01-03T00:00:00', + 1 => '2010-12-26T23:59:59', + ), + '2010-12-31T00:00:00' => array( + 0 => '2011-01-03T00:00:00', + 1 => '2010-12-26T23:59:59', + ), + '2011-01-01T00:00:00' => array( + 0 => '2011-01-03T00:00:00', + 1 => '2010-12-26T23:59:59', + ), + '2011-01-03T00:00:00' => array( + 0 => '2011-01-10T00:00:00', + 1 => '2011-01-02T23:59:59', + ), + ); + foreach ( $settings as $datetime_s => $setting ) { + $datetime = new DateTime( $datetime_s, self::$local_tz ); + foreach ( $setting as $reversed => $exp_value ) { + $result_dt = WC_Admin_Reports_Interval::next_week_start( $datetime, $reversed ); + $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); + } + } + } + + /** + * Test function that returns beginning of next week, for weeks starting on Sunday. + */ + public function test_next_week_start_Sunday_based_week() { + update_option( 'start_of_week', 7 ); + $settings = array( + '2010-12-25T10:00:00' => array( + 0 => '2010-12-26T00:00:00', + 1 => '2010-12-18T23:59:59', + ), + '2010-12-26T10:00:00' => array( + 0 => '2011-01-01T00:00:00', + 1 => '2010-12-25T23:59:59', + ), + '2011-01-01T00:00:00' => array( + 0 => '2011-01-02T00:00:00', + 1 => '2010-12-31T23:59:59', + ), + '2011-01-02T00:00:00' => array( + 0 => '2011-01-09T00:00:00', + 1 => '2011-01-01T23:59:59', + ), + ); + foreach ( $settings as $datetime_s => $setting ) { + $datetime = new DateTime( $datetime_s, self::$local_tz ); + foreach ( $setting as $reversed => $exp_value ) { + $result_dt = WC_Admin_Reports_Interval::next_week_start( $datetime, $reversed ); + $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); + } + } + } + + /** + * Test function that returns beginning of next month. + */ + public function test_next_month_start() { + $settings = array( + '2017-12-30T00:00:00' => array( + 0 => '2018-01-01T00:00:00', + 1 => '2017-11-30T23:59:59', + ), + // Leap year reversed test. + '2016-03-05T10:00:00' => array( + 0 => '2016-04-01T00:00:00', + 1 => '2016-02-29T23:59:59', + ), + ); + foreach ( $settings as $datetime_s => $setting ) { + $datetime = new DateTime( $datetime_s, self::$local_tz ); + foreach ( $setting as $reversed => $exp_value ) { + $result_dt = WC_Admin_Reports_Interval::next_month_start( $datetime, $reversed ); + $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); + } + } + } + + /** + * Test function that returns beginning of next quarter. + */ + public function test_next_quarter_start() { + $settings = array( + '2017-12-31T00:00:00' => array( + 0 => '2018-01-01T00:00:00', + 1 => '2017-09-30T23:59:59', + ), + '2018-01-01T10:00:00' => array( + 0 => '2018-04-01T00:00:00', + 1 => '2017-12-31T23:59:59', + ), + '2018-02-14T10:00:00' => array( + 0 => '2018-04-01T00:00:00', + 1 => '2017-12-31T23:59:59', + ), + '2018-04-14T10:00:00' => array( + 0 => '2018-07-01T00:00:00', + 1 => '2018-03-31T23:59:59', + ), + '2018-07-14T10:00:00' => array( + 0 => '2018-10-01T00:00:00', + 1 => '2018-06-30T23:59:59', + ), + ); + foreach ( $settings as $datetime_s => $setting ) { + $datetime = new DateTime( $datetime_s, self::$local_tz ); + foreach ( $setting as $reversed => $exp_value ) { + $result_dt = WC_Admin_Reports_Interval::next_quarter_start( $datetime, $reversed ); + $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); + } + } + } + + /** + * Test function that returns beginning of next year. + */ + public function test_next_year_start() { + $settings = array( + '2017-12-31T23:59:59' => array( + 0 => '2018-01-01T00:00:00', + 1 => '2016-12-31T23:59:59', + ), + '2017-01-01T00:00:00' => array( + 0 => '2018-01-01T00:00:00', + 1 => '2016-12-31T23:59:59', + ), + '2017-04-23T14:53:00' => array( + 0 => '2018-01-01T00:00:00', + 1 => '2016-12-31T23:59:59', + ), + ); + foreach ( $settings as $datetime_s => $setting ) { + $datetime = new DateTime( $datetime_s, self::$local_tz ); + foreach ( $setting as $reversed => $exp_value ) { + $result_dt = WC_Admin_Reports_Interval::next_year_start( $datetime, $reversed ); + $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); + } + } + } + + /** + * Test function that normalizes *_between query parameters to *_min & *_max. + */ + public function test_normalize_between_params() { + $request = array( + 'a_between' => 'malformed', // won't be normalized (not an array). + 'b_between' => array( 1, 5 ), // results in min=1, max=5. + 'c_between' => array( 4, 2 ), // results in min=2, max=4. + 'd_between' => array( 7 ), // won't be normalized (only 1 item). + 'f_between' => array( 10, 12 ), // not in params, skipped. + ); + $params = array( 'a', 'b', 'c', 'd' ); + $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params, false ); + $expected = array( + 'b_min' => 1, + 'b_max' => 5, + 'c_min' => 2, + 'c_max' => 4, + ); + + $this->assertEquals( $result, $expected ); + } + + /** + * Test function that normalizes *_between query parameters for dates to *_after & *_before. + */ + public function test_normalize_between_date_params() { + $request = array( + 'a_between' => 'malformed', // won't be normalized (not an array). + 'b_between' => array( 1, 5 ), // results in after=1, before=5. + 'c_between' => array( 4, 2 ), // results in after=2, before=4. + 'd_between' => array( 7 ), // won't be normalized (only 1 item). + 'f_between' => array( 10, 12 ), // not in params, skipped. + ); + $params = array( 'a', 'b', 'c', 'd' ); + $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params, true ); + $expected = array( + 'b_after' => 1, + 'b_before' => 5, + 'c_after' => 2, + 'c_before' => 4, + ); + + $this->assertEquals( $result, $expected ); + } + + /** + * Test function that validates *_between query parameters for numeric values. + */ + public function test_rest_validate_between_numeric_arg() { + $this->assertIsWPError( + WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( 'not array', null, 'param' ), + 'param is not a numerically indexed array.' + ); + + $this->assertIsWPError( + WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1 ), null, 'param' ), + 'param must contain 2 numbers.' + ); + + $this->assertTrue( + WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1, 2 ), null, 'param' ) + ); + } + + /** + * Test function that validates *_between query parameters for date values. + */ + public function rest_validate_between_date_arg() { + $this->assertIsWPError( + WC_Admin_Reports_Interval::rest_validate_between_date_arg( 'not array', null, 'param' ), + 'param is not a numerically indexed array.' + ); + + $this->assertIsWPError( + WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( '2019-01-01T00:00:00' ), null, 'param' ), + 'param must contain 2 valid dates.' + ); + + $this->assertIsWPError( + WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( 'not a valid date' ), null, 'param' ), + 'param must contain 2 valid dates.' + ); + + $this->assertTrue( + WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( '2019-01-01T00:00:00', '2019-01-15T00:00:00' ), null, 'param' ) + ); + } +} diff --git a/tests/Version4/Reports/reports-orders-stats.php b/tests/Version4/Reports/reports-orders-stats.php new file mode 100644 index 00000000000..546bef0de67 --- /dev/null +++ b/tests/Version4/Reports/reports-orders-stats.php @@ -0,0 +1,132 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + + // @todo Update after report interface is done. + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); // totals and intervals. + // @todo Update results after implement report interface. + // $this->assertEquals( array(), $reports ); // @codingStandardsIgnoreLine. + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 2, count( $properties ) ); + $this->assertArrayHasKey( 'totals', $properties ); + $this->assertArrayHasKey( 'intervals', $properties ); + + $totals = $properties['totals']['properties']; + $this->assertEquals( 11, count( $totals ) ); + $this->assertArrayHasKey( 'net_revenue', $totals ); + $this->assertArrayHasKey( 'avg_order_value', $totals ); + $this->assertArrayHasKey( 'orders_count', $totals ); + $this->assertArrayHasKey( 'avg_items_per_order', $totals ); + $this->assertArrayHasKey( 'num_items_sold', $totals ); + $this->assertArrayHasKey( 'coupons', $totals ); + $this->assertArrayHasKey( 'coupons_count', $totals ); + $this->assertArrayHasKey( 'num_returning_customers', $totals ); + $this->assertArrayHasKey( 'num_new_customers', $totals ); + $this->assertArrayHasKey( 'products', $totals ); + $this->assertArrayHasKey( 'segments', $totals ); + + $intervals = $properties['intervals']['items']['properties']; + $this->assertEquals( 6, count( $intervals ) ); + $this->assertArrayHasKey( 'interval', $intervals ); + $this->assertArrayHasKey( 'date_start', $intervals ); + $this->assertArrayHasKey( 'date_start_gmt', $intervals ); + $this->assertArrayHasKey( 'date_end', $intervals ); + $this->assertArrayHasKey( 'date_end_gmt', $intervals ); + $this->assertArrayHasKey( 'subtotals', $intervals ); + + $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; + $this->assertEquals( 10, count( $subtotals ) ); + $this->assertArrayHasKey( 'net_revenue', $subtotals ); + $this->assertArrayHasKey( 'avg_order_value', $subtotals ); + $this->assertArrayHasKey( 'orders_count', $subtotals ); + $this->assertArrayHasKey( 'avg_items_per_order', $subtotals ); + $this->assertArrayHasKey( 'num_items_sold', $subtotals ); + $this->assertArrayHasKey( 'coupons', $subtotals ); + $this->assertArrayHasKey( 'coupons_count', $subtotals ); + $this->assertArrayHasKey( 'num_returning_customers', $subtotals ); + $this->assertArrayHasKey( 'num_new_customers', $subtotals ); + $this->assertArrayHasKey( 'segments', $subtotals ); + } +} diff --git a/tests/Version4/Reports/reports-orders.php b/tests/Version4/Reports/reports-orders.php new file mode 100644 index 00000000000..cf0315a0795 --- /dev/null +++ b/tests/Version4/Reports/reports-orders.php @@ -0,0 +1,128 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $expected_customer_id = WC_Admin_Reports_Customers_Data_Store::get_customer_id_by_user_id( 1 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + + $order_report = reset( $reports ); + + $this->assertEquals( $order->get_id(), $order_report['order_id'] ); + $this->assertEquals( $order->get_order_number(), $order_report['order_number'] ); + $this->assertEquals( date( 'Y-m-d H:i:s', $order->get_date_created()->getTimestamp() ), $order_report['date_created'] ); + $this->assertEquals( $expected_customer_id, $order_report['customer_id'] ); + $this->assertEquals( 4, $order_report['num_items_sold'] ); + $this->assertEquals( 90.0, $order_report['net_total'] ); // 25 x 4 - 10 (shipping) + $this->assertEquals( 'new', $order_report['customer_type'] ); + $this->assertArrayHasKey( '_links', $order_report ); + $this->assertArrayHasKey( 'order', $order_report['_links'] ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 9, count( $properties ) ); + $this->assertArrayHasKey( 'order_id', $properties ); + $this->assertArrayHasKey( 'order_number', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'status', $properties ); + $this->assertArrayHasKey( 'customer_id', $properties ); + $this->assertArrayHasKey( 'net_total', $properties ); + $this->assertArrayHasKey( 'num_items_sold', $properties ); + $this->assertArrayHasKey( 'customer_type', $properties ); + $this->assertArrayHasKey( 'extended_info', $properties ); + } +} diff --git a/tests/Version4/Reports/reports-performance-indicators.php b/tests/Version4/Reports/reports-performance-indicators.php new file mode 100644 index 00000000000..487ba3fb9e6 --- /dev/null +++ b/tests/Version4/Reports/reports-performance-indicators.php @@ -0,0 +1,183 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + $this->assertArrayHasKey( $this->endpoint . '/allowed', $routes ); + } + + /** + * Test getting indicators. + */ + public function test_get_indicators() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. We'll create an order and a download. + $prod_download = new WC_Product_Download(); + $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); + $prod_download->set_id( 1 ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_downloadable( 'yes' ); + $product->set_downloads( array( $prod_download ) ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 25 ); + $order->save(); + + $download = new WC_Customer_Download(); + $download->set_user_id( $this->user ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $object->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $object->save(); + + WC_Helper_Queue::run_all_pending(); + + $time = time(); + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d H:00:00', $time - ( 7 * DAY_IN_SECONDS ) ), + 'stats' => 'orders/orders_count,downloads/download_count,test/bogus_stat', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $this->assertEquals( 'orders/orders_count', $reports[0]['stat'] ); + $this->assertEquals( 'Amount of orders', $reports[0]['label'] ); + $this->assertEquals( 1, $reports[0]['value'] ); + $this->assertEquals( 'orders_count', $reports[0]['chart'] ); + $this->assertEquals( '/analytics/orders', $response->data[0]['_links']['report'][0]['href'] ); + + $this->assertEquals( 'downloads/download_count', $reports[1]['stat'] ); + $this->assertEquals( 'Number of downloads', $reports[1]['label'] ); + $this->assertEquals( 2, $reports[1]['value'] ); + $this->assertEquals( 'download_count', $reports[1]['chart'] ); + $this->assertEquals( '/analytics/downloads', $response->data[1]['_links']['report'][0]['href'] ); + } + + /** + * Test getting indicators with an empty request. + */ + public function test_get_indicators_empty_request() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + $time = time(); + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d H:00:00', $time - ( 7 * DAY_IN_SECONDS ) ), + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 500, $response->get_status() ); + } + + /** + * Test getting without valid permissions. + */ + public function test_get_indicators_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test schema. + */ + public function test_indicators_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 5, count( $properties ) ); + $this->assertArrayHasKey( 'stat', $properties ); + $this->assertArrayHasKey( 'chart', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'format', $properties ); + $this->assertArrayHasKey( 'value', $properties ); + } + + /** + * Test schema for /allowed indicators endpoint. + */ + public function test_indicators_schema_allowed() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint . '/allowed' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'stat', $properties ); + $this->assertArrayHasKey( 'chart', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + } +} diff --git a/tests/Version4/Reports/reports-products-stats.php b/tests/Version4/Reports/reports-products-stats.php new file mode 100644 index 00000000000..1c5ef5d63b3 --- /dev/null +++ b/tests/Version4/Reports/reports-products-stats.php @@ -0,0 +1,171 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + WC_Helper_Reports::reset_stats_dbs(); + wp_set_current_user( $this->user ); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $time = time(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_shipping_total( 10 ); + $order->set_discount_total( 20 ); + $order->set_discount_tax( 0 ); + $order->set_cart_tax( 5 ); + $order->set_shipping_tax( 2 ); + $order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax. + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d 00:00:00', $time ), + 'interval' => 'day', + ) + ); + + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $expected_reports = array( + 'totals' => array( + 'items_sold' => 4, + 'net_revenue' => 100.0, + 'orders_count' => 1, + 'products_count' => 1, + 'variations_count' => 1, + 'segments' => array(), + ), + 'intervals' => array( + array( + 'interval' => date( 'Y-m-d', $time ), + 'date_start' => date( 'Y-m-d 00:00:00', $time ), + 'date_start_gmt' => date( 'Y-m-d 00:00:00', $time ), + 'date_end' => date( 'Y-m-d 23:59:59', $time ), + 'date_end_gmt' => date( 'Y-m-d 23:59:59', $time ), + 'subtotals' => (object) array( + 'items_sold' => 4, + 'net_revenue' => 100.0, + 'orders_count' => 1, + 'products_count' => 1, + 'variations_count' => 1, + 'segments' => array(), + ), + ), + ), + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $expected_reports, $reports ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 2, count( $properties ) ); + $this->assertArrayHasKey( 'totals', $properties ); + $this->assertArrayHasKey( 'intervals', $properties ); + + $totals = $properties['totals']['properties']; + $this->assertEquals( 4, count( $totals ) ); + $this->assertArrayHasKey( 'net_revenue', $totals ); + $this->assertArrayHasKey( 'items_sold', $totals ); + $this->assertArrayHasKey( 'orders_count', $totals ); + $this->assertArrayHasKey( 'segments', $totals ); + + $intervals = $properties['intervals']['items']['properties']; + $this->assertEquals( 6, count( $intervals ) ); + $this->assertArrayHasKey( 'interval', $intervals ); + $this->assertArrayHasKey( 'date_start', $intervals ); + $this->assertArrayHasKey( 'date_start_gmt', $intervals ); + $this->assertArrayHasKey( 'date_end', $intervals ); + $this->assertArrayHasKey( 'date_end_gmt', $intervals ); + $this->assertArrayHasKey( 'subtotals', $intervals ); + + $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; + $this->assertEquals( 4, count( $subtotals ) ); + $this->assertArrayHasKey( 'net_revenue', $subtotals ); + $this->assertArrayHasKey( 'items_sold', $subtotals ); + $this->assertArrayHasKey( 'orders_count', $subtotals ); + $this->assertArrayHasKey( 'segments', $subtotals ); + } +} diff --git a/tests/Version4/Reports/reports-products.php b/tests/Version4/Reports/reports-products.php new file mode 100644 index 00000000000..6730e010480 --- /dev/null +++ b/tests/Version4/Reports/reports-products.php @@ -0,0 +1,174 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + + $product_report = reset( $reports ); + + $this->assertEquals( $product->get_id(), $product_report['product_id'] ); + $this->assertEquals( 4, $product_report['items_sold'] ); + $this->assertEquals( 1, $product_report['orders_count'] ); + $this->assertArrayHasKey( '_links', $product_report ); + $this->assertArrayHasKey( 'product', $product_report['_links'] ); + } + + /** + * Test getting reports with the `products` param. + * + * @since 3.5.0 + */ + public function test_get_reports_products_param() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $product_2 = new WC_Product_Simple(); + $product_2->set_name( 'Test Product 2' ); + $product_2->set_regular_price( 25 ); + $product_2->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'products' => $product->get_id() . ',' . $product_2->get_id(), + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $product_report = reset( $reports ); + + $this->assertEquals( $product->get_id(), $product_report['product_id'] ); + $this->assertEquals( 4, $product_report['items_sold'] ); + $this->assertEquals( 1, $product_report['orders_count'] ); + $this->assertArrayHasKey( '_links', $product_report ); + $this->assertArrayHasKey( 'product', $product_report['_links'] ); + + $product_report = next( $reports ); + + $this->assertEquals( $product_2->get_id(), $product_report['product_id'] ); + $this->assertEquals( null, $product_report['items_sold'] ); + $this->assertEquals( null, $product_report['orders_count'] ); + $this->assertArrayHasKey( '_links', $product_report ); + $this->assertArrayHasKey( 'product', $product_report['_links'] ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 5, count( $properties ) ); + $this->assertArrayHasKey( 'product_id', $properties ); + $this->assertArrayHasKey( 'items_sold', $properties ); + $this->assertArrayHasKey( 'net_revenue', $properties ); + $this->assertArrayHasKey( 'orders_count', $properties ); + $this->assertArrayHasKey( 'extended_info', $properties ); + } +} diff --git a/tests/Version4/Reports/reports-revenue-stats.php b/tests/Version4/Reports/reports-revenue-stats.php new file mode 100644 index 00000000000..f62a3ad2ced --- /dev/null +++ b/tests/Version4/Reports/reports-revenue-stats.php @@ -0,0 +1,135 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + + // @todo update after report interface is done. + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $data ) ); // @todo Update results after implement report interface. + // $this->assertEquals( array(), $reports ); // @todo Update results after implement report interface. + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 2, count( $properties ) ); + $this->assertArrayHasKey( 'totals', $properties ); + $this->assertArrayHasKey( 'intervals', $properties ); + + $totals = $properties['totals']['properties']; + $this->assertEquals( 11, count( $totals ) ); + $this->assertArrayHasKey( 'gross_revenue', $totals ); + $this->assertArrayHasKey( 'net_revenue', $totals ); + $this->assertArrayHasKey( 'coupons', $totals ); + $this->assertArrayHasKey( 'coupons_count', $totals ); + $this->assertArrayHasKey( 'shipping', $totals ); + $this->assertArrayHasKey( 'taxes', $totals ); + $this->assertArrayHasKey( 'refunds', $totals ); + $this->assertArrayHasKey( 'orders_count', $totals ); + $this->assertArrayHasKey( 'num_items_sold', $totals ); + $this->assertArrayHasKey( 'products', $totals ); + $this->assertArrayHasKey( 'segments', $totals ); + + $intervals = $properties['intervals']['items']['properties']; + $this->assertEquals( 6, count( $intervals ) ); + $this->assertArrayHasKey( 'interval', $intervals ); + $this->assertArrayHasKey( 'date_start', $intervals ); + $this->assertArrayHasKey( 'date_start_gmt', $intervals ); + $this->assertArrayHasKey( 'date_end', $intervals ); + $this->assertArrayHasKey( 'date_end_gmt', $intervals ); + $this->assertArrayHasKey( 'subtotals', $intervals ); + + $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; + $this->assertEquals( 10, count( $subtotals ) ); + $this->assertArrayHasKey( 'gross_revenue', $subtotals ); + $this->assertArrayHasKey( 'net_revenue', $subtotals ); + $this->assertArrayHasKey( 'coupons', $subtotals ); + $this->assertArrayHasKey( 'coupons_count', $subtotals ); + $this->assertArrayHasKey( 'shipping', $subtotals ); + $this->assertArrayHasKey( 'taxes', $subtotals ); + $this->assertArrayHasKey( 'refunds', $subtotals ); + $this->assertArrayHasKey( 'orders_count', $subtotals ); + $this->assertArrayHasKey( 'num_items_sold', $subtotals ); + $this->assertArrayHasKey( 'segments', $subtotals ); + } +} diff --git a/tests/Version4/Reports/reports-stock-stats.php b/tests/Version4/Reports/reports-stock-stats.php new file mode 100644 index 00000000000..a4e0e95d54e --- /dev/null +++ b/tests/Version4/Reports/reports-stock-stats.php @@ -0,0 +1,139 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + $number_of_low_stock = 3; + for ( $i = 1; $i <= $number_of_low_stock; $i++ ) { + $low_stock = new WC_Product_Simple(); + $low_stock->set_name( "Test low stock {$i}" ); + $low_stock->set_regular_price( 5 ); + $low_stock->set_manage_stock( true ); + $low_stock->set_stock_quantity( 1 ); + $low_stock->set_stock_status( 'instock' ); + $low_stock->save(); + } + + $number_of_out_of_stock = 6; + for ( $i = 1; $i <= $number_of_out_of_stock; $i++ ) { + $out_of_stock = new WC_Product_Simple(); + $out_of_stock->set_name( "Test out of stock {$i}" ); + $out_of_stock->set_regular_price( 5 ); + $out_of_stock->set_stock_status( 'outofstock' ); + $out_of_stock->save(); + } + + $number_of_in_stock = 10; + for ( $i = 1; $i <= $number_of_in_stock; $i++ ) { + $in_stock = new WC_Product_Simple(); + $in_stock->set_name( "Test in stock {$i}" ); + $in_stock->set_regular_price( 25 ); + $in_stock->save(); + } + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertArrayHasKey( 'totals', $reports ); + $this->assertEquals( 19, $reports['totals']['products'] ); + $this->assertEquals( 6, $reports['totals']['outofstock'] ); + $this->assertEquals( 0, $reports['totals']['onbackorder'] ); + $this->assertEquals( 3, $reports['totals']['lowstock'] ); + $this->assertEquals( 13, $reports['totals']['instock'] ); + + // Test backorder and cache update. + $backorder_stock = new WC_Product_Simple(); + $backorder_stock->set_name( 'Test backorder' ); + $backorder_stock->set_regular_price( 5 ); + $backorder_stock->set_stock_status( 'onbackorder' ); + $backorder_stock->save(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 20, $reports['totals']['products'] ); + $this->assertEquals( 6, $reports['totals']['outofstock'] ); + $this->assertEquals( 1, $reports['totals']['onbackorder'] ); + $this->assertEquals( 3, $reports['totals']['lowstock'] ); + $this->assertEquals( 13, $reports['totals']['instock'] ); + } + + /** + * Test getting reports without valid permissions. + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 1, $properties ); + $this->assertArrayHasKey( 'totals', $properties ); + $this->assertCount( 5, $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'products', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'outofstock', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'onbackorder', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'lowstock', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'instock', $properties['totals']['properties'] ); + } +} diff --git a/tests/Version4/Reports/reports-stock.php b/tests/Version4/Reports/reports-stock.php new file mode 100644 index 00000000000..47303cb3571 --- /dev/null +++ b/tests/Version4/Reports/reports-stock.php @@ -0,0 +1,119 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $low_stock = new WC_Product_Simple(); + $low_stock->set_name( 'Test low stock' ); + $low_stock->set_regular_price( 5 ); + $low_stock->set_manage_stock( true ); + $low_stock->set_stock_quantity( 1 ); + $low_stock->set_stock_status( 'instock' ); + $low_stock->save(); + + $out_of_stock = new WC_Product_Simple(); + $out_of_stock->set_name( 'Test out of stock' ); + $out_of_stock->set_regular_price( 5 ); + $out_of_stock->set_stock_status( 'outofstock' ); + $out_of_stock->save(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_param( 'include', implode( ',', array( $low_stock->get_id(), $out_of_stock->get_id() ) ) ); + $request->set_param( 'orderby', 'id' ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $this->assertEquals( $low_stock->get_id(), $reports[0]['id'] ); + $this->assertEquals( 'instock', $reports[0]['stock_status'] ); + $this->assertEquals( 1, $reports[0]['stock_quantity'] ); + $this->assertArrayHasKey( '_links', $reports[0] ); + $this->assertArrayHasKey( 'product', $reports[0]['_links'] ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_param( 'include', implode( ',', array( $low_stock->get_id(), $out_of_stock->get_id() ) ) ); + $request->set_param( 'type', 'lowstock' ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + } + + /** + * Test getting reports without valid permissions. + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 7, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'parent_id', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'sku', $properties ); + $this->assertArrayHasKey( 'stock_status', $properties ); + $this->assertArrayHasKey( 'stock_quantity', $properties ); + $this->assertArrayHasKey( 'manage_stock', $properties ); + } +} diff --git a/tests/Version4/Reports/reports-taxes-stats.php b/tests/Version4/Reports/reports-taxes-stats.php new file mode 100644 index 00000000000..8dd54f908d7 --- /dev/null +++ b/tests/Version4/Reports/reports-taxes-stats.php @@ -0,0 +1,172 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $tax = WC_Tax::_insert_tax_rate( + array( + 'tax_rate_country' => 'US', + 'tax_rate_state' => '', + 'tax_rate' => '7', + 'tax_rate_name' => 'TestTax', + 'tax_rate_priority' => '1', + 'tax_rate_compound' => '0', + 'tax_rate_shipping' => '1', + 'tax_rate_order' => '1', + 'tax_rate_class' => '', + ) + ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->set_tax_class( 'TestTax' ); + $product->save(); + + update_option( 'woocommerce_calc_taxes', 'yes' ); + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->calculate_taxes(); + $order->save(); + + // Add refunds to line items. + foreach ( $order->get_items() as $item_id => $item ) { + $refund = array( + 'amount' => 1, + 'reason' => 'Testing line item refund', + 'order_id' => $order->get_id(), + 'line_items' => array( + $item_id => array( + 'qty' => 1, + 'refund_total' => 1, + 'refund_tax' => array( $tax => 1 ), + ), + ), + ); + $wc_refund = wc_create_refund( $refund ); + } + + WC_Helper_Queue::run_all_pending(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $tax_report = reset( $reports ); + + $this->assertEquals( 1, $tax_report['tax_codes'] ); + $this->assertEquals( 6.7, $tax_report['total_tax'] ); // 110 * 0.07 (tax rate) - 1 (refund) + $this->assertEquals( 6, $tax_report['order_tax'] ); // 100 * 0.07 (tax rate) - 1 (refund) + $this->assertEquals( 0.7, $tax_report['shipping_tax'] ); + $this->assertEquals( 1, $tax_report['orders_count'] ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $totals = $properties['totals']['properties']; + + $this->assertEquals( 6, count( $totals ) ); + $this->assertArrayHasKey( 'order_tax', $totals ); + $this->assertArrayHasKey( 'orders_count', $totals ); + $this->assertArrayHasKey( 'shipping_tax', $totals ); + $this->assertArrayHasKey( 'tax_codes', $totals ); + $this->assertArrayHasKey( 'total_tax', $totals ); + $this->assertArrayHasKey( 'segments', $totals ); + + $intervals = $properties['intervals']['items']['properties']; + $this->assertEquals( 6, count( $intervals ) ); + $this->assertArrayHasKey( 'interval', $intervals ); + $this->assertArrayHasKey( 'date_start', $intervals ); + $this->assertArrayHasKey( 'date_start_gmt', $intervals ); + $this->assertArrayHasKey( 'date_end', $intervals ); + $this->assertArrayHasKey( 'date_end_gmt', $intervals ); + $this->assertArrayHasKey( 'subtotals', $intervals ); + + $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; + $this->assertEquals( 6, count( $subtotals ) ); + $this->assertArrayHasKey( 'order_tax', $subtotals ); + $this->assertArrayHasKey( 'orders_count', $subtotals ); + $this->assertArrayHasKey( 'shipping_tax', $subtotals ); + $this->assertArrayHasKey( 'tax_codes', $subtotals ); + $this->assertArrayHasKey( 'total_tax', $subtotals ); + $this->assertArrayHasKey( 'segments', $subtotals ); + + } +} diff --git a/tests/Version4/Reports/reports-taxes.php b/tests/Version4/Reports/reports-taxes.php new file mode 100644 index 00000000000..e0de47dbe73 --- /dev/null +++ b/tests/Version4/Reports/reports-taxes.php @@ -0,0 +1,363 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_id' => 1, + 'tax_rate' => '7', + 'tax_rate_country' => 'US', + 'tax_rate_state' => 'GA', + 'tax_rate_name' => 'TestTax', + 'tax_rate_priority' => 1, + 'tax_rate_order' => 1, + ) + ); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + // @todo Remove this once order data is synced to wc_order_tax_lookup + $wpdb->insert( + $wpdb->prefix . 'wc_order_tax_lookup', + array( + 'order_id' => $order->get_id(), + 'tax_rate_id' => 1, + 'date_created' => date( 'Y-m-d H:i:s' ), + 'shipping_tax' => 2, + 'order_tax' => 5, + 'total_tax' => 7, + ) + ); + + WC_Helper_Queue::run_all_pending(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + + $tax_report = reset( $reports ); + + $this->assertEquals( 1, $tax_report['tax_rate_id'] ); + $this->assertEquals( 'TestTax', $tax_report['name'] ); + $this->assertEquals( 7, $tax_report['tax_rate'] ); + $this->assertEquals( 'US', $tax_report['country'] ); + $this->assertEquals( 'GA', $tax_report['state'] ); + $this->assertEquals( 7, $tax_report['total_tax'] ); + $this->assertEquals( 5, $tax_report['order_tax'] ); + $this->assertEquals( 2, $tax_report['shipping_tax'] ); + $this->assertEquals( 1, $tax_report['orders_count'] ); + } + + /** + * Test getting reports with the `taxes` report. + * + * @since 3.5.0 + */ + public function test_get_reports_taxes_param() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_id' => 1, + 'tax_rate' => '7', + 'tax_rate_country' => 'US', + 'tax_rate_state' => 'GA', + 'tax_rate_name' => 'TestTax', + 'tax_rate_priority' => 1, + 'tax_rate_order' => 1, + ) + ); + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_id' => 2, + 'tax_rate' => '8', + 'tax_rate_country' => 'CA', + 'tax_rate_state' => 'ON', + 'tax_rate_name' => 'TestTax 2', + 'tax_rate_priority' => 1, + 'tax_rate_order' => 1, + ) + ); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + // @todo Remove this once order data is synced to wc_order_tax_lookup + $wpdb->insert( + $wpdb->prefix . 'wc_order_tax_lookup', + array( + 'order_id' => $order->get_id(), + 'tax_rate_id' => 1, + 'date_created' => date( 'Y-m-d H:i:s' ), + 'shipping_tax' => 2, + 'order_tax' => 5, + 'total_tax' => 7, + ) + ); + + WC_Helper_Queue::run_all_pending(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'taxes' => '1,2', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $tax_report = reset( $reports ); + + $this->assertEquals( 2, $tax_report['tax_rate_id'] ); + $this->assertEquals( 'TestTax 2', $tax_report['name'] ); + $this->assertEquals( 8, $tax_report['tax_rate'] ); + $this->assertEquals( 'CA', $tax_report['country'] ); + $this->assertEquals( 'ON', $tax_report['state'] ); + $this->assertEquals( 0, $tax_report['total_tax'] ); + $this->assertEquals( 0, $tax_report['order_tax'] ); + $this->assertEquals( 0, $tax_report['shipping_tax'] ); + $this->assertEquals( 0, $tax_report['orders_count'] ); + + $tax_report = next( $reports ); + + $this->assertEquals( 1, $tax_report['tax_rate_id'] ); + $this->assertEquals( 'TestTax', $tax_report['name'] ); + $this->assertEquals( 7, $tax_report['tax_rate'] ); + $this->assertEquals( 'US', $tax_report['country'] ); + $this->assertEquals( 'GA', $tax_report['state'] ); + $this->assertEquals( 7, $tax_report['total_tax'] ); + $this->assertEquals( 5, $tax_report['order_tax'] ); + $this->assertEquals( 2, $tax_report['shipping_tax'] ); + $this->assertEquals( 1, $tax_report['orders_count'] ); + } + + /** + * Test getting reports with param `orderby=rate`. + * + * @since 3.5.0 + */ + public function test_get_reports_orderby_tax_rate() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_id' => 1, + 'tax_rate' => '7', + 'tax_rate_country' => 'US', + 'tax_rate_state' => 'GA', + 'tax_rate_name' => 'TestTax', + 'tax_rate_priority' => 1, + 'tax_rate_order' => 1, + ) + ); + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_id' => 2, + 'tax_rate' => '10', + 'tax_rate_country' => 'CA', + 'tax_rate_state' => 'ON', + 'tax_rate_name' => 'TestTax 2', + 'tax_rate_priority' => 1, + 'tax_rate_order' => 1, + ) + ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'order' => 'asc', + 'orderby' => 'rate', + 'taxes' => '1,2', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $this->assertEquals( 1, $reports[0]['tax_rate_id'] ); + $this->assertEquals( 7, $reports[0]['tax_rate'] ); + + $this->assertEquals( 2, $reports[1]['tax_rate_id'] ); + $this->assertEquals( 10, $reports[1]['tax_rate'] ); + } + + /** + * Test getting reports with param `orderby=tax_code`. + * + * @since 3.5.0 + */ + public function test_get_reports_orderby_tax_code() { + global $wpdb; + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_id' => 1, + 'tax_rate' => '7', + 'tax_rate_country' => 'US', + 'tax_rate_state' => 'GA', + 'tax_rate_name' => 'TestTax', + 'tax_rate_priority' => 1, + 'tax_rate_order' => 1, + ) + ); + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_id' => 2, + 'tax_rate' => '10', + 'tax_rate_country' => 'CA', + 'tax_rate_state' => 'ON', + 'tax_rate_name' => 'TestTax 2', + 'tax_rate_priority' => 1, + 'tax_rate_order' => 1, + ) + ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'order' => 'asc', + 'orderby' => 'tax_code', + 'taxes' => '1,2', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $this->assertEquals( 2, $reports[0]['tax_rate_id'] ); + + $this->assertEquals( 1, $reports[1]['tax_rate_id'] ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 10, count( $properties ) ); + $this->assertArrayHasKey( 'tax_rate_id', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'tax_rate', $properties ); + $this->assertArrayHasKey( 'country', $properties ); + $this->assertArrayHasKey( 'state', $properties ); + $this->assertArrayHasKey( 'priority', $properties ); + $this->assertArrayHasKey( 'total_tax', $properties ); + $this->assertArrayHasKey( 'order_tax', $properties ); + $this->assertArrayHasKey( 'shipping_tax', $properties ); + $this->assertArrayHasKey( 'orders_count', $properties ); + } +} diff --git a/tests/Version4/Reports/reports-variations.php b/tests/Version4/Reports/reports-variations.php new file mode 100644 index 00000000000..d4b12df1237 --- /dev/null +++ b/tests/Version4/Reports/reports-variations.php @@ -0,0 +1,183 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $variation = new WC_Product_Variation(); + $variation->set_name( 'Test Variation' ); + $variation->set_regular_price( 25 ); + $variation->set_attributes( array( 'color' => 'green' ) ); + $variation->save(); + + $order = WC_Helper_Order::create_order( 1, $variation ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $reports ) ); + + $variation_report = reset( $reports ); + + $this->assertEquals( $variation->get_id(), $variation_report['variation_id'] ); + $this->assertEquals( 4, $variation_report['items_sold'] ); + $this->assertEquals( 1, $variation_report['orders_count'] ); + $this->assertArrayHasKey( '_links', $variation_report ); + $this->assertArrayHasKey( 'extended_info', $variation_report ); + $this->assertArrayHasKey( 'product', $variation_report['_links'] ); + $this->assertArrayHasKey( 'variation', $variation_report['_links'] ); + } + + /** + * Test getting reports with the `variations` param. + * + * @since 3.5.0 + */ + public function test_get_reports_variations_param() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + // Populate all of the data. + $variation = new WC_Product_Variation(); + $variation->set_name( 'Test Variation' ); + $variation->set_regular_price( 25 ); + $variation->set_attributes( array( 'color' => 'green' ) ); + $variation->save(); + + $variation_2 = new WC_Product_Variation(); + $variation_2->set_name( 'Test Variation 2' ); + $variation_2->set_regular_price( 100 ); + $variation_2->set_attributes( array( 'color' => 'red' ) ); + $variation_2->save(); + + $order = WC_Helper_Order::create_order( 1, $variation ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); // $25 x 4. + $order->save(); + + WC_Helper_Queue::run_all_pending(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'product_includes' => $variation->get_parent_id(), + 'products' => $variation->get_parent_id(), + 'variations' => $variation->get_id() . ',' . $variation_2->get_id(), + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $reports ) ); + + $variation_report = reset( $reports ); + + $this->assertEquals( $variation->get_id(), $variation_report['variation_id'] ); + $this->assertEquals( 4, $variation_report['items_sold'] ); + $this->assertEquals( 1, $variation_report['orders_count'] ); + $this->assertArrayHasKey( '_links', $variation_report ); + $this->assertArrayHasKey( 'extended_info', $variation_report ); + $this->assertArrayHasKey( 'product', $variation_report['_links'] ); + $this->assertArrayHasKey( 'variation', $variation_report['_links'] ); + + $variation_report = next( $reports ); + + $this->assertEquals( $variation_2->get_id(), $variation_report['variation_id'] ); + $this->assertEquals( 0, $variation_report['items_sold'] ); + $this->assertEquals( 0, $variation_report['orders_count'] ); + $this->assertArrayHasKey( '_links', $variation_report ); + $this->assertArrayHasKey( 'extended_info', $variation_report ); + $this->assertArrayHasKey( 'product', $variation_report['_links'] ); + $this->assertArrayHasKey( 'variation', $variation_report['_links'] ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 6, count( $properties ) ); + $this->assertArrayHasKey( 'product_id', $properties ); + $this->assertArrayHasKey( 'variation_id', $properties ); + $this->assertArrayHasKey( 'items_sold', $properties ); + $this->assertArrayHasKey( 'net_revenue', $properties ); + $this->assertArrayHasKey( 'orders_count', $properties ); + $this->assertArrayHasKey( 'extended_info', $properties ); + } +} diff --git a/tests/Version4/admin-notes.php b/tests/Version4/admin-notes.php new file mode 100644 index 00000000000..54b63a23c94 --- /dev/null +++ b/tests/Version4/admin-notes.php @@ -0,0 +1,313 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + + WC_Helper_Admin_Notes::reset_notes_dbs(); + WC_Helper_Admin_Notes::add_notes_for_tests(); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test getting a single note. + * + * @since 3.5.0 + */ + public function test_get_note() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); + $note = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 1, $note['id'] ); + $this->assertEquals( 'PHPUNIT_TEST_NOTE_NAME', $note['name'] ); + $this->assertEquals( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL, $note['type'] ); + $this->assertArrayHasKey( 'locale', $note ); + $this->assertEquals( 'PHPUNIT_TEST_NOTE_1_TITLE', $note['title'] ); + + $this->assertEquals( 'PHPUNIT_TEST_NOTE_1_CONTENT', $note['content'] ); + $this->assertEquals( 'info', $note['icon'] ); + $this->assertArrayHasKey( 'content_data', $note ); + $this->assertEquals( 1.23, $note['content_data']->amount ); + $this->assertEquals( WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED, $note['status'] ); + $this->assertEquals( 'PHPUNIT_TEST', $note['source'] ); + + $this->assertArrayHasKey( 'date_created', $note ); + $this->assertArrayHasKey( 'date_created_gmt', $note ); + $this->assertArrayHasKey( 'date_reminder', $note ); + $this->assertArrayHasKey( 'date_reminder_gmt', $note ); + $this->assertArrayHasKey( 'actions', $note ); + + $this->assertEquals( 'PHPUNIT_TEST_NOTE_1_ACTION_1_SLUG', $note['actions'][0]->name ); + $this->assertEquals( 'http://example.org/wp-admin/admin.php?s=PHPUNIT_TEST_NOTE_1_ACTION_1_URL', $note['actions'][0]->url ); + } + + /** + * Test getting a 404 from invalid ID. + * + * @since 3.5.0 + */ + public function test_get_invalid_note() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/999' ) ); + $note = $response->get_data(); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single note without permission. It should fail. + * + * @since 3.5.0 + */ + public function test_get_note_without_permission() { + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single note. + */ + public function test_update_note() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); + $note = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'unactioned', $note['status'] ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint . '/1' ); + $request->set_body_params( + array( + 'status' => 'actioned', + ) + ); + + $response = $this->server->dispatch( $request ); + $note = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'actioned', $note['status'] ); + } + + /** + * Test updating a single note without permission. It should fail. + */ + public function test_update_note_without_permission() { + $request = new WP_REST_Request( 'PUT', $this->endpoint . '/1' ); + $request->set_body_params( + array( + 'status' => 'actioned', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting lots of notes. + * + * @since 3.5.0 + */ + public function test_get_notes() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $notes = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 3, count( $notes ) ); + } + + /** + * Test getting notes of a certain type. + * + * @since 3.5.0 + */ + public function test_get_warning_notes() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'type' => 'warning' ) ); + $response = $this->server->dispatch( $request ); + $notes = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $notes ) ); + $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' ); + } + + + /** + * Test getting notes of a certain status. + */ + public function test_get_actioned_notes() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'status' => 'actioned' ) ); + $response = $this->server->dispatch( $request ); + $notes = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $notes ) ); + $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'status' => 'invalid' ) ); + $response = $this->server->dispatch( $request ); + $notes = $response->get_data(); + + // get_notes returns all results since 'status' is not one of actioned or unactioned. + $this->assertEquals( 3, count( $notes ) ); + } + + /** + * Test note "unsnoozing". + */ + public function test_note_unsnoozing() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'status' => 'snoozed' ) ); + $response = $this->server->dispatch( $request ); + $notes = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $notes ) ); + $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_3_TITLE' ); + + // The test snoozed note's reminder date is an hour ago. + WC_Admin_Notes::unsnooze_notes(); + + $response = $this->server->dispatch( $request ); + $notes = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEmpty( $notes ); + } + + /** + * Test ordering of notes. + */ + public function test_order_notes() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'orderby' => 'title', + 'order' => 'asc', + ) + ); + $response = $this->server->dispatch( $request ); + $notes = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 3, count( $notes ) ); + $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_1_TITLE' ); + $this->assertEquals( $notes[1]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' ); + $this->assertEquals( $notes[2]['title'], 'PHPUNIT_TEST_NOTE_3_TITLE' ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( + array( + 'orderby' => 'status', + 'order' => 'desc', + ) + ); + $response = $this->server->dispatch( $request ); + $notes = $response->get_data(); + + $this->assertEquals( 3, count( $notes ) ); + $this->assertEquals( $notes[0]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED ); + $this->assertEquals( $notes[1]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED ); + $this->assertEquals( $notes[2]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED ); + } + + /** + * Test getting lots of notes without permission. It should fail. + * + * @since 3.5.0 + */ + public function test_get_notes_without_permission() { + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting the notes schema. + * + * @since 3.5.0 + */ + public function test_get_notes_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 16, count( $properties ) ); + + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'locale', $properties ); + $this->assertArrayHasKey( 'title', $properties ); + + $this->assertArrayHasKey( 'content', $properties ); + $this->assertArrayHasKey( 'icon', $properties ); + $this->assertArrayHasKey( 'content_data', $properties ); + $this->assertArrayHasKey( 'status', $properties ); + $this->assertArrayHasKey( 'source', $properties ); + + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_created_gmt', $properties ); + $this->assertArrayHasKey( 'date_reminder', $properties ); + $this->assertArrayHasKey( 'date_reminder_gmt', $properties ); + $this->assertArrayHasKey( 'actions', $properties ); + $this->assertArrayHasKey( 'is_snoozable', $properties ); + } +} diff --git a/tests/Version4/data.php b/tests/Version4/data.php new file mode 100644 index 00000000000..88e4704eff3 --- /dev/null +++ b/tests/Version4/data.php @@ -0,0 +1,119 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test that the list of data endpoints includes download-ips. + */ + public function test_get_items_contains_download_ips() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 4, count( $data ) ); + $this->assertEquals( 'download-ips', $data[3]['slug'] ); + } + + /** + * Test download-ips match searching. + */ + public function test_download_ips() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + $prod_download = new WC_Product_Download(); + $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); + $prod_download->set_id( 1 ); + + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_downloadable( 'yes' ); + $product->set_downloads( array( $prod_download ) ); + $product->set_regular_price( 25 ); + $product->save(); + + $order = WC_Helper_Order::create_order( 1, $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); + $order->save(); + + $download = new WC_Customer_Download(); + $download->set_user_id( $this->user ); + $download->set_order_id( $order->get_id() ); + $download->set_product_id( $product->get_id() ); + $download->set_download_id( $prod_download->get_id() ); + $download->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '1.2.3.4' ); + $id = $object->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '54.2.1.3' ); + $id = $object->save(); + + // Save a second log for the same IP -- only one result for this IP should be returned. + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '54.2.1.3' ); + $id = $object->save(); + + $object = new WC_Customer_Download_Log(); + $object->set_permission_id( $download->get_id() ); + $object->set_user_id( $this->user ); + $object->set_user_ip_address( '54.5.1.7' ); + $id = $object->save(); + + $request = new WP_REST_Request( 'GET', $this->endpoint . '/download-ips' ); + $request->set_query_params( + array( + 'match' => '54', + ) + ); + + $response = $this->server->dispatch( $request ); + $addresses = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $addresses ) ); + + $this->assertEquals( '54.2.1.3', $addresses[0]['user_ip_address'] ); + $this->assertEquals( '54.5.1.7', $addresses[1]['user_ip_address'] ); + } +} diff --git a/tests/Version4/leaderboards.php b/tests/Version4/leaderboards.php new file mode 100644 index 00000000000..e2e0a0ac696 --- /dev/null +++ b/tests/Version4/leaderboards.php @@ -0,0 +1,154 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test that leaderboards are returned by the endpoint. + */ + public function test_get_leaderboards() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'customers', $data[0]['id'] ); + $this->assertEquals( 'coupons', $data[1]['id'] ); + $this->assertEquals( 'categories', $data[2]['id'] ); + $this->assertEquals( 'products', $data[3]['id'] ); + } + + /** + * Test reports schema. + */ + public function test_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 4, $properties ); + $this->assert_item_schema( $properties ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint . '/allowed' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 3, $properties ); + $this->assert_allowed_item_schema( $properties ); + } + + /** + * Asserts the item schema is correct. + * + * @param array $schema Item to check schema. + */ + public function assert_item_schema( $schema ) { + $this->assertArrayHasKey( 'id', $schema ); + $this->assertArrayHasKey( 'label', $schema ); + $this->assertArrayHasKey( 'headers', $schema ); + $this->assertArrayHasKey( 'rows', $schema ); + + $header_properties = $schema['headers']['items']['properties']; + $this->assertCount( 1, $header_properties ); + $this->assertArrayHasKey( 'label', $header_properties ); + + $row_properties = $schema['rows']['items']['properties']; + $this->assertCount( 2, $row_properties ); + $this->assertArrayHasKey( 'display', $row_properties ); + $this->assertArrayHasKey( 'value', $row_properties ); + } + + /** + * Asserts the allowed item schema is correct. + * + * @param array $schema Item to check schema. + */ + public function assert_allowed_item_schema( $schema ) { + $this->assertArrayHasKey( 'id', $schema ); + $this->assertArrayHasKey( 'label', $schema ); + $this->assertArrayHasKey( 'headers', $schema ); + + $header_properties = $schema['headers']['items']['properties']; + $this->assertCount( 1, $header_properties ); + $this->assertArrayHasKey( 'label', $header_properties ); + } + + /** + * Test that leaderboards response changes based on applied filters. + */ + public function test_filter_leaderboards() { + wp_set_current_user( $this->user ); + + add_filter( + 'woocommerce_leaderboards', + function( $leaderboards, $per_page, $after, $before, $persisted_query ) { + $leaderboards[] = array( + 'id' => 'top_widgets', + 'label' => 'Top Widgets', + 'headers' => array( + array( + 'label' => 'Widget Link', + ), + ), + 'rows' => array( + array( + 'display' => wc_admin_url( 'test/path', $persisted_query ), + 'value' => null, + ), + ), + ); + return $leaderboards; + }, + 10, + 5 + ); + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request->set_query_params( array( 'persisted_query' => '{ "persisted_param": 1 }' ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $widgets_leaderboard = end( $data ); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'top_widgets', $widgets_leaderboard['id'] ); + $this->assertEquals( admin_url( 'admin.php?page=wc-admin#test/path?persisted_param=1' ), $widgets_leaderboard['rows'][0]['display'] ); + + $request = new WP_REST_Request( 'GET', $this->endpoint . '/allowed' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $widgets_leaderboard = end( $data ); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'top_widgets', $widgets_leaderboard['id'] ); + } +} diff --git a/tests/Version4/product-reviews.php b/tests/Version4/product-reviews.php new file mode 100644 index 00000000000..41571b8aaef --- /dev/null +++ b/tests/Version4/product-reviews.php @@ -0,0 +1,50 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test product reviews shows product field as embeddable. + */ + public function test_product_review_embed() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/products/reviews' ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertTrue( $data[0]['_links']['up'][0]['embeddable'] ); + + $product->delete( true ); + } +} diff --git a/tests/Version4/products.php b/tests/Version4/products.php new file mode 100644 index 00000000000..3ff0a150c82 --- /dev/null +++ b/tests/Version4/products.php @@ -0,0 +1,62 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test product schema contains embed fields. + */ + public function test_product_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $properties_to_embed = array( + 'id', + 'name', + 'slug', + 'permalink', + 'images', + 'description', + 'short_description', + ); + + foreach ( $properties as $property_key => $property ) { + if ( in_array( $property_key, $properties_to_embed, true ) ) { + $this->assertEquals( array( 'view', 'edit', 'embed' ), $property['context'] ); + } + } + + $product->delete( true ); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 38893381864..cc42b05115a 100755 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -43,6 +43,7 @@ require $tests_dir . '/includes/bootstrap.php'; require $wc_tests_dir . '/bootstrap.php'; // Framework. +require_once __DIR__ . '/AbstractRestApiTest.php'; require_once $wc_tests_dir . '/framework/class-wc-unit-test-factory.php'; require_once $wc_tests_dir . '/framework/class-wc-mock-session-handler.php'; require_once $wc_tests_dir . '/framework/class-wc-mock-wc-data.php'; From 91647f305188b80adfd9c66242da7ba85687811a Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 7 Jun 2019 17:16:28 +0100 Subject: [PATCH 059/440] ProductReviews/Products tests --- .../Version4/Controllers/ProductReviews.php | 30 +- tests/AbstractRestApiTest.php | 42 +- tests/Version4/Coupons.php | 12 +- tests/Version4/Orders.php | 20 +- tests/Version4/ProductReviews.php | 400 +++++++++ tests/Version4/product-reviews.php | 50 -- tests/Version4/products.php | 809 +++++++++++++++++- 7 files changed, 1228 insertions(+), 135 deletions(-) create mode 100644 tests/Version4/ProductReviews.php delete mode 100644 tests/Version4/product-reviews.php diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/RestApi/Version4/Controllers/ProductReviews.php index e7ebff54136..351ded63a1c 100644 --- a/src/RestApi/Version4/Controllers/ProductReviews.php +++ b/src/RestApi/Version4/Controllers/ProductReviews.php @@ -297,11 +297,11 @@ class ProductReviews extends AbstractController { } /** - * Filters arguments, before passing to WP_Comment_Query, when querying reviews via the REST API. + * Filters arguments, before passing to \WP_Comment_Query, when querying reviews via the REST API. * * @since 3.5.0 - * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ - * @param array $prepared_args Array of arguments for WP_Comment_Query. + * @link https://developer.wordpress.org/reference/classes/\WP_Comment_Query/ + * @param array $prepared_args Array of arguments for \WP_Comment_Query. * @param \WP_REST_Request $request The current request. */ $prepared_args = apply_filters( 'woocommerce_rest_product_review_query', $prepared_args, $request ); @@ -310,7 +310,7 @@ class ProductReviews extends AbstractController { $prepared_args['type'] = 'review'; // Query reviews. - $query = new WP_Comment_Query(); + $query = new \WP_Comment_Query(); $query_result = $query->query( $prepared_args ); $reviews = array(); @@ -330,7 +330,7 @@ class ProductReviews extends AbstractController { // Out-of-bounds, run the query again without LIMIT for total count. unset( $prepared_args['number'], $prepared_args['offset'] ); - $query = new WP_Comment_Query(); + $query = new \WP_Comment_Query(); $prepared_args['count'] = true; $total_reviews = $query->query( $prepared_args ); @@ -368,7 +368,7 @@ class ProductReviews extends AbstractController { * Create a single review. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -499,7 +499,7 @@ class ProductReviews extends AbstractController { * Get a single product review. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $review = $this->get_review( $request['id'] ); @@ -517,7 +517,7 @@ class ProductReviews extends AbstractController { * Updates a review. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response Response object on success, or error object on failure. + * @return \WP_Error|\WP_REST_Response Response object on success, or error object on failure. */ public function update_item( $request ) { $review = $this->get_review( $request['id'] ); @@ -603,7 +603,7 @@ class ProductReviews extends AbstractController { * Deletes a review. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response Response object on success, or error object on failure. + * @return \WP_Error|\WP_REST_Response Response object on success, or error object on failure. */ public function delete_item( $request ) { $review = $this->get_review( $request['id'] ); @@ -629,7 +629,7 @@ class ProductReviews extends AbstractController { if ( $force ) { $previous = $this->prepare_item_for_response( $review, $request ); $result = wp_delete_comment( $review->comment_ID, true ); - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -660,7 +660,7 @@ class ProductReviews extends AbstractController { * Fires after a review is deleted via the REST API. * * @param WP_Comment $review The deleted review data. - * @param WP_REST_Response $response The response returned from the API. + * @param \WP_REST_Response $response The response returned from the API. * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_review', $review, $response, $request ); @@ -673,7 +673,7 @@ class ProductReviews extends AbstractController { * * @param WP_Comment $review Product review object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $review, $request ) { $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; @@ -725,7 +725,7 @@ class ProductReviews extends AbstractController { /** * Filter product reviews object returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WP_Comment $review Product review object used to create response. * @param \WP_REST_Request $request Request object. */ @@ -1021,8 +1021,8 @@ class ProductReviews extends AbstractController { * Filter collection parameters for the reviews controller. * * This filter registers the collection parameter, but does not map the - * collection parameter to an internal WP_Comment_Query parameter. Use the - * `wc_rest_review_query` filter to set WP_Comment_Query parameters. + * collection parameter to an internal \WP_Comment_Query parameter. Use the + * `wc_rest_review_query` filter to set \WP_Comment_Query parameters. * * @since 3.5.0 * @param array $params JSON Schema-formatted collection parameters. diff --git a/tests/AbstractRestApiTest.php b/tests/AbstractRestApiTest.php index 3809d31461e..1d60be6f376 100644 --- a/tests/AbstractRestApiTest.php +++ b/tests/AbstractRestApiTest.php @@ -90,60 +90,28 @@ abstract class AbstractRestApiTest extends WC_REST_Unit_Test_Case { } /** - * Classes should test creation using this method. + * Test creation using this method. * If read-only, test to confirm this. */ abstract public function test_create(); /** - * Classes should test get/read using this method. + * Test get/read using this method. */ abstract public function test_read(); /** - * Classes should test updates using this method. + * Test updates using this method. * If read-only, test to confirm this. */ abstract public function test_update(); /** - * Classes should test delete using this method. + * Test delete using this method. * If read-only, test to confirm this. */ abstract public function test_delete(); - /** - * Tests delete when there is no user logged in. - */ - public function test_guest_create() { - wp_set_current_user( 0 ); - $this->assertEquals( 0, get_current_user_id() ); - } - - /** - * Tests delete when there is no user logged in. - */ - public function test_guest_read() { - wp_set_current_user( 0 ); - $this->assertEquals( 0, get_current_user_id() ); - } - - /** - * Tests delete when there is no user logged in. - */ - public function test_guest_update() { - wp_set_current_user( 0 ); - $this->assertEquals( 0, get_current_user_id() ); - } - - /** - * Tests delete when there is no user logged in. - */ - public function test_guest_delete() { - wp_set_current_user( 0 ); - $this->assertEquals( 0, get_current_user_id() ); - } - /** * Perform a request and return the status and returned data. * @@ -153,7 +121,7 @@ abstract class AbstractRestApiTest extends WC_REST_Unit_Test_Case { * @return object */ protected function do_request( $endpoint, $type = 'GET', $params = [] ) { - $request = new \WP_REST_Request( $type, $endpoint ); + $request = new \WP_REST_Request( $type, untrailingslashit( $endpoint ) ); 'GET' === $type ? $request->set_query_params( $params ) : $request->set_body_params( $params ); $response = $this->server->dispatch( $request ); diff --git a/tests/Version4/Coupons.php b/tests/Version4/Coupons.php index 7c6d65cc0dd..b456b2ded0f 100644 --- a/tests/Version4/Coupons.php +++ b/tests/Version4/Coupons.php @@ -189,8 +189,7 @@ class Coupons extends AbstractRestApiTest { * Test read. */ public function test_guest_create() { - parent::test_guest_create(); - + wp_set_current_user( 0 ); $valid_data = [ 'code' => 'test-coupon', 'amount' => '5.00', @@ -225,8 +224,7 @@ class Coupons extends AbstractRestApiTest { * Test read. */ public function test_guest_read() { - parent::test_guest_read(); - + wp_set_current_user( 0 ); $response = $this->do_request( '/wc/v4/coupons', 'GET' ); $this->assertExpectedResponse( $response, 401 ); } @@ -235,8 +233,7 @@ class Coupons extends AbstractRestApiTest { * Test update. */ public function test_guest_update() { - parent::test_guest_update(); - + wp_set_current_user( 0 ); $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); $response = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), @@ -253,8 +250,7 @@ class Coupons extends AbstractRestApiTest { * Test delete. */ public function test_guest_delete() { - parent::test_guest_delete(); - + wp_set_current_user( 0 ); $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); $this->assertEquals( 401, $result->status ); diff --git a/tests/Version4/Orders.php b/tests/Version4/Orders.php index 15ee8e399a3..55ceeb59d1d 100644 --- a/tests/Version4/Orders.php +++ b/tests/Version4/Orders.php @@ -371,8 +371,7 @@ class Orders extends AbstractRestApiTest { * Test read. */ public function test_guest_create() { - parent::test_guest_create(); - + wp_set_current_user( 0 ); $product = \WC_Helper_Product::create_simple_product(); $data = [ 'currency' => 'ZAR', @@ -428,8 +427,7 @@ class Orders extends AbstractRestApiTest { * Test read. */ public function test_guest_read() { - parent::test_guest_read(); - + wp_set_current_user( 0 ); $response = $this->do_request( '/wc/v4/orders', 'GET' ); $this->assertExpectedResponse( $response, 401 ); } @@ -438,8 +436,7 @@ class Orders extends AbstractRestApiTest { * Test update. */ public function test_guest_update() { - parent::test_guest_update(); - + wp_set_current_user( 0 ); $order = \WC_Helper_Order::create_order(); $data = [ 'payment_method' => 'test-update', @@ -460,8 +457,7 @@ class Orders extends AbstractRestApiTest { * Test delete. */ public function test_guest_delete() { - parent::test_guest_delete(); - + wp_set_current_user( 0 ); $order = \WC_Helper_Order::create_order(); $response = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => true ] ); $this->assertEquals( 401, $response->status ); @@ -547,7 +543,7 @@ class Orders extends AbstractRestApiTest { $fee_data = current( $order->get_items( 'fee' ) ); $response = $this->do_request( - '/wc/v3/orders/' . $order->get_id(), + '/wc/v4/orders/' . $order->get_id(), 'PUT', [ 'fee_lines' => array( @@ -575,7 +571,7 @@ class Orders extends AbstractRestApiTest { $coupon->save(); $response = $this->do_request( - '/wc/v3/orders/' . $order->get_id(), + '/wc/v4/orders/' . $order->get_id(), 'PUT', [ 'coupon_lines' => array( @@ -609,7 +605,7 @@ class Orders extends AbstractRestApiTest { $coupon_data = current( $order->get_items( 'coupon' ) ); $response = $this->do_request( - '/wc/v3/orders/' . $order->get_id(), + '/wc/v4/orders/' . $order->get_id(), 'PUT', [ 'coupon_lines' => array( @@ -640,7 +636,7 @@ class Orders extends AbstractRestApiTest { public function test_invalid_coupon() { $order = \WC_Helper_Order::create_order(); $response = $this->do_request( - '/wc/v3/orders/' . $order->get_id(), + '/wc/v4/orders/' . $order->get_id(), 'PUT', [ 'coupon_lines' => array( diff --git a/tests/Version4/ProductReviews.php b/tests/Version4/ProductReviews.php new file mode 100644 index 00000000000..f0548796fb1 --- /dev/null +++ b/tests/Version4/ProductReviews.php @@ -0,0 +1,400 @@ +[\d]+)', + '/wc/v4/products/reviews/batch', + ]; + + /** + * The endpoint schema. + * + * @var array Keys are property names, values are supported context. + */ + protected $properties = [ + 'id' => array( 'view', 'edit' ), + 'date_created' => array( 'view', 'edit' ), + 'date_created_gmt' => array( 'view', 'edit' ), + 'product_id' => array( 'view', 'edit' ), + 'status' => array( 'view', 'edit' ), + 'reviewer' => array( 'view', 'edit' ), + 'reviewer_email' => array( 'view', 'edit' ), + 'review' => array( 'view', 'edit' ), + 'rating' => array( 'view', 'edit' ), + 'verified' => array( 'view', 'edit' ), + 'reviewer_avatar_urls' => array( 'view', 'edit' ), + ]; + + /** + * Test creation using this method. + * If read-only, test to confirm this. + */ + public function test_create() { + $product = \WC_Helper_Product::create_simple_product(); + $data = [ + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + 'rating' => '5', + 'product_id' => $product->get_id(), + ]; + $response = $this->do_request( '/wc/v4/products/reviews', 'POST', $data ); + $this->assertExpectedResponse( $response, 201, $data ); + $this->assertEquals( + array( + 'id' => $response->data['id'], + 'date_created' => $response->data['date_created'], + 'date_created_gmt' => $response->data['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => 'Hello world.', + 'rating' => 5, + 'verified' => false, + 'reviewer_avatar_urls' => $response->data['reviewer_avatar_urls'], + ), + $response->data + ); + } + + /** + * Test get/read using this method. + */ + public function test_read() { + $product = \WC_Helper_Product::create_simple_product(); + for ( $i = 0; $i < 10; $i++ ) { + $review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + } + + // Invalid. + $response = $this->do_request( '/wc/v4/products/0/reviews' ); + $this->assertExpectedResponse( $response, 404 ); + + // Collections. + $response = $this->do_request( '/wc/v4/products/reviews' ); + $product_reviews = $response->data; + + $this->assertExpectedResponse( $response, 200 ); + $this->assertEquals( 10, count( $product_reviews ) ); + $this->assertContains( + array( + 'id' => $review_id, + 'date_created' => $product_reviews[0]['date_created'], + 'date_created_gmt' => $product_reviews[0]['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => "

Review content here

\n", + 'rating' => 0, + 'verified' => false, + 'reviewer_avatar_urls' => $product_reviews[0]['reviewer_avatar_urls'], + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/products/reviews/' . $review_id ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/products/reviews' ), + ), + ), + 'up' => array( + array( + 'embeddable' => true, + 'href' => rest_url( '/wc/v4/products/' . $product->get_id() ), + ), + ), + ), + ), + $product_reviews + ); + } + + /** + * Test updates using this method. + * If read-only, test to confirm this. + */ + public function test_update() { + $product = \WC_Helper_Product::create_simple_product(); + $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + + $response = $this->do_request( '/wc/v4/products/reviews/' . $product_review_id ); + $this->assertEquals( 200, $response->status ); + $this->assertEquals( "

Review content here

\n", $response->data['review'] ); + $this->assertEquals( 'admin', $response->data['reviewer'] ); + $this->assertEquals( 'woo@woo.local', $response->data['reviewer_email'] ); + $this->assertEquals( 0, $response->data['rating'] ); + + $data = [ + 'review' => 'Hello world - updated.', + 'reviewer' => 'Justin', + 'reviewer_email' => 'woo2@woo.local', + 'rating' => 3, + ]; + $response = $this->do_request( '/wc/v4/products/reviews/' . $product_review_id, 'PUT', $data ); + + $this->assertExpectedResponse( $response, 200, $data ); + + foreach ( $this->get_properties( 'view' ) as $property ) { + $this->assertArrayHasKey( $property, $response->data ); + } + } + + /** + * Test delete using this method. + * If read-only, test to confirm this. + */ + public function test_delete() { + // Invalid. + $result = $this->do_request( '/wc/v4/products/reviews/0', 'DELETE', [ 'force' => true ] ); + $this->assertEquals( 404, $result->status ); + + // Valid. + $product = \WC_Helper_Product::create_simple_product(); + $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $result = $this->do_request( '/wc/v4/products/reviews/' . $product_review_id, 'DELETE', [ 'force' => true ] ); + $this->assertEquals( 200, $result->status ); + } + + /** + * Test get/read using this method. + */ + public function test_guest_read() { + wp_set_current_user( 0 ); + $result = $this->do_request( '/wc/v4/products/reviews' ); + $this->assertEquals( 401, $result->status ); + } + + /** + * Tests getting a single product review. + * + * @since 3.5.0 + */ + public function test_get_product_review() { + $product = \WC_Helper_Product::create_simple_product(); + $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v4/products/reviews/' . $product_review_id ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $product_review_id, + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'product_id' => $product->get_id(), + 'status' => 'approved', + 'reviewer' => 'admin', + 'reviewer_email' => 'woo@woo.local', + 'review' => "

Review content here

\n", + 'rating' => 0, + 'verified' => false, + 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], + ), + $data + ); + } + + /** + * Tests getting a product review with an invalid ID. + * + * @since 3.5.0 + */ + public function test_get_product_review_invalid_id() { + $product = \WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v4/products/reviews/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests creating a product review without required fields. + * + * @since 3.5.0 + */ + public function test_create_product_review_invalid_fields() { + $product = \WC_Helper_Product::create_simple_product(); + + // missing review + $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews' ); + $request->set_body_params( + array( + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + + // Missing reviewer. + $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer_email' => 'woo@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + + // missing reviewer_email + $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Tests updating a product review without the correct permissions. + * + * @since 3.5.0 + */ + public function test_update_product_review_without_permission() { + wp_set_current_user( 0 ); + $product = \WC_Helper_Product::create_simple_product(); + $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new \WP_REST_Request( 'PUT', '/wc/v4/products/reviews/' . $product_review_id ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.dev', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests that updating a product review with an invalid id fails. + * + * @since 3.5.0 + */ + public function test_update_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = \WC_Helper_Product::create_simple_product(); + + $request = new \WP_REST_Request( 'PUT', '/wc/v4/products/reviews/0' ); + $request->set_body_params( + array( + 'review' => 'Hello world.', + 'reviewer' => 'Admin', + 'reviewer_email' => 'woo@woo.dev', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test deleting a product review without permission/creds. + * + * @since 3.5.0 + */ + public function test_delete_product_without_permission() { + wp_set_current_user( 0 ); + $product = \WC_Helper_Product::create_simple_product(); + $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new \WP_REST_Request( 'DELETE', '/wc/v4/products/reviews/' . $product_review_id ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch managing product reviews. + * + * @since 3.5.0 + */ + public function test_product_reviews_batch() { + wp_set_current_user( $this->user ); + $product = \WC_Helper_Product::create_simple_product(); + + $review_1_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $review_2_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $review_3_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $review_4_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + + $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $review_1_id, + 'review' => 'Updated review.', + ), + ), + 'delete' => array( + $review_2_id, + $review_3_id, + ), + 'create' => array( + array( + 'review' => 'New review.', + 'reviewer' => 'Justin', + 'reviewer_email' => 'woo3@woo.local', + 'product_id' => $product->get_id(), + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'Updated review.', $data['update'][0]['review'] ); + $this->assertEquals( 'New review.', $data['create'][0]['review'] ); + $this->assertEquals( $review_2_id, $data['delete'][0]['previous']['id'] ); + $this->assertEquals( $review_3_id, $data['delete'][1]['previous']['id'] ); + + $request = new \WP_REST_Request( 'GET', '/wc/v4/products/reviews' ); + $request->set_param( 'product', $product->get_id() ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } +} + diff --git a/tests/Version4/product-reviews.php b/tests/Version4/product-reviews.php deleted file mode 100644 index 41571b8aaef..00000000000 --- a/tests/Version4/product-reviews.php +++ /dev/null @@ -1,50 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test product reviews shows product field as embeddable. - */ - public function test_product_review_embed() { - wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - WC_Helper_Product::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/products/reviews' ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertTrue( $data[0]['_links']['up'][0]['embeddable'] ); - - $product->delete( true ); - } -} diff --git a/tests/Version4/products.php b/tests/Version4/products.php index 3ff0a150c82..9d0d30f56d0 100644 --- a/tests/Version4/products.php +++ b/tests/Version4/products.php @@ -1,33 +1,816 @@ [\d]+)', + '/wc/v4/products/batch', + ]; /** - * Setup test data. Called before every test. + * Test creation using this method. + * If read-only, test to confirm this. */ - public function setUp() { - parent::setUp(); + public function test_create() { - $this->user = $this->factory->user->create( + } + + /** + * Test get/read using this method. + */ + public function test_read() { + + } + + /** + * Test updates using this method. + * If read-only, test to confirm this. + */ + public function test_update() { + + } + + /** + * Test delete using this method. + * If read-only, test to confirm this. + */ + public function test_delete() { + + } + + /** + * Test getting products. + * + * @since 3.5.0 + */ + public function test_get_products() { + wp_set_current_user( $this->user ); + WC_Helper_Product::create_external_product(); + sleep( 1 ); // So both products have different timestamps. + WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 2, count( $products ) ); + $this->assertEquals( 'Dummy Product', $products[0]['name'] ); + $this->assertEquals( 'DUMMY SKU', $products[0]['sku'] ); + $this->assertEquals( 'Dummy External Product', $products[1]['name'] ); + $this->assertEquals( 'DUMMY EXTERNAL SKU', $products[1]['sku'] ); + } + + /** + * Test getting products without permission. + * + * @since 3.5.0 + */ + public function test_get_products_without_permission() { + wp_set_current_user( 0 ); + WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single product. + * + * @since 3.5.0 + */ + public function test_get_product() { + wp_set_current_user( $this->user ); + $simple = WC_Helper_Product::create_external_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $simple->get_id() ) ); + $product = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( array( - 'role' => 'administrator', + 'id' => $simple->get_id(), + 'name' => 'Dummy External Product', + 'type' => 'simple', + 'status' => 'publish', + 'sku' => 'DUMMY EXTERNAL SKU', + 'regular_price' => 10, + ), + $product + ); + } + + /** + * Test getting single product without permission. + * + * @since 3.5.0 + */ + public function test_get_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single product. + * + * @since 3.5.0 + */ + public function test_delete_product() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); + $variations = $response->get_data(); + $this->assertEquals( 0, count( $variations ) ); + } + + /** + * Test deleting a single product without permission. + * + * @since 3.5.0 + */ + public function test_delete_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single product with an invalid ID. + * + * @since 3.5.0 + */ + public function test_delete_product_with_invalid_id() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test editing a single product. Tests multiple product types. + * + * @since 3.5.0 + */ + public function test_update_product() { + wp_set_current_user( $this->user ); + + // test simple products. + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); + $data = $response->get_data(); + $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); + + $this->assertEquals( 'DUMMY SKU', $data['sku'] ); + $this->assertEquals( 10, $data['regular_price'] ); + $this->assertEmpty( $data['sale_price'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU', + 'sale_price' => '8', + 'description' => 'Testing', + 'date_created' => $date_created, + 'images' => array( + array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + ), ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Testing', $data['description'] ); + $this->assertEquals( '8', $data['price'] ); + $this->assertEquals( '8', $data['sale_price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertEquals( 'FIXED-SKU', $data['sku'] ); + $this->assertEquals( $date_created, $data['date_created'] ); + $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); + $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); + $product->delete( true ); + + // test variable product (variations are tested in product-variations.php). + $product = WC_Helper_Product::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); + $data = $response->get_data(); + + foreach ( array( 'small', 'large' ) as $term_name ) { + $this->assertContains( $term_name, $data['attributes'][0]['options'] ); + } + + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'attributes' => array( + array( + 'id' => 0, + 'name' => 'pa_color', + 'options' => array( + 'red', + 'yellow', + ), + 'visible' => false, + 'variation' => 1, + ), + array( + 'id' => 0, + 'name' => 'pa_size', + 'options' => array( + 'small', + ), + 'visible' => false, + 'variation' => 1, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( array( 'small' ), $data['attributes'][0]['options'] ); + + foreach ( array( 'red', 'yellow' ) as $term_name ) { + $this->assertContains( $term_name, $data['attributes'][1]['options'] ); + } + + $product->delete( true ); + + // test external product. + $product = WC_Helper_Product::create_external_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 'Buy external product', $data['button_text'] ); + $this->assertEquals( 'http://woocommerce.com', $data['external_url'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'button_text' => 'Test API Update', + 'external_url' => 'http://automattic.com', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'Test API Update', $data['button_text'] ); + $this->assertEquals( 'http://automattic.com', $data['external_url'] ); + } + + /** + * Test updating a single product without permission. + * + * @since 3.5.0 + */ + public function test_update_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single product with an invalid ID. + * + * @since 3.5.0 + */ + public function test_update_product_with_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-INVALID-ID', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating a single product. + * + * @since 3.5.0 + */ + public function test_create_product() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/products/shipping_classes' ); + $request->set_body_params( + array( + 'name' => 'Test', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $shipping_class_id = $data['id']; + + // Create simple. + $request = new WP_REST_Request( 'POST', '/wc/v4/products' ); + $request->set_body_params( + array( + 'type' => 'simple', + 'name' => 'Test Simple Product', + 'sku' => 'DUMMY SKU SIMPLE API', + 'regular_price' => '10', + 'shipping_class' => 'test', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '10', $data['price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertTrue( $data['purchasable'] ); + $this->assertEquals( 'DUMMY SKU SIMPLE API', $data['sku'] ); + $this->assertEquals( 'Test Simple Product', $data['name'] ); + $this->assertEquals( 'simple', $data['type'] ); + $this->assertEquals( $shipping_class_id, $data['shipping_class_id'] ); + + // Create external. + $request = new WP_REST_Request( 'POST', '/wc/v4/products' ); + $request->set_body_params( + array( + 'type' => 'external', + 'name' => 'Test External Product', + 'sku' => 'DUMMY SKU EXTERNAL API', + 'regular_price' => '10', + 'button_text' => 'Test Button', + 'external_url' => 'https://wordpress.org', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '10', $data['price'] ); + $this->assertEquals( '10', $data['regular_price'] ); + $this->assertFalse( $data['purchasable'] ); + $this->assertEquals( 'DUMMY SKU EXTERNAL API', $data['sku'] ); + $this->assertEquals( 'Test External Product', $data['name'] ); + $this->assertEquals( 'external', $data['type'] ); + $this->assertEquals( 'Test Button', $data['button_text'] ); + $this->assertEquals( 'https://wordpress.org', $data['external_url'] ); + + // Create variable. + $request = new WP_REST_Request( 'POST', '/wc/v4/products' ); + $request->set_body_params( + array( + 'type' => 'variable', + 'name' => 'Test Variable Product', + 'sku' => 'DUMMY SKU VARIABLE API', + 'attributes' => array( + array( + 'id' => 0, + 'name' => 'pa_size', + 'options' => array( + 'small', + 'medium', + ), + 'visible' => false, + 'variation' => 1, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'DUMMY SKU VARIABLE API', $data['sku'] ); + $this->assertEquals( 'Test Variable Product', $data['name'] ); + $this->assertEquals( 'variable', $data['type'] ); + $this->assertEquals( array( 'small', 'medium' ), $data['attributes'][0]['options'] ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); + $products = $response->get_data(); + $this->assertEquals( 3, count( $products ) ); + } + + /** + * Test creating a single product without permission. + * + * @since 3.5.0 + */ + public function test_create_product_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/products' ); + $request->set_body_params( + array( + 'name' => 'Test Product', + 'regular_price' => '12', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch managing products. + * + * @since 3.5.0 + */ + public function test_products_batch() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_2 = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'POST', '/wc/v4/products/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $product->get_id(), + 'description' => 'Updated description.', + ), + ), + 'delete' => array( + $product_2->get_id(), + ), + 'create' => array( + array( + 'sku' => 'DUMMY SKU BATCH TEST 1', + 'regular_price' => '10', + 'name' => 'Test Batch Create 1', + 'type' => 'external', + 'button_text' => 'Test Button', + ), + array( + 'sku' => 'DUMMY SKU BATCH TEST 2', + 'regular_price' => '20', + 'name' => 'Test Batch Create 2', + 'type' => 'simple', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); + $this->assertEquals( 'DUMMY SKU BATCH TEST 1', $data['create'][0]['sku'] ); + $this->assertEquals( 'DUMMY SKU BATCH TEST 2', $data['create'][1]['sku'] ); + $this->assertEquals( 'Test Button', $data['create'][0]['button_text'] ); + $this->assertEquals( 'external', $data['create'][0]['type'] ); + $this->assertEquals( 'simple', $data['create'][1]['type'] ); + $this->assertEquals( $product_2->get_id(), $data['delete'][0]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Tests to make sure you can filter products post statuses by both + * the status query arg and WP_Query. + * + * @since 3.5.0 + */ + public function test_products_filter_post_status() { + wp_set_current_user( $this->user ); + for ( $i = 0; $i < 8; $i++ ) { + $product = WC_Helper_Product::create_simple_product(); + if ( 0 === $i % 2 ) { + wp_update_post( + array( + 'ID' => $product->get_id(), + 'post_status' => 'draft', + ) + ); + } + } + + // Test filtering with status=publish. + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); + $request->set_param( 'status', 'publish' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 4, count( $products ) ); + foreach ( $products as $product ) { + $this->assertEquals( 'publish', $product['status'] ); + } + + // Test filtering with status=draft. + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); + $request->set_param( 'status', 'draft' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 4, count( $products ) ); + foreach ( $products as $product ) { + $this->assertEquals( 'draft', $product['status'] ); + } + + // Test filtering with no filters - which should return 'any' (all 8). + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 8, count( $products ) ); + } + + /** + * Test product category. + * + * @since 3.5.0 + */ + public function test_get_products_by_category() { + wp_set_current_user( $this->user ); + + // Create one product with a category. + $category = wp_insert_term( 'Some Category', 'product_cat' ); + + $product = new WC_Product_Simple(); + $product->set_category_ids( array( $category['term_id'] ) ); + $product->save(); + + // Create one product without category, i.e. Uncategorized. + $product_2 = new WC_Product_Simple(); + $product_2->save(); + + // Test product assigned to a single category. + $query_params = array( + 'category' => (string) $category['term_id'], + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $product->get_id(), $response_product['id'] ); + $this->assertEquals( $product->get_category_ids(), wp_list_pluck( $response_product['categories'], 'id' ) ); + } + + // Test product without categories. + $request = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product_2->get_id() ); + $response = $this->server->dispatch( $request ); + $response_product = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertCount( 1, $response_product['categories'], print_r( $response_product, true ) ); + $this->assertEquals( 'uncategorized', $response_product['categories'][0]['slug'] ); + + } + + /** + * Test getting products by product type. + * + * @since 3.5.0 + */ + public function test_get_products_by_type() { + wp_set_current_user( $this->user ); + + $simple = WC_Helper_Product::create_simple_product(); + $external = WC_Helper_Product::create_external_product(); + $grouped = WC_Helper_Product::create_grouped_product(); + $variable = WC_Helper_Product::create_variation_product(); + + $product_ids_for_type = array( + 'simple' => array( $simple->get_id() ), + 'external' => array( $external->get_id() ), + 'grouped' => array( $grouped->get_id() ), + 'variable' => array( $variable->get_id() ), + ); + + foreach ( $grouped->get_children() as $additional_product ) { + $product_ids_for_type['simple'][] = $additional_product; + } + + foreach ( $product_ids_for_type as $product_type => $product_ids ) { + $query_params = array( + 'type' => $product_type, + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $product_ids ), count( $response_products ) ); + foreach ( $response_products as $response_product ) { + $this->assertContains( $response_product['id'], $product_ids_for_type[ $product_type ], 'REST API: ' . $product_type . ' not found correctly' ); + } + } + } + + /** + * Test getting products by featured property. + * + * @since 3.5.0 + */ + public function test_get_featured_products() { + wp_set_current_user( $this->user ); + + // Create a featured product. + $feat_product = WC_Helper_Product::create_simple_product(); + $feat_product->set_featured( true ); + $feat_product->save(); + + // Create a non-featured product. + $nonfeat_product = WC_Helper_Product::create_simple_product(); + $nonfeat_product->save(); + + $query_params = array( + 'featured' => 'true', + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $feat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' ); + } + + $query_params = array( + 'featured' => 'false', + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $nonfeat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' ); + } + } + + /** + * Test getting products by shipping class property. + * + * @since 3.5.0 + */ + public function test_get_products_by_shipping_class() { + wp_set_current_user( $this->user ); + + $shipping_class_1 = wp_insert_term( 'Bulky', 'product_shipping_class' ); + + $product_1 = new WC_Product_Simple(); + $product_1->set_shipping_class_id( $shipping_class_1['term_id'] ); + $product_1->save(); + + $query_params = array( + 'shipping_class' => (string) $shipping_class_1['term_id'], + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $product_1->get_id(), $response_product['id'] ); + } + } + + /** + * Test getting products by tag. + * + * @since 3.5.0 + */ + public function test_get_products_by_tag() { + wp_set_current_user( $this->user ); + + $test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' ); + + // Product with a tag. + $product = WC_Helper_Product::create_simple_product(); + $product->set_tag_ids( array( $test_tag_1['term_id'] ) ); + $product->save(); + + // Product without a tag. + $product_2 = WC_Helper_Product::create_simple_product(); + + $query_params = array( + 'tag' => (string) $test_tag_1['term_id'], + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + foreach ( $response_products as $response_product ) { + $this->assertEquals( $product->get_id(), $response_product['id'] ); + } + } + + /** + * Test getting products by global attribute. + * + * @since 3.5.0 + */ + public function test_get_products_by_attribute() { + global $wpdb; + wp_set_current_user( $this->user ); + + // Variable product with 2 different variations. + $variable_product = WC_Helper_Product::create_variation_product(); + + // Terms created by variable product. + $term_large = get_term_by( 'slug', 'large', 'pa_size' ); + $term_small = get_term_by( 'slug', 'small', 'pa_size' ); + + // Simple product without attribute. + $product_1 = WC_Helper_Product::create_simple_product(); + + // Simple product with attribute size = large. + $product_2 = WC_Helper_Product::create_simple_product(); + $product_2->set_attributes( array( 'pa_size' => 'large' ) ); + $product_2->save(); + + // Link the product to the term. + $wpdb->insert( + $wpdb->prefix . 'term_relationships', + array( + 'object_id' => $product_2->get_id(), + 'term_taxonomy_id' => $term_large->term_id, + 'term_order' => 0, + ) + ); + + // Products with attribute size == large. + $expected_product_ids = array( + $variable_product->get_id(), + $product_2->get_id(), + ); + $query_params = array( + 'attribute' => 'pa_size', + 'attribute_term' => (string) $term_large->term_id, + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $expected_product_ids ), count( $response_products ) ); + foreach ( $response_products as $response_product ) { + $this->assertContains( $response_product['id'], $expected_product_ids ); + } + + // Products with attribute size == small. + $expected_product_ids = array( + $variable_product->get_id(), + ); + $query_params = array( + 'attribute' => 'pa_size', + 'attribute_term' => (string) $term_small->term_id, + ); + $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $response_products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $expected_product_ids ), count( $response_products ) ); + foreach ( $response_products as $response_product ) { + $this->assertContains( $response_product['id'], $expected_product_ids ); + } } /** From 191eb4865ba995183742143fe00a7ccc1b53a1d6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 12:36:11 +0100 Subject: [PATCH 060/440] Namespaced v3 tests to v4 --- phpunit.xml.dist | 4 +- src/RestApi/Version4/Controllers.php | 6 - .../Controllers/Onboarding/Levels.php | 269 ----- .../Controllers/Onboarding/Plugins.php | 293 ------ .../Controllers/Onboarding/Profile.php | 353 ------- .../Version4/Onboarding/onboarding-levels.php | 107 -- .../Onboarding/onboarding-profile.php | 150 --- tests/Version4/Reports/reports-interval.php | 925 ------------------ tests/bootstrap.php | 70 -- {tests => unit-tests}/AbstractRestApiTest.php | 2 +- unit-tests/Bootstrap.php | 92 ++ unit-tests/Helpers/AdminNotesHelper.php | 83 ++ unit-tests/Helpers/CouponHelper.php | 147 +++ unit-tests/Helpers/CustomerHelper.php | 138 +++ unit-tests/Helpers/OrderHelper.php | 129 +++ unit-tests/Helpers/ProductHelper.php | 306 ++++++ unit-tests/Helpers/QueueHelper.php | 62 ++ unit-tests/Helpers/ReportsHelper.php | 27 + unit-tests/Helpers/SettingsHelper.php | 82 ++ unit-tests/Helpers/ShippingHelper.php | 50 + .../Blocks/products-attributes-terms.php | 4 +- .../Tests}/Blocks/products-attributes.php | 4 +- .../Tests}/Blocks/products-categories.php | 4 +- .../Tests}/Blocks/products.php | 28 +- .../Tests}/Version2/coupons.php | 24 +- .../Tests}/Version2/customers.php | 24 +- .../Tests}/Version2/orders.php | 42 +- .../Tests}/Version2/payment-gateways.php | 0 .../Tests}/Version2/product-reviews.php | 54 +- .../Tests}/Version2/product-variations.php | 30 +- .../Tests}/Version2/products.php | 32 +- .../Tests}/Version2/settings.php | 6 +- .../Tests}/Version2/shipping-methods.php | 0 .../Tests}/Version2/shipping-zones.php | 0 .../Tests}/Version2/system-status.php | 0 .../Tests}/Version3/coupons.php | 24 +- .../Tests}/Version3/customers.php | 26 +- .../Tests}/Version3/functions.php | 0 .../Tests}/Version3/orders.php | 44 +- .../Tests}/Version3/payment-gateways.php | 0 .../Tests}/Version3/product-reviews.php | 54 +- .../Tests}/Version3/product-variations.php | 30 +- .../Tests}/Version3/products.php | 52 +- .../Version3/reports-coupons-totals.php | 2 +- .../Version3/reports-customers-totals.php | 2 +- .../Tests}/Version3/reports-orders-totals.php | 2 +- .../Version3/reports-products-totals.php | 2 +- .../Version3/reports-reviews-totals.php | 2 +- .../Tests}/Version3/settings.php | 6 +- .../Tests}/Version3/shipping-methods.php | 0 .../Tests}/Version3/shipping-zones.php | 0 .../Tests}/Version3/system-status.php | 0 .../Tests/Version4/AdminNotes.php | 15 +- .../Tests}/Version4/Coupons.php | 30 +- unit-tests/Tests/Version4/Customers.php | 640 ++++++++++++ .../Tests/Version4/Data.php | 12 +- unit-tests/Tests/Version4/Functions.php | 257 +++++ .../Tests/Version4/Leaderboards.php | 8 +- .../Tests}/Version4/Orders.php | 53 +- unit-tests/Tests/Version4/PaymentGateways.php | 352 +++++++ .../Tests}/Version4/ProductReviews.php | 47 +- .../Tests/Version4/ProductVariations.php | 480 +++++++++ .../Tests/Version4/Products.php | 146 ++- .../Tests/Version4/Reports/Categories.php | 26 +- .../Tests/Version4/Reports/Coupons.php | 39 +- .../Tests/Version4/Reports/CouponsStats.php | 29 +- .../Tests/Version4/Reports/CustomerStats.php | 27 +- .../Tests/Version4/Reports/Customers.php | 39 +- .../Tests/Version4/Reports/DownloadStats.php | 64 +- .../Tests/Version4/Reports/Downloads.php | 50 +- .../Tests/Version4/Reports/Import.php | 69 +- .../Tests/Version4/Reports/OrderStats.php | 13 +- .../Tests/Version4/Reports/Orders.php | 20 +- .../Reports/PerformanceIndicators.php | 32 +- .../Tests/Version4/Reports/ProductStats.php | 22 +- .../Tests/Version4/Reports/Products.php | 29 +- .../Tests/Version4/Reports/RevenueStats.php | 11 +- .../Tests/Version4/Reports/Stock.php | 21 +- .../Tests/Version4/Reports/StockStats.php | 22 +- .../Tests/Version4/Reports/TaxStats.php | 22 +- .../Tests/Version4/Reports/Taxes.php | 37 +- .../Tests/Version4/Reports/Variations.php | 34 +- unit-tests/Tests/Version4/Settings.php | 901 +++++++++++++++++ unit-tests/Tests/Version4/ShippingMethods.php | 149 +++ unit-tests/Tests/Version4/ShippingZones.php | 831 ++++++++++++++++ unit-tests/Tests/Version4/SystemStatus.php | 473 +++++++++ 86 files changed, 6016 insertions(+), 2777 deletions(-) delete mode 100644 src/RestApi/Version4/Controllers/Onboarding/Levels.php delete mode 100644 src/RestApi/Version4/Controllers/Onboarding/Plugins.php delete mode 100644 src/RestApi/Version4/Controllers/Onboarding/Profile.php delete mode 100644 tests/Version4/Onboarding/onboarding-levels.php delete mode 100644 tests/Version4/Onboarding/onboarding-profile.php delete mode 100644 tests/Version4/Reports/reports-interval.php delete mode 100755 tests/bootstrap.php rename {tests => unit-tests}/AbstractRestApiTest.php (99%) create mode 100755 unit-tests/Bootstrap.php create mode 100644 unit-tests/Helpers/AdminNotesHelper.php create mode 100644 unit-tests/Helpers/CouponHelper.php create mode 100644 unit-tests/Helpers/CustomerHelper.php create mode 100644 unit-tests/Helpers/OrderHelper.php create mode 100644 unit-tests/Helpers/ProductHelper.php create mode 100644 unit-tests/Helpers/QueueHelper.php create mode 100644 unit-tests/Helpers/ReportsHelper.php create mode 100644 unit-tests/Helpers/SettingsHelper.php create mode 100644 unit-tests/Helpers/ShippingHelper.php rename {tests => unit-tests/Tests}/Blocks/products-attributes-terms.php (92%) rename {tests => unit-tests/Tests}/Blocks/products-attributes.php (92%) rename {tests => unit-tests/Tests}/Blocks/products-categories.php (95%) rename {tests => unit-tests/Tests}/Blocks/products.php (90%) rename {tests => unit-tests/Tests}/Version2/coupons.php (92%) rename {tests => unit-tests/Tests}/Version2/customers.php (90%) rename {tests => unit-tests/Tests}/Version2/orders.php (91%) rename {tests => unit-tests/Tests}/Version2/payment-gateways.php (100%) rename {tests => unit-tests/Tests}/Version2/product-reviews.php (81%) rename {tests => unit-tests/Tests}/Version2/product-variations.php (91%) rename {tests => unit-tests/Tests}/Version2/products.php (91%) rename {tests => unit-tests/Tests}/Version2/settings.php (99%) rename {tests => unit-tests/Tests}/Version2/shipping-methods.php (100%) rename {tests => unit-tests/Tests}/Version2/shipping-zones.php (100%) rename {tests => unit-tests/Tests}/Version2/system-status.php (100%) rename {tests => unit-tests/Tests}/Version3/coupons.php (92%) rename {tests => unit-tests/Tests}/Version3/customers.php (90%) rename {tests => unit-tests/Tests}/Version3/functions.php (100%) rename {tests => unit-tests/Tests}/Version3/orders.php (90%) rename {tests => unit-tests/Tests}/Version3/payment-gateways.php (100%) rename {tests => unit-tests/Tests}/Version3/product-reviews.php (81%) rename {tests => unit-tests/Tests}/Version3/product-variations.php (91%) rename {tests => unit-tests/Tests}/Version3/products.php (90%) rename {tests => unit-tests/Tests}/Version3/reports-coupons-totals.php (96%) rename {tests => unit-tests/Tests}/Version3/reports-customers-totals.php (96%) rename {tests => unit-tests/Tests}/Version3/reports-orders-totals.php (96%) rename {tests => unit-tests/Tests}/Version3/reports-products-totals.php (96%) rename {tests => unit-tests/Tests}/Version3/reports-reviews-totals.php (96%) rename {tests => unit-tests/Tests}/Version3/settings.php (99%) rename {tests => unit-tests/Tests}/Version3/shipping-methods.php (100%) rename {tests => unit-tests/Tests}/Version3/shipping-zones.php (100%) rename {tests => unit-tests/Tests}/Version3/system-status.php (100%) rename tests/Version4/admin-notes.php => unit-tests/Tests/Version4/AdminNotes.php (96%) rename {tests => unit-tests/Tests}/Version4/Coupons.php (86%) create mode 100644 unit-tests/Tests/Version4/Customers.php rename tests/Version4/data.php => unit-tests/Tests/Version4/Data.php (90%) create mode 100644 unit-tests/Tests/Version4/Functions.php rename tests/Version4/leaderboards.php => unit-tests/Tests/Version4/Leaderboards.php (96%) rename {tests => unit-tests/Tests}/Version4/Orders.php (92%) create mode 100644 unit-tests/Tests/Version4/PaymentGateways.php rename {tests => unit-tests/Tests}/Version4/ProductReviews.php (86%) create mode 100644 unit-tests/Tests/Version4/ProductVariations.php rename tests/Version4/products.php => unit-tests/Tests/Version4/Products.php (86%) rename tests/Version4/Reports/reports-categories.php => unit-tests/Tests/Version4/Reports/Categories.php (88%) rename tests/Version4/Reports/reports-coupons.php => unit-tests/Tests/Version4/Reports/Coupons.php (82%) rename tests/Version4/Reports/reports-coupons-stats.php => unit-tests/Tests/Version4/Reports/CouponsStats.php (85%) rename tests/Version4/Reports/reports-customers-stats.php => unit-tests/Tests/Version4/Reports/CustomerStats.php (82%) rename tests/Version4/Reports/reports-customers.php => unit-tests/Tests/Version4/Reports/Customers.php (87%) rename tests/Version4/Reports/reports-downloads-stats.php => unit-tests/Tests/Version4/Reports/DownloadStats.php (87%) rename tests/Version4/Reports/reports-downloads.php => unit-tests/Tests/Version4/Reports/Downloads.php (91%) rename tests/Version4/Reports/reports-import.php => unit-tests/Tests/Version4/Reports/Import.php (88%) rename tests/Version4/Reports/reports-orders-stats.php => unit-tests/Tests/Version4/Reports/OrderStats.php (94%) rename tests/Version4/Reports/reports-orders.php => unit-tests/Tests/Version4/Reports/Orders.php (84%) rename tests/Version4/Reports/reports-performance-indicators.php => unit-tests/Tests/Version4/Reports/PerformanceIndicators.php (86%) rename tests/Version4/Reports/reports-products-stats.php => unit-tests/Tests/Version4/Reports/ProductStats.php (88%) rename tests/Version4/Reports/reports-products.php => unit-tests/Tests/Version4/Reports/Products.php (86%) rename tests/Version4/Reports/reports-revenue-stats.php => unit-tests/Tests/Version4/Reports/RevenueStats.php (94%) rename tests/Version4/Reports/reports-stock.php => unit-tests/Tests/Version4/Reports/Stock.php (87%) rename tests/Version4/Reports/reports-stock-stats.php => unit-tests/Tests/Version4/Reports/StockStats.php (89%) rename tests/Version4/Reports/reports-taxes-stats.php => unit-tests/Tests/Version4/Reports/TaxStats.php (89%) rename tests/Version4/Reports/reports-taxes.php => unit-tests/Tests/Version4/Reports/Taxes.php (91%) rename tests/Version4/Reports/reports-variations.php => unit-tests/Tests/Version4/Reports/Variations.php (86%) create mode 100644 unit-tests/Tests/Version4/Settings.php create mode 100644 unit-tests/Tests/Version4/ShippingMethods.php create mode 100644 unit-tests/Tests/Version4/ShippingZones.php create mode 100644 unit-tests/Tests/Version4/SystemStatus.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index dfa2605c311..9119520176d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,6 @@ - ./tests/ + ./unit-tests/Tests diff --git a/src/RestApi/Version4/Controllers.php b/src/RestApi/Version4/Controllers.php index 3372afec08b..727c311f70c 100644 --- a/src/RestApi/Version4/Controllers.php +++ b/src/RestApi/Version4/Controllers.php @@ -56,12 +56,6 @@ class Controllers { 'webhooks' => __NAMESPACE__ . '\Controllers\Webhooks', ]; - if ( class_exists( 'WC_Admin_Onboarding' ) ) { - $controllers['onboarding-levels'] = __NAMESPACE__ . '\Controllers\Onboarding\Levels'; - $controllers['onboarding-plugins'] = __NAMESPACE__ . '\Controllers\Onboarding\Plugins'; - $controllers['onboarding-profile'] = __NAMESPACE__ . '\Controllers\Onboarding\Profile'; - } - if ( class_exists( 'WC_Admin_Reports_Sync' ) ) { $controllers['reports-categories'] = __NAMESPACE__ . '\Controllers\Reports\Categories'; $controllers['reports-coupons'] = __NAMESPACE__ . '\Controllers\Reports\Coupons'; diff --git a/src/RestApi/Version4/Controllers/Onboarding/Levels.php b/src/RestApi/Version4/Controllers/Onboarding/Levels.php deleted file mode 100644 index 6f25493294a..00000000000 --- a/src/RestApi/Version4/Controllers/Onboarding/Levels.php +++ /dev/null @@ -1,269 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get an array of all levels and child tasks. - * - * @todo Status values below should pull from the database task status once implemented. - */ - public function get_levels() { - $levels = array( - 'account' => array( - 'tasks' => array( - 'create_account' => array( - 'label' => __( 'Create an account', 'woocommerce' ), - 'description' => __( 'Speed up & secure your store', 'woocommerce' ), - 'illustration' => '', - 'status' => 'visible', - 'is_required' => false, - ), - ), - ), - 'storefront' => array( - 'tasks' => array( - 'add_products' => array( - 'label' => __( 'Add your products', 'woocommerce' ), - 'description' => __( 'Bring your store to life', 'woocommerce' ), - 'illustration' => '', - 'status' => 'visible', - 'is_required' => true, - ), - 'customize_appearance' => array( - 'label' => __( 'Customize Appearance', 'woocommerce' ), - 'description' => __( 'Ensure your store is on-brand', 'woocommerce' ), - 'illustration' => '', - 'status' => 'visible', - 'is_required' => false, - ), - ), - ), - 'checkout' => array( - 'id' => 'checkout', - 'tasks' => array( - 'configure_shipping' => array( - 'label' => __( 'Configure shipping', 'woocommerce' ), - 'description' => __( 'Set up prices and destinations', 'woocommerce' ), - 'illustration' => '', - 'status' => 'visible', - 'is_required' => true, - ), - 'configure_taxes' => array( - 'label' => __( 'Configure taxes', 'woocommerce' ), - 'description' => __( 'Set up sales tax rates', 'woocommerce' ), - 'illustration' => '', - 'status' => 'visible', - 'is_required' => false, - ), - 'configure_payments' => array( - 'label' => __( 'Configure payments', 'woocommerce' ), - 'description' => __( 'Choose payment providers', 'woocommerce' ), - 'illustration' => '', - 'status' => 'visible', - 'is_required' => true, - ), - ), - ), - ); - - return apply_filters( 'woocommerce_onboarding_levels', $levels ); - } - - /** - * Return all level items and child tasks. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - global $wpdb; - - $levels = $this->get_levels(); - $data = array(); - - if ( ! empty( $levels ) ) { - foreach ( $levels as $id => $level ) { - $level = $this->convert_to_non_associative( $level, $id ); - $response = $this->prepare_item_for_response( $level, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - } - - return rest_ensure_response( $data ); - } - - /** - * 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 ); - - $response->add_links( $this->prepare_links( $item ) ); - - /** - * 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_onboarding_level', $response, $item, $request ); - } - - /** - * Convert the associative levels and tasks to non-associative for JSON use. - * - * @param array $item Level. - * @param string $id Level ID. - * @return array - */ - public function convert_to_non_associative( $item, $id ) { - $item = array( 'id' => $id ) + $item; - - $tasks = array(); - foreach ( $item['tasks'] as $key => $task ) { - $tasks[] = array( 'id' => $key ) + $task; - } - $item['tasks'] = $tasks; - - return $item; - } - - /** - * Prepare links for the request. - * - * @param object $item Data object. - * @return array Links for the given object. - * @todo Check to make sure this generates a valid URL after #1897. - */ - protected function prepare_links( $item ) { - $links = array( - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/onboarding/tasks?level=%s', $this->namespace, $item['id'] ) ), - ), - ); - return $links; - } - - /** - * 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' => 'onboarding_level', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'type' => 'string', - 'description' => __( 'Level ID.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'tasks' => array( - 'type' => 'array', - 'description' => __( 'Array of tasks under the level.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Task ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'Task label.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Task description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'illustration' => array( - 'description' => __( 'URL for illustration used.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Task status.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'enum' => array( 'visible', 'hidden', 'in-progress', 'skipped', 'completed' ), - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Version4/Controllers/Onboarding/Plugins.php b/src/RestApi/Version4/Controllers/Onboarding/Plugins.php deleted file mode 100644 index 90d864bdb1e..00000000000 --- a/src/RestApi/Version4/Controllers/Onboarding/Plugins.php +++ /dev/null @@ -1,293 +0,0 @@ -namespace, - '/' . $this->rest_base . '/install', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'install_plugin' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - ), - 'schema' => array( $this, 'get_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/activate', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'activate_plugin' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - ), - 'schema' => array( $this, 'get_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/connect-jetpack', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'connect_jetpack' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - ), - 'schema' => array( $this, 'get_connect_schema' ), - ) - ); - } - - /** - * Check if a given request has access to manage plugins. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - if ( ! current_user_can( 'install_plugins' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot manage plugins.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Get an array of plugins that can be installed & activated via the endpoints. - */ - public function get_allowed_plugins() { - return apply_filters( - 'woocommerce_onboarding_plugins_whitelist', - array( - 'jetpack' => 'jetpack/jetpack.php', - 'woocommerce-services' => 'woocommerce-services/woocommerce-services.php', - ) - ); - } - - /** - * Installs the requested plugin. - * - * @param \WP_REST_Request $request Full details about the request. - * @return array Plugin Status - */ - public function install_plugin( $request ) { - $allowed_plugins = $this->get_allowed_plugins(); - $plugin = sanitize_title_with_dashes( $request['plugin'] ); - if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); - } - - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $slug = $plugin; - $path = $allowed_plugins[ $slug ]; - $installed_plugins = get_plugins(); - - if ( in_array( $path, array_keys( $installed_plugins ), true ) ) { - return( array( - 'slug' => $slug, - 'name' => $installed_plugins[ $path ]['Name'], - 'status' => 'success', - ) ); - } - - include_once ABSPATH . '/wp-admin/includes/admin.php'; - include_once ABSPATH . '/wp-admin/includes/plugin-install.php'; - include_once ABSPATH . '/wp-admin/includes/plugin.php'; - include_once ABSPATH . '/wp-admin/includes/class-wp-upgrader.php'; - include_once ABSPATH . '/wp-admin/includes/class-plugin-upgrader.php'; - - $api = plugins_api( - 'plugin_information', - array( - 'slug' => sanitize_key( $slug ), - 'fields' => array( - 'sections' => false, - ), - ) - ); - - if ( is_wp_error( $api ) ) { - return new \WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce' ), 500 ); - } - - $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); - $result = $upgrader->install( $api->download_link ); - - if ( is_wp_error( $result ) || is_null( $result ) ) { - return new \WP_Error( 'woocommerce_rest_plugin_install', __( 'The requested plugin could not be installed.', 'woocommerce' ), 500 ); - } - - return array( - 'slug' => $slug, - 'name' => $api->name, - 'status' => 'success', - ); - } - - /** - * Activate the requested plugin. - * - * @param \WP_REST_Request $request Full details about the request. - * @return array Plugin Status - */ - public function activate_plugin( $request ) { - $allowed_plugins = $this->get_allowed_plugins(); - $plugin = sanitize_title_with_dashes( $request['plugin'] ); - if ( ! in_array( $plugin, array_keys( $allowed_plugins ), true ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); - } - - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $slug = $plugin; - $path = $allowed_plugins[ $slug ]; - $installed_plugins = get_plugins(); - - if ( ! in_array( $path, array_keys( $installed_plugins ), true ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'Invalid plugin.', 'woocommerce' ), 404 ); - } - - $result = activate_plugin( $path ); - if ( ! is_null( $result ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_plugin', __( 'The requested plugin could not be activated.', 'woocommerce' ), 500 ); - } - - return( array( - 'slug' => $slug, - 'name' => $installed_plugins[ $path ]['Name'], - 'status' => 'success', - ) ); - } - - /** - * Generates a Jetpack Connect URL. - * - * @return array Connection URL for Jetpack - */ - public function connect_jetpack() { - if ( ! class_exists( 'Jetpack' ) ) { - return new \WP_Error( 'woocommerce_rest_jetpack_not_active', __( 'Jetpack is not installed or active.', 'woocommerce' ), 404 ); - } - - $next_step_slug = apply_filters( 'woocommerce_onboarding_after_jetpack_step', 'store-details' ); - $redirect_url = esc_url_raw( - add_query_arg( - array( - 'page' => 'wc-admin', - ), - admin_url( 'admin.php' ) - ) . '#/?step=' . $next_step_slug - ); - - $connect_url = Jetpack::init()->build_connect_url( true, $redirect_url, 'woocommerce-setup-wizard' ); - - // Redirect to local calypso instead of production. - if ( defined( 'WOOCOMMERCE_CALYPSO_LOCAL' ) && WOOCOMMERCE_CALYPSO_LOCAL ) { - $connect_url = add_query_arg( - array( - 'calypso_env' => 'development', - ), - $connect_url - ); - } - - return( array( - 'slug' => $slug, - 'name' => __( 'Jetpack', 'woocommerce' ), - 'connectAction' => $connect_url, - ) ); - } - - /** - * 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' => 'onboarding_plugin', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'Plugin slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Plugin name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Plugin status.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the schema, conforming to JSON Schema. - * - * @return array - */ - public function get_connect_schema() { - $schema = $this->get_item_schema(); - unset( $schema['properties']['status'] ); - $schema['properties']['connectAction'] = array( - 'description' => __( 'Action that should be completed to connect Jetpack.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ); - return $schema; - } -} diff --git a/src/RestApi/Version4/Controllers/Onboarding/Profile.php b/src/RestApi/Version4/Controllers/Onboarding/Profile.php deleted file mode 100644 index abbfb7452bd..00000000000 --- a/src/RestApi/Version4/Controllers/Onboarding/Profile.php +++ /dev/null @@ -1,353 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_items' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check whether a given request has permission to read onboarding profile data. - * - * @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( 'settings', '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 edit onboarding profile data. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Return all onboarding profile data. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $onboarding_data = get_option( 'wc_onboarding_profile', array() ); - $item_schema = $this->get_item_schema(); - - $items = array(); - foreach ( $item_schema['properties'] as $key => $property_schema ) { - $items[ $key ] = isset( $onboarding_data[ $key ] ) ? $onboarding_data[ $key ] : null; - } - - $item = $this->prepare_item_for_response( $items, $request ); - $data = $this->prepare_response_for_collection( $item ); - - return rest_ensure_response( $data ); - } - - /** - * Update onboarding profile data. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response - */ - public function update_items( $request ) { - $params = $request->get_json_params(); - $query_args = $this->prepare_objects_query( $params ); - $onboarding_data = get_option( 'wc_onboarding_profile', array() ); - update_option( 'wc_onboarding_profile', array_merge( $onboarding_data, $query_args ) ); - - $result = array( - 'status' => 'success', - 'message' => __( 'Onboarding profile data has been updated.', 'woocommerce' ), - ); - - $response = $this->prepare_item_for_response( $result, $request ); - $data = $this->prepare_response_for_collection( $response ); - - return rest_ensure_response( $data ); - } - - /** - * Prepare objects query. - * - * @param array $params The params sent in the request. - * @return array - */ - protected function prepare_objects_query( $params ) { - $args = array(); - $properties = self::get_profile_properties(); - - foreach ( $properties as $key => $property ) { - if ( isset( $params[ $key ] ) ) { - $args[ $key ] = $params[ $key ]; - } - } - - /** - * 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 array $params The params sent in the request. - */ - $args = apply_filters( 'woocommerce_rest_onboarding_profile_object_query', $args, $params ); - - 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_onboarding_profile', $response, $item, $request ); - } - - /** - * Get onboarding profile properties. - * - * @return array - */ - public static function get_profile_properties() { - $properties = array( - 'completed' => array( - 'type' => 'boolean', - 'description' => __( 'Whether or not the profile was completed.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'validate_callback' => 'rest_validate_request_arg', - ), - 'skipped' => array( - 'type' => 'boolean', - 'description' => __( 'Whether or not the profile was skipped.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'validate_callback' => 'rest_validate_request_arg', - ), - 'account_type' => array( - 'type' => 'string', - 'description' => __( 'Account type used for Jetpack.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'validate_callback' => 'rest_validate_request_arg', - 'enum' => array( - 'new', - 'existing', - 'google', - ), - ), - 'industry' => array( - 'type' => 'array', - 'description' => __( 'Industry.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => array_keys( \WC_Admin_Onboarding::get_allowed_industries() ), - 'type' => 'string', - ), - ), - 'product_types' => array( - 'type' => 'array', - 'description' => __( 'Types of products sold.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'sanitize_callback' => 'wp_parse_slug_list', - 'validate_callback' => 'rest_validate_request_arg', - 'items' => array( - 'enum' => array_keys( \WC_Admin_Onboarding::get_allowed_product_types() ), - 'type' => 'string', - ), - ), - 'product_count' => array( - 'type' => 'string', - 'description' => __( 'Number of products to be added.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'validate_callback' => 'rest_validate_request_arg', - 'enum' => array( - '1-10', - '11-100', - '101-1000', - '1000+', - ), - ), - 'selling_venues' => array( - 'type' => 'string', - 'description' => __( 'Other places the store is selling products.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'validate_callback' => 'rest_validate_request_arg', - 'enum' => array( - 'no', - 'other', - 'brick-mortar', - 'brick-mortar-other', - ), - ), - 'other_platform' => array( - 'type' => 'string', - 'description' => __( 'Name of other platform used to sell.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'validate_callback' => 'rest_validate_request_arg', - 'enum' => array( - 'shopify', - 'bigcommerce', - 'magento', - 'wix', - 'other', - ), - ), - 'theme' => array( - 'type' => 'string', - 'description' => __( 'Selected store theme.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'sanitize_callback' => 'sanitize_title_with_dashes', - 'validate_callback' => 'rest_validate_request_arg', - ), - 'items_purchased' => array( - 'type' => 'boolean', - 'description' => __( 'Whether or not the user opted to purchase items now or later.', 'woocommerce' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'validate_callback' => 'rest_validate_request_arg', - ), - ); - - return apply_filters( 'woocommerce_onboarding_profile_properties', $properties ); - } - - /** - * Get the schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - // Unset properties used for collection params. - $properties = self::get_profile_properties(); - foreach ( $properties as $key => $property ) { - unset( $properties[ $key ]['default'] ); - unset( $properties[ $key ]['items'] ); - unset( $properties[ $key ]['validate_callback'] ); - unset( $properties[ $key ]['sanitize_callback'] ); - } - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'onboarding_profile', - 'type' => 'object', - 'properties' => $properties, - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - // Unset properties used for item schema. - $params = self::get_profile_properties(); - foreach ( $params as $key => $param ) { - unset( $params[ $key ]['context'] ); - unset( $params[ $key ]['readonly'] ); - } - - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - - return apply_filters( 'rest_onboarding_profile_collection_params', $params ); - } -} diff --git a/tests/Version4/Onboarding/onboarding-levels.php b/tests/Version4/Onboarding/onboarding-levels.php deleted file mode 100644 index e7c52b05e22..00000000000 --- a/tests/Version4/Onboarding/onboarding-levels.php +++ /dev/null @@ -1,107 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test that levels are returned by the endpoint. - */ - public function test_get_level_items() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'account', $data[0]['id'] ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_schema() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertCount( 2, $properties ); - $this->assert_item_schema( $properties ); - } - - /** - * Asserts the item schema is correct. - * - * @param array $schema Item to check schema. - */ - public function assert_item_schema( $schema ) { - $this->assertArrayHasKey( 'id', $schema ); - $this->assertArrayHasKey( 'tasks', $schema ); - - $task_properties = $schema['tasks']['items']['properties']; - $this->assertCount( 5, $task_properties ); - $this->assertArrayHasKey( 'id', $task_properties ); - $this->assertArrayHasKey( 'label', $task_properties ); - $this->assertArrayHasKey( 'description', $task_properties ); - $this->assertArrayHasKey( 'illustration', $task_properties ); - $this->assertArrayHasKey( 'status', $task_properties ); - } - - /** - * Test that levels response changes based on applied filters. - */ - public function test_filter_levels() { - wp_set_current_user( $this->user ); - - add_filter( - 'woocommerce_onboarding_levels', - function( $levels ) { - $levels['test_level'] = array( - 'id' => 'test_level', - 'tasks' => array(), - ); - return $levels; - } - ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'test_level', end( $data )['id'] ); - - } -} diff --git a/tests/Version4/Onboarding/onboarding-profile.php b/tests/Version4/Onboarding/onboarding-profile.php deleted file mode 100644 index 5338f51c015..00000000000 --- a/tests/Version4/Onboarding/onboarding-profile.php +++ /dev/null @@ -1,150 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test that profile data is returned by the endpoint. - */ - public function test_get_profile_items() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $properties = WC_Admin_REST_Onboarding_Profile_Controller::get_profile_properties(); - foreach ( $properties as $key => $property ) { - $this->assertArrayHasKey( $key, $properties ); - } - } - - /** - * Test that profile date is updated by the endpoint. - */ - public function test_update_profile_items() { - wp_set_current_user( $this->user ); - - // Test updating 2 fields separately. - $request = new WP_REST_Request( 'POST', $this->endpoint ); - $request->set_headers( array( 'content-type' => 'application/json' ) ); - $request->set_body( wp_json_encode( array( 'industry' => 'health-beauty' ) ) ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'success', $data['status'] ); - - // Test that the update works. - $request = new WP_REST_Request( 'POST', $this->endpoint ); - $request->set_headers( array( 'content-type' => 'application/json' ) ); - $request->set_body( wp_json_encode( array( 'theme' => 'Storefront' ) ) ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'success', $data['status'] ); - - // Make sure the original field value wasn't overwritten. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'health-beauty', $data['industry'][0] ); - $this->assertEquals( 'storefront', $data['theme'] ); - } - - /** - * Test schema. - * - * @since 3.5.0 - */ - public function test_schema() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertCount( 10, $properties ); - $this->assertArrayHasKey( 'completed', $properties ); - $this->assertArrayHasKey( 'skipped', $properties ); - $this->assertArrayHasKey( 'account_type', $properties ); - $this->assertArrayHasKey( 'industry', $properties ); - $this->assertArrayHasKey( 'product_types', $properties ); - $this->assertArrayHasKey( 'product_count', $properties ); - $this->assertArrayHasKey( 'selling_venues', $properties ); - $this->assertArrayHasKey( 'other_platform', $properties ); - $this->assertArrayHasKey( 'theme', $properties ); - $this->assertArrayHasKey( 'items_purchased', $properties ); - } - - /** - * Test that profiles response changes based on applied filters. - */ - public function test_profile_extensibility() { - wp_set_current_user( $this->user ); - - add_filter( - 'woocommerce_onboarding_profile_properties', - function( $properties ) { - $properties['test_profile_datum'] = array( - 'type' => 'array', - 'description' => __( 'Test onboarding profile extensibility.', 'woocommerce-admin' ), - 'context' => array( 'view' ), - 'readonly' => true, - ); - return $properties; - } - ); - - // Test that the update works. - $request = new WP_REST_Request( 'POST', $this->endpoint ); - $request->set_headers( array( 'content-type' => 'application/json' ) ); - $request->set_body( wp_json_encode( array( 'test_profile_datum' => 'woo' ) ) ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'success', $data['status'] ); - - // Test that the new field is retrieved. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'woo', $data['test_profile_datum'] ); - } -} diff --git a/tests/Version4/Reports/reports-interval.php b/tests/Version4/Reports/reports-interval.php deleted file mode 100644 index 2b08f2b6855..00000000000 --- a/tests/Version4/Reports/reports-interval.php +++ /dev/null @@ -1,925 +0,0 @@ -assertEquals( 4, WC_Admin_Reports_Interval::quarter( $datetime ) ); - - $datetime = new DateTime( '2018-01-01T00:00:00', self::$local_tz ); - $this->assertEquals( 1, WC_Admin_Reports_Interval::quarter( $datetime ) ); - - $datetime = new DateTime( '2018-03-31T23:59:59', self::$local_tz ); - $this->assertEquals( 1, WC_Admin_Reports_Interval::quarter( $datetime ) ); - - $datetime = new DateTime( '2018-04-01T00:00:00', self::$local_tz ); - $this->assertEquals( 2, WC_Admin_Reports_Interval::quarter( $datetime ) ); - - $datetime = new DateTime( '2018-06-30T23:59:59', self::$local_tz ); - $this->assertEquals( 2, WC_Admin_Reports_Interval::quarter( $datetime ) ); - - $datetime = new DateTime( '2018-07-01T00:00:00', self::$local_tz ); - $this->assertEquals( 3, WC_Admin_Reports_Interval::quarter( $datetime ) ); - - $datetime = new DateTime( '2018-09-30T23:59:59', self::$local_tz ); - $this->assertEquals( 3, WC_Admin_Reports_Interval::quarter( $datetime ) ); - - $datetime = new DateTime( '2018-10-01T00:00:00', self::$local_tz ); - $this->assertEquals( 4, WC_Admin_Reports_Interval::quarter( $datetime ) ); - - $datetime = new DateTime( '2018-12-31T23:59:59', self::$local_tz ); - $this->assertEquals( 4, WC_Admin_Reports_Interval::quarter( $datetime ) ); - } - - /** - * Test simple week number function. - */ - public function test_simple_week_number() { - $expected_week_no = array( - '2010-12-24' => array( - 1 => 52, - 2 => 52, - 3 => 52, - 4 => 52, - 5 => 52, - 6 => 52, - 7 => 52, - ), - '2010-12-25' => array( - 1 => 52, - 2 => 52, - 3 => 52, - 4 => 52, - 5 => 52, - 6 => 53, - 7 => 52, - ), - '2010-12-26' => array( - 1 => 52, - 2 => 52, - 3 => 52, - 4 => 52, - 5 => 52, - 6 => 53, - 7 => 53, - ), - '2010-12-27' => array( - 1 => 53, - 2 => 52, - 3 => 52, - 4 => 52, - 5 => 52, - 6 => 53, - 7 => 53, - ), - '2010-12-28' => array( - 1 => 53, - 2 => 53, - 3 => 52, - 4 => 52, - 5 => 52, - 6 => 53, - 7 => 53, - ), - '2010-12-29' => array( - 1 => 53, - 2 => 53, - 3 => 53, - 4 => 52, - 5 => 52, - 6 => 53, - 7 => 53, - ), - '2010-12-30' => array( - 1 => 53, - 2 => 53, - 3 => 53, - 4 => 53, - 5 => 52, - 6 => 53, - 7 => 53, - ), - '2010-12-31' => array( - 1 => 53, - 2 => 53, - 3 => 53, - 4 => 53, - 5 => 53, - 6 => 53, - 7 => 53, - ), - '2011-01-01' => array( - 1 => 1, - 2 => 1, - 3 => 1, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 1, - ), - '2011-01-02' => array( - 1 => 1, - 2 => 1, - 3 => 1, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 2, - ), - '2011-01-03' => array( - 1 => 2, - 2 => 1, - 3 => 1, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 2, - ), - '2011-01-04' => array( - 1 => 2, - 2 => 2, - 3 => 1, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 2, - ), - '2011-01-05' => array( - 1 => 2, - 2 => 2, - 3 => 2, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 2, - ), - '2011-01-06' => array( - 1 => 2, - 2 => 2, - 3 => 2, - 4 => 2, - 5 => 1, - 6 => 1, - 7 => 2, - ), - '2011-01-07' => array( - 1 => 2, - 2 => 2, - 3 => 2, - 4 => 2, - 5 => 2, - 6 => 1, - 7 => 2, - ), - '2011-01-08' => array( - 1 => 2, - 2 => 2, - 3 => 2, - 4 => 2, - 5 => 2, - 6 => 2, - 7 => 2, - ), - '2011-01-09' => array( - 1 => 2, - 2 => 2, - 3 => 2, - 4 => 2, - 5 => 2, - 6 => 2, - 7 => 3, - ), - '2011-01-10' => array( - 1 => 3, - 2 => 2, - 3 => 2, - 4 => 2, - 5 => 2, - 6 => 2, - 7 => 3, - ), - '2011-12-26' => array( - 1 => 53, - 2 => 52, - 3 => 52, - 4 => 52, - 5 => 52, - 6 => 52, - 7 => 53, - ), - '2011-12-27' => array( - 1 => 53, - 2 => 53, - 3 => 52, - 4 => 52, - 5 => 52, - 6 => 52, - 7 => 53, - ), - '2011-12-28' => array( - 1 => 53, - 2 => 53, - 3 => 53, - 4 => 52, - 5 => 52, - 6 => 52, - 7 => 53, - ), - '2011-12-29' => array( - 1 => 53, - 2 => 53, - 3 => 53, - 4 => 53, - 5 => 52, - 6 => 52, - 7 => 53, - ), - '2011-12-30' => array( - 1 => 53, - 2 => 53, - 3 => 53, - 4 => 53, - 5 => 53, - 6 => 52, - 7 => 53, - ), - '2011-12-31' => array( - 1 => 53, - 2 => 53, - 3 => 53, - 4 => 53, - 5 => 53, - 6 => 53, - 7 => 53, - ), - '2012-01-01' => array( - 1 => 1, - 2 => 1, - 3 => 1, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 1, - ), - '2012-01-02' => array( - 1 => 2, - 2 => 1, - 3 => 1, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 1, - ), - '2012-01-03' => array( - 1 => 2, - 2 => 2, - 3 => 1, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 1, - ), - '2012-01-04' => array( - 1 => 2, - 2 => 2, - 3 => 2, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 1, - ), - '2012-01-05' => array( - 1 => 2, - 2 => 2, - 3 => 2, - 4 => 2, - 5 => 1, - 6 => 1, - 7 => 1, - ), - '2012-01-06' => array( - 1 => 2, - 2 => 2, - 3 => 2, - 4 => 2, - 5 => 2, - 6 => 1, - 7 => 1, - ), - ); - - foreach ( $expected_week_no as $date => $week_numbers ) { - for ( $first_day_of_week = 1; $first_day_of_week <= 7; $first_day_of_week++ ) { - $datetime = new DateTime( $date, self::$local_tz ); - $this->assertEquals( $expected_week_no[ $date ][ $first_day_of_week ], WC_Admin_Reports_Interval::simple_week_number( $datetime, $first_day_of_week ), "First day of week: $first_day_of_week; Date: $date" ); - } - } - - } - - /** - * Testing ISO week number function. - */ - public function test_ISO_week_no() { - $expected_week_no = array( - '2010-12-24' => 51, - '2010-12-25' => 51, - '2010-12-26' => 51, - '2010-12-27' => 52, - '2010-12-28' => 52, - '2010-12-29' => 52, - '2010-12-30' => 52, - '2010-12-31' => 52, - '2011-01-01' => 52, - '2011-01-02' => 52, - '2011-01-03' => 1, - '2011-01-04' => 1, - '2011-01-05' => 1, - '2011-01-06' => 1, - '2011-01-07' => 1, - '2011-01-08' => 1, - '2011-01-09' => 1, - '2011-01-10' => 2, - '2011-12-26' => 52, - '2011-12-27' => 52, - '2011-12-28' => 52, - '2011-12-29' => 52, - '2011-12-30' => 52, - '2011-12-31' => 52, - '2012-01-01' => 52, - '2012-01-02' => 1, - '2012-01-03' => 1, - '2012-01-04' => 1, - '2012-01-05' => 1, - '2012-01-06' => 1, - ); - foreach ( $expected_week_no as $date => $week_numbers ) { - $datetime = new DateTime( $date, self::$local_tz ); - $this->assertEquals( $expected_week_no[ $date ], WC_Admin_Reports_Interval::week_number( $datetime, 1 ), "ISO week number for date: $date" ); - } - } - - /** - * Test function counting intervals between two datetimes. - */ - public function test_intervals_between() { - // Please note that all intervals are inclusive on both sides. - $test_settings = array( - // 0 interval length, should just return 1. - array( - 'start' => '2017-12-24T11:00:00', - 'end' => '2017-12-24T11:00:00', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 1, - 'day' => 1, - 'week' => 1, - 'month' => 1, - 'quarter' => 1, - 'year' => 1, - ), - ), - // <1 hour interval length -> should return 1 for all - array( - 'start' => '2017-12-24T11:00:00', - 'end' => '2017-12-24T11:40:00', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 1, - 'day' => 1, - 'week' => 1, - 'month' => 1, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 1.66 hour interval length -> 2 hours, 1 for the rest - array( - 'start' => '2017-12-24T11:00:00', - 'end' => '2017-12-24T12:40:00', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 2, - 'day' => 1, - 'week' => 1, - 'month' => 1, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 8.0186111 hours interval length -> 10 hours, 2 days, 1 for the rest - array( - 'start' => '2019-01-16T16:59:00', - 'end' => '2019-01-17T01:00:07', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 10, - 'day' => 2, - 'week' => 1, - 'month' => 1, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 23:59:59 h:m:s interval -> 24 hours, 2 days, 1 for the rest - array( - 'start' => '2017-12-24T11:00:00', - 'end' => '2017-12-25T10:59:59', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 24, - 'day' => 2, - 'week' => 2, - 'month' => 1, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 24 hour inclusive interval -> 25 hours, 2 days, 1 for the rest - array( - 'start' => '2017-12-24T11:00:00', - 'end' => '2017-12-25T11:00:00', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 25, - 'day' => 2, - 'week' => 2, - 'month' => 1, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 1 month interval spanning 1 month -> 720 hours, 30 days, 5 iso weeks, 1 months - array( - 'start' => '2017-11-01T00:00:00', - 'end' => '2017-11-30T23:59:59', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 720, - 'day' => 30, - 'week' => 5, - 'month' => 1, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 1 month interval spanning 2 months, but 1 quarter and 1 year -> 721 hours, 31 days, 5 iso weeks, 2 months - array( - 'start' => '2017-11-24T11:00:00', - 'end' => '2017-12-24T11:00:00', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 30 * 24 + 1, // 30 full days + 1 second from next hour - 'day' => 31, - 'week' => 5, - 'month' => 2, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 1 month + 14 hour interval spanning 2 months in 1 quarter -> 735 hours, 32 days, 6 iso weeks, 2 months - array( - 'start' => '2017-11-24T11:00:00', - 'end' => '2017-12-25T01:00:00', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 30 * 24 + 13 + 2, // 30 full days + 13 full hours on Nov 24 + 2 hours on Dec 25 - 'day' => 32, - 'week' => 6, - 'month' => 2, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 1 month interval spanning 2 months and 2 quarters, 1 year -> 720 hours, 31 days, 6 iso weeks, 2 months, 2 q, 1 y - array( - 'start' => '2017-09-24T11:00:00', - 'end' => '2017-10-24T10:59:59', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 30 * 24, - 'day' => 31, // Sept has 30 days, but need to include interval for half of Sept 24 and interval for half of Oct 24. - 'week' => 6, - 'month' => 2, - 'quarter' => 2, - 'year' => 1, - ), - ), - // 1 month interval spanning 2 months and 2 quarters, 2 years -> 744 hours, 32 days, 6 iso weeks, 2 months, 2 quarters, 2 years - array( - 'start' => '2017-12-24T11:00:00', - 'end' => '2018-01-24T10:59:59', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 31 * 24, - 'day' => 32, // Dec has 31 days, plus 1 interval for half day at the end. - 'week' => 6, - 'month' => 2, - 'quarter' => 2, - 'year' => 2, - ), - ), - // 3 months interval spanning 1 quarter, 1 year -> 2208 hours, 92 days, 14 iso weeks, 3 months, 1 quarters, 1 years - array( - 'start' => '2017-10-01T00:00:00', - 'end' => '2017-12-31T23:59:59', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 92 * 24, // 92 days - 'day' => 92, - 'week' => 14, - 'month' => 3, - 'quarter' => 1, - 'year' => 1, - ), - ), - // 3 months + 1 day interval spanning 2 quarters, 1 year -> 2208 hours, 92 days, 14 iso weeks, 3 months, 2 quarters, 1 years - array( - 'start' => '2017-09-30T00:00:00', - 'end' => '2017-12-30T23:59:59', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 92 * 24, // 92 days - 'day' => 92, - 'week' => 14, - 'month' => 4, - 'quarter' => 2, - 'year' => 1, - ), - ), - // 3 months + 1 day interval spanning 2 quarters, 2 years -> 2232 hours, 93 days, 14 iso weeks, 3 months, 2 quarters, 2 years - array( - 'start' => '2017-10-31T00:00:00', - 'end' => '2018-01-31T23:59:59', - 'week_start' => 1, - 'intervals' => array( - 'hour' => 93 * 24, // 93 days - 'day' => 93, // Jan 31d + Dec 31d + Nov 30d + Oct 1d = 93d. - 'week' => 14, - 'month' => 4, - 'quarter' => 2, - 'year' => 2, - ), - ), - // 9 months + 1 day interval spanning 2 quarters, 2 years. - array( - 'start' => '2017-04-01T00:00:00', - 'end' => '2018-01-01T00:00:00', - 'week_start' => 1, - 'intervals' => array( - 'month' => 9 + 1, - 'quarter' => 3 + 1, - 'year' => 2, - ), - ), - // 9 months + 1 day interval spanning 2 quarters, 2 years. - array( - 'start' => '2015-04-01T00:00:00', - 'end' => '2018-01-01T00:00:00', - 'week_start' => 1, - 'intervals' => array( - 'day' => 1007, // This includes leap year in 2016. - 'month' => 9 + 12 + 12 + 1, // Rest of 2015 + 2016 + 2017 + 1 second in 2018. - 'quarter' => 3 + 4 + 4 + 1, // Rest of 2015 + 2016 + 2017 + 1 second in 2018. - 'year' => 4, - ), - ), - ); - - foreach ( $test_settings as $setting ) { - update_option( 'start_of_week', $setting['week_start'] ); - foreach ( $setting['intervals'] as $interval => $exp_value ) { - $start_datetime = new DateTime( $setting['start'], self::$local_tz ); - $end_datetime = new DateTime( $setting['end'], self::$local_tz ); - $this->assertEquals( $exp_value, WC_Admin_Reports_Interval::intervals_between( $start_datetime, $end_datetime, $interval ), "First Day of Week: {$setting['week_start']}; Start: {$setting['start']}; End: {$setting['end']}; Interval: {$interval}" ); - } - } - } - - /** - * Test function that returns beginning of next hour. - */ - public function test_next_hour_start() { - $settings = array( - '2017-12-30T00:00:00' => array( - 0 => '2017-12-30T01:00:00', - 1 => '2017-12-29T23:59:59', - ), - '2017-12-30T10:00:00' => array( - 0 => '2017-12-30T11:00:00', - 1 => '2017-12-30T09:59:59', - ), - ); - foreach ( $settings as $datetime_s => $setting ) { - $datetime = new DateTime( $datetime_s, self::$local_tz ); - foreach ( $setting as $reversed => $exp_value ) { - $result_dt = WC_Admin_Reports_Interval::next_hour_start( $datetime, $reversed ); - $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); - } - } - } - - /** - * Test function that returns beginning of next day. - */ - public function test_next_day_start() { - $settings = array( - '2017-12-30T00:00:00' => array( - 0 => '2017-12-31T00:00:00', - 1 => '2017-12-29T23:59:59', - ), - '2017-12-30T10:00:00' => array( - 0 => '2017-12-31T00:00:00', - 1 => '2017-12-29T23:59:59', - ), - ); - foreach ( $settings as $datetime_s => $setting ) { - $datetime = new DateTime( $datetime_s, self::$local_tz ); - foreach ( $setting as $reversed => $exp_value ) { - $result_dt = WC_Admin_Reports_Interval::next_day_start( $datetime, $reversed ); - $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); - } - } - } - - /** - * Test function that returns beginning of next week, for weeks starting on Monday. - */ - public function test_next_week_start_ISO_week() { - update_option( 'start_of_week', 1 ); - $settings = array( - '2017-12-30T00:00:00' => array( - 0 => '2018-01-01T00:00:00', - 1 => '2017-12-24T23:59:59', - ), - '2017-12-30T10:00:00' => array( - 0 => '2018-01-01T00:00:00', - 1 => '2017-12-24T23:59:59', - ), - '2010-12-25T10:00:00' => array( - 0 => '2010-12-27T00:00:00', - 1 => '2010-12-19T23:59:59', - ), - '2010-12-26T10:00:00' => array( - 0 => '2010-12-27T00:00:00', - 1 => '2010-12-19T23:59:59', - ), - '2010-12-27T00:00:00' => array( - 0 => '2011-01-03T00:00:00', - 1 => '2010-12-26T23:59:59', - ), - '2010-12-31T00:00:00' => array( - 0 => '2011-01-03T00:00:00', - 1 => '2010-12-26T23:59:59', - ), - '2011-01-01T00:00:00' => array( - 0 => '2011-01-03T00:00:00', - 1 => '2010-12-26T23:59:59', - ), - '2011-01-03T00:00:00' => array( - 0 => '2011-01-10T00:00:00', - 1 => '2011-01-02T23:59:59', - ), - ); - foreach ( $settings as $datetime_s => $setting ) { - $datetime = new DateTime( $datetime_s, self::$local_tz ); - foreach ( $setting as $reversed => $exp_value ) { - $result_dt = WC_Admin_Reports_Interval::next_week_start( $datetime, $reversed ); - $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); - } - } - } - - /** - * Test function that returns beginning of next week, for weeks starting on Sunday. - */ - public function test_next_week_start_Sunday_based_week() { - update_option( 'start_of_week', 7 ); - $settings = array( - '2010-12-25T10:00:00' => array( - 0 => '2010-12-26T00:00:00', - 1 => '2010-12-18T23:59:59', - ), - '2010-12-26T10:00:00' => array( - 0 => '2011-01-01T00:00:00', - 1 => '2010-12-25T23:59:59', - ), - '2011-01-01T00:00:00' => array( - 0 => '2011-01-02T00:00:00', - 1 => '2010-12-31T23:59:59', - ), - '2011-01-02T00:00:00' => array( - 0 => '2011-01-09T00:00:00', - 1 => '2011-01-01T23:59:59', - ), - ); - foreach ( $settings as $datetime_s => $setting ) { - $datetime = new DateTime( $datetime_s, self::$local_tz ); - foreach ( $setting as $reversed => $exp_value ) { - $result_dt = WC_Admin_Reports_Interval::next_week_start( $datetime, $reversed ); - $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); - } - } - } - - /** - * Test function that returns beginning of next month. - */ - public function test_next_month_start() { - $settings = array( - '2017-12-30T00:00:00' => array( - 0 => '2018-01-01T00:00:00', - 1 => '2017-11-30T23:59:59', - ), - // Leap year reversed test. - '2016-03-05T10:00:00' => array( - 0 => '2016-04-01T00:00:00', - 1 => '2016-02-29T23:59:59', - ), - ); - foreach ( $settings as $datetime_s => $setting ) { - $datetime = new DateTime( $datetime_s, self::$local_tz ); - foreach ( $setting as $reversed => $exp_value ) { - $result_dt = WC_Admin_Reports_Interval::next_month_start( $datetime, $reversed ); - $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); - } - } - } - - /** - * Test function that returns beginning of next quarter. - */ - public function test_next_quarter_start() { - $settings = array( - '2017-12-31T00:00:00' => array( - 0 => '2018-01-01T00:00:00', - 1 => '2017-09-30T23:59:59', - ), - '2018-01-01T10:00:00' => array( - 0 => '2018-04-01T00:00:00', - 1 => '2017-12-31T23:59:59', - ), - '2018-02-14T10:00:00' => array( - 0 => '2018-04-01T00:00:00', - 1 => '2017-12-31T23:59:59', - ), - '2018-04-14T10:00:00' => array( - 0 => '2018-07-01T00:00:00', - 1 => '2018-03-31T23:59:59', - ), - '2018-07-14T10:00:00' => array( - 0 => '2018-10-01T00:00:00', - 1 => '2018-06-30T23:59:59', - ), - ); - foreach ( $settings as $datetime_s => $setting ) { - $datetime = new DateTime( $datetime_s, self::$local_tz ); - foreach ( $setting as $reversed => $exp_value ) { - $result_dt = WC_Admin_Reports_Interval::next_quarter_start( $datetime, $reversed ); - $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); - } - } - } - - /** - * Test function that returns beginning of next year. - */ - public function test_next_year_start() { - $settings = array( - '2017-12-31T23:59:59' => array( - 0 => '2018-01-01T00:00:00', - 1 => '2016-12-31T23:59:59', - ), - '2017-01-01T00:00:00' => array( - 0 => '2018-01-01T00:00:00', - 1 => '2016-12-31T23:59:59', - ), - '2017-04-23T14:53:00' => array( - 0 => '2018-01-01T00:00:00', - 1 => '2016-12-31T23:59:59', - ), - ); - foreach ( $settings as $datetime_s => $setting ) { - $datetime = new DateTime( $datetime_s, self::$local_tz ); - foreach ( $setting as $reversed => $exp_value ) { - $result_dt = WC_Admin_Reports_Interval::next_year_start( $datetime, $reversed ); - $this->assertEquals( $exp_value, $result_dt->format( WC_Admin_Reports_Interval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" ); - } - } - } - - /** - * Test function that normalizes *_between query parameters to *_min & *_max. - */ - public function test_normalize_between_params() { - $request = array( - 'a_between' => 'malformed', // won't be normalized (not an array). - 'b_between' => array( 1, 5 ), // results in min=1, max=5. - 'c_between' => array( 4, 2 ), // results in min=2, max=4. - 'd_between' => array( 7 ), // won't be normalized (only 1 item). - 'f_between' => array( 10, 12 ), // not in params, skipped. - ); - $params = array( 'a', 'b', 'c', 'd' ); - $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params, false ); - $expected = array( - 'b_min' => 1, - 'b_max' => 5, - 'c_min' => 2, - 'c_max' => 4, - ); - - $this->assertEquals( $result, $expected ); - } - - /** - * Test function that normalizes *_between query parameters for dates to *_after & *_before. - */ - public function test_normalize_between_date_params() { - $request = array( - 'a_between' => 'malformed', // won't be normalized (not an array). - 'b_between' => array( 1, 5 ), // results in after=1, before=5. - 'c_between' => array( 4, 2 ), // results in after=2, before=4. - 'd_between' => array( 7 ), // won't be normalized (only 1 item). - 'f_between' => array( 10, 12 ), // not in params, skipped. - ); - $params = array( 'a', 'b', 'c', 'd' ); - $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params, true ); - $expected = array( - 'b_after' => 1, - 'b_before' => 5, - 'c_after' => 2, - 'c_before' => 4, - ); - - $this->assertEquals( $result, $expected ); - } - - /** - * Test function that validates *_between query parameters for numeric values. - */ - public function test_rest_validate_between_numeric_arg() { - $this->assertIsWPError( - WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( 'not array', null, 'param' ), - 'param is not a numerically indexed array.' - ); - - $this->assertIsWPError( - WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1 ), null, 'param' ), - 'param must contain 2 numbers.' - ); - - $this->assertTrue( - WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1, 2 ), null, 'param' ) - ); - } - - /** - * Test function that validates *_between query parameters for date values. - */ - public function rest_validate_between_date_arg() { - $this->assertIsWPError( - WC_Admin_Reports_Interval::rest_validate_between_date_arg( 'not array', null, 'param' ), - 'param is not a numerically indexed array.' - ); - - $this->assertIsWPError( - WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( '2019-01-01T00:00:00' ), null, 'param' ), - 'param must contain 2 valid dates.' - ); - - $this->assertIsWPError( - WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( 'not a valid date' ), null, 'param' ), - 'param must contain 2 valid dates.' - ); - - $this->assertTrue( - WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( '2019-01-01T00:00:00', '2019-01-15T00:00:00' ), null, 'param' ) - ); - } -} diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100755 index cc42b05115a..00000000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,70 +0,0 @@ -query( "TRUNCATE TABLE {$wpdb->prefix}wc_admin_notes" ); // @codingStandardsIgnoreLine. + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}wc_admin_note_actions" ); // @codingStandardsIgnoreLine. + } + + /** + * Create two notes that we can use for notes REST API tests + */ + public static function add_notes_for_tests() { + $data_store = WC_Data_Store::load( 'admin-note' ); + + $note_1 = new WC_Admin_Note(); + $note_1->set_title( 'PHPUNIT_TEST_NOTE_1_TITLE' ); + $note_1->set_content( 'PHPUNIT_TEST_NOTE_1_CONTENT' ); + $note_1->set_content_data( (object) array( 'amount' => 1.23 ) ); + $note_1->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL ); + $note_1->set_icon( 'info' ); + $note_1->set_name( 'PHPUNIT_TEST_NOTE_NAME' ); + $note_1->set_source( 'PHPUNIT_TEST' ); + $note_1->add_action( + 'PHPUNIT_TEST_NOTE_1_ACTION_1_SLUG', + 'PHPUNIT_TEST_NOTE_1_ACTION_1_LABEL', + '?s=PHPUNIT_TEST_NOTE_1_ACTION_1_URL' + ); + $note_1->add_action( + 'PHPUNIT_TEST_NOTE_1_ACTION_2_SLUG', + 'PHPUNIT_TEST_NOTE_1_ACTION_2_LABEL', + '?s=PHPUNIT_TEST_NOTE_1_ACTION_2_URL' + ); + $note_1->save(); + + $note_2 = new WC_Admin_Note(); + $note_2->set_title( 'PHPUNIT_TEST_NOTE_2_TITLE' ); + $note_2->set_content( 'PHPUNIT_TEST_NOTE_2_CONTENT' ); + $note_2->set_content_data( (object) array( 'amount' => 4.56 ) ); + $note_2->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_WARNING ); + $note_2->set_icon( 'info' ); + $note_2->set_name( 'PHPUNIT_TEST_NOTE_NAME' ); + $note_2->set_source( 'PHPUNIT_TEST' ); + $note_2->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED ); + // This note has no actions. + $note_2->save(); + + $note_3 = new WC_Admin_Note(); + $note_3->set_title( 'PHPUNIT_TEST_NOTE_3_TITLE' ); + $note_3->set_content( 'PHPUNIT_TEST_NOTE_3_CONTENT' ); + $note_3->set_content_data( (object) array( 'amount' => 7.89 ) ); + $note_3->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL ); + $note_3->set_icon( 'info' ); + $note_3->set_name( 'PHPUNIT_TEST_NOTE_NAME' ); + $note_3->set_source( 'PHPUNIT_TEST' ); + $note_3->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED ); + $note_3->set_date_reminder( time() - HOUR_IN_SECONDS ); + // This note has no actions. + $note_3->save(); + + } +} diff --git a/unit-tests/Helpers/CouponHelper.php b/unit-tests/Helpers/CouponHelper.php new file mode 100644 index 00000000000..1ca863d1ca7 --- /dev/null +++ b/unit-tests/Helpers/CouponHelper.php @@ -0,0 +1,147 @@ + $coupon_code, + 'post_type' => 'shop_coupon', + 'post_status' => 'publish', + 'post_excerpt' => 'This is a dummy coupon', + ) + ); + + $meta = wp_parse_args( + $meta, + array( + 'discount_type' => 'fixed_cart', + 'coupon_amount' => '1', + 'individual_use' => 'no', + 'product_ids' => '', + 'exclude_product_ids' => '', + 'usage_limit' => '', + 'usage_limit_per_user' => '', + 'limit_usage_to_x_items' => '', + 'expiry_date' => '', + 'free_shipping' => 'no', + 'exclude_sale_items' => 'no', + 'product_categories' => array(), + 'exclude_product_categories' => array(), + 'minimum_amount' => '', + 'maximum_amount' => '', + 'customer_email' => array(), + 'usage_count' => '0', + ) + ); + + // Update meta. + foreach ( $meta as $key => $value ) { + update_post_meta( $coupon_id, $key, $value ); + } + + return new WC_Coupon( $coupon_code ); + } + + /** + * Delete a coupon. + * + * @param $coupon_id + * + * @return bool + */ + public static function delete_coupon( $coupon_id ) { + wp_delete_post( $coupon_id, true ); + + return true; + } + + /** + * Register a custom coupon type. + * + * @param string $coupon_type + */ + public static function register_custom_type( $coupon_type ) { + static $filters_added = false; + if ( isset( self::$custom_types[ $coupon_type ] ) ) { + return; + } + + self::$custom_types[ $coupon_type ] = "Testing custom type {$coupon_type}"; + + if ( ! $filters_added ) { + add_filter( 'woocommerce_coupon_discount_types', array( __CLASS__, 'filter_discount_types' ) ); + add_filter( 'woocommerce_coupon_get_discount_amount', array( __CLASS__, 'filter_get_discount_amount' ), 10, 5 ); + add_filter( 'woocommerce_coupon_is_valid_for_product', '__return_true' ); + $filters_added = true; + } + } + + /** + * Unregister custom coupon type. + * + * @param $coupon_type + */ + public static function unregister_custom_type( $coupon_type ) { + unset( self::$custom_types[ $coupon_type ] ); + if ( empty( self::$custom_types ) ) { + remove_filter( 'woocommerce_coupon_discount_types', array( __CLASS__, 'filter_discount_types' ) ); + remove_filter( 'woocommerce_coupon_get_discount_amount', array( __CLASS__, 'filter_get_discount_amount' ) ); + remove_filter( 'woocommerce_coupon_is_valid_for_product', '__return_true' ); + } + } + + /** + * Register custom discount types. + * + * @param array $discount_types + * @return array + */ + public static function filter_discount_types( $discount_types ) { + return array_merge( $discount_types, self::$custom_types ); + } + + /** + * Get custom discount type amount. Works like 'percent' type. + * + * @param float $discount + * @param float $discounting_amount + * @param array|null $item + * @param bool $single + * @param WC_Coupon $coupon + * + * @return float + */ + public static function filter_get_discount_amount( $discount, $discounting_amount, $item, $single, $coupon ) { + if ( ! isset( self::$custom_types [ $coupon->get_discount_type() ] ) ) { + return $discount; + } + + return (float) $coupon->get_amount() * ( $discounting_amount / 100 ); + } +} diff --git a/unit-tests/Helpers/CustomerHelper.php b/unit-tests/Helpers/CustomerHelper.php new file mode 100644 index 00000000000..3cf4f2ca1e5 --- /dev/null +++ b/unit-tests/Helpers/CustomerHelper.php @@ -0,0 +1,138 @@ + 0, + 'date_modified' => null, + 'country' => 'US', + 'state' => 'PA', + 'postcode' => '19123', + 'city' => 'Philadelphia', + 'address' => '123 South Street', + 'address_2' => 'Apt 1', + 'shipping_country' => 'US', + 'shipping_state' => 'PA', + 'shipping_postcode' => '19123', + 'shipping_city' => 'Philadelphia', + 'shipping_address' => '123 South Street', + 'shipping_address_2' => 'Apt 1', + 'is_vat_exempt' => false, + 'calculated_shipping' => false, + ); + + self::set_customer_details( $customer_data ); + + $customer = new WC_Customer( 0, true ); + + return $customer; + } + + /** + * Creates a customer in the tests DB. + */ + public static function create_customer( $username = 'testcustomer', $password = 'hunter2', $email = 'test@woo.local' ) { + $customer = new WC_Customer(); + $customer->set_billing_country( 'US' ); + $customer->set_first_name( 'Justin' ); + $customer->set_billing_state( 'PA' ); + $customer->set_billing_postcode( '19123' ); + $customer->set_billing_city( 'Philadelphia' ); + $customer->set_billing_address( '123 South Street' ); + $customer->set_billing_address_2( 'Apt 1' ); + $customer->set_shipping_country( 'US' ); + $customer->set_shipping_state( 'PA' ); + $customer->set_shipping_postcode( '19123' ); + $customer->set_shipping_city( 'Philadelphia' ); + $customer->set_shipping_address( '123 South Street' ); + $customer->set_shipping_address_2( 'Apt 1' ); + $customer->set_username( $username ); + $customer->set_password( $password ); + $customer->set_email( $email ); + $customer->save(); + return $customer; + } + + /** + * Get the expected output for the store's base location settings. + * + * @return array + */ + public static function get_expected_store_location() { + return array( 'GB', '', '', '' ); + } + + /** + * Get the customer's shipping and billing info from the session. + * + * @return array + */ + public static function get_customer_details() { + return WC()->session->get( 'customer' ); + } + + /** + * Get the user's chosen shipping method. + * + * @return array + */ + public static function get_chosen_shipping_methods() { + return WC()->session->get( 'chosen_shipping_methods' ); + } + + /** + * Get the "Tax Based On" WooCommerce option. + * + * @return string base or billing + */ + public static function get_tax_based_on() { + return get_option( 'woocommerce_tax_based_on' ); + } + + /** + * Set the the current customer's billing details in the session. + * + * @param string $default_shipping_method Shipping Method slug + */ + public static function set_customer_details( $customer_details ) { + WC()->session->set( 'customer', array_map( 'strval', $customer_details ) ); + } + + /** + * Set the user's chosen shipping method. + * + * @param string $chosen_shipping_method Shipping Method slug + */ + public static function set_chosen_shipping_methods( $chosen_shipping_methods ) { + WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods ); + } + + /** + * Set the "Tax Based On" WooCommerce option. + * + * @param string $default_shipping_method Shipping Method slug + */ + public static function set_tax_based_on( $default_shipping_method ) { + update_option( 'woocommerce_tax_based_on', $default_shipping_method ); + } +} diff --git a/unit-tests/Helpers/OrderHelper.php b/unit-tests/Helpers/OrderHelper.php new file mode 100644 index 00000000000..06c3f0c2663 --- /dev/null +++ b/unit-tests/Helpers/OrderHelper.php @@ -0,0 +1,129 @@ +get_items() as $item ) { + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::delete_product( $item['product_id'] ); + } + + ShippingHelper::delete_simple_flat_rate(); + + // Delete the order post. + $order->delete( true ); + } + + /** + * Create a order. + * + * @since 2.4 + * @version 3.0 New parameter $product. + * + * @param int $customer_id + * @param WC_Product $product + * + * @return WC_Order + */ + public static function create_order( $customer_id = 1, $product = null ) { + + if ( ! is_a( $product, 'WC_Product' ) ) { + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + } + + ShippingHelper::create_simple_flat_rate(); + + $order_data = array( + 'status' => 'pending', + 'customer_id' => $customer_id, + 'customer_note' => '', + 'total' => '', + ); + + $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // Required, else wc_create_order throws an exception + $order = wc_create_order( $order_data ); + + // Add order products + $item = new WC_Order_Item_Product(); + $item->set_props( + array( + 'product' => $product, + 'quantity' => 4, + 'subtotal' => wc_get_price_excluding_tax( $product, array( 'qty' => 4 ) ), + 'total' => wc_get_price_excluding_tax( $product, array( 'qty' => 4 ) ), + ) + ); + $item->save(); + $order->add_item( $item ); + + // Set billing address + $order->set_billing_first_name( 'Jeroen' ); + $order->set_billing_last_name( 'Sormani' ); + $order->set_billing_company( 'WooCompany' ); + $order->set_billing_address_1( 'WooAddress' ); + $order->set_billing_address_2( '' ); + $order->set_billing_city( 'WooCity' ); + $order->set_billing_state( 'NY' ); + $order->set_billing_postcode( '123456' ); + $order->set_billing_country( 'US' ); + $order->set_billing_email( 'admin@example.org' ); + $order->set_billing_phone( '555-32123' ); + + // Add shipping costs + $shipping_taxes = WC_Tax::calc_shipping_tax( '10', WC_Tax::get_shipping_tax_rates() ); + $rate = new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', $shipping_taxes, 'flat_rate' ); + $item = new WC_Order_Item_Shipping(); + $item->set_props( + array( + 'method_title' => $rate->label, + 'method_id' => $rate->id, + 'total' => wc_format_decimal( $rate->cost ), + 'taxes' => $rate->taxes, + ) + ); + foreach ( $rate->get_meta_data() as $key => $value ) { + $item->add_meta_data( $key, $value, true ); + } + $order->add_item( $item ); + + // Set payment gateway + $payment_gateways = WC()->payment_gateways->payment_gateways(); + $order->set_payment_method( $payment_gateways['bacs'] ); + + // Set totals + $order->set_shipping_total( 10 ); + $order->set_discount_total( 0 ); + $order->set_discount_tax( 0 ); + $order->set_cart_tax( 0 ); + $order->set_shipping_tax( 0 ); + $order->set_total( 50 ); // 4 x $10 simple helper product + $order->save(); + + return $order; + } +} diff --git a/unit-tests/Helpers/ProductHelper.php b/unit-tests/Helpers/ProductHelper.php new file mode 100644 index 00000000000..187cf4c7db6 --- /dev/null +++ b/unit-tests/Helpers/ProductHelper.php @@ -0,0 +1,306 @@ +delete( true ); + } + } + + /** + * Create simple product. + * + * @since 2.3 + * @param bool $save Save or return object. + * @return WC_Product_Simple + */ + public static function create_simple_product( $save = true ) { + $product = new WC_Product_Simple(); + $product->set_props( + array( + 'name' => 'Dummy Product', + 'regular_price' => 10, + 'price' => 10, + 'sku' => 'DUMMY SKU', + 'manage_stock' => false, + 'tax_status' => 'taxable', + 'downloadable' => false, + 'virtual' => false, + 'stock_status' => 'instock', + 'weight' => '1.1', + ) + ); + + if ( $save ) { + $product->save(); + return \wc_get_product( $product->get_id() ); + } else { + return $product; + } + } + + /** + * Create external product. + * + * @since 3.0.0 + * @return WC_Product_External + */ + public static function create_external_product() { + $product = new WC_Product_External(); + $product->set_props( + array( + 'name' => 'Dummy External Product', + 'regular_price' => 10, + 'sku' => 'DUMMY EXTERNAL SKU', + 'product_url' => 'http://woocommerce.com', + 'button_text' => 'Buy external product', + ) + ); + $product->save(); + + return \wc_get_product( $product->get_id() ); + } + + /** + * Create grouped product. + * + * @since 3.0.0 + * @return WC_Product_Grouped + */ + public static function create_grouped_product() { + $simple_product_1 = self::create_simple_product(); + $simple_product_2 = self::create_simple_product(); + $product = new WC_Product_Grouped(); + $product->set_props( + array( + 'name' => 'Dummy Grouped Product', + 'sku' => 'DUMMY GROUPED SKU', + ) + ); + $product->set_children( array( $simple_product_1->get_id(), $simple_product_2->get_id() ) ); + $product->save(); + + return \wc_get_product( $product->get_id() ); + } + + /** + * Create a dummy variation product. + * + * @since 2.3 + * + * @return WC_Product_Variable + */ + public static function create_variation_product() { + $product = new WC_Product_Variable(); + $product->set_props( + array( + 'name' => 'Dummy Variable Product', + 'sku' => 'DUMMY VARIABLE SKU', + ) + ); + + $attribute_data = self::create_attribute( 'size', array( 'small', 'large' ) ); // Create all attribute related things. + $attributes = array(); + $attribute = new WC_Product_Attribute(); + $attribute->set_id( $attribute_data['attribute_id'] ); + $attribute->set_name( $attribute_data['attribute_taxonomy'] ); + $attribute->set_options( $attribute_data['term_ids'] ); + $attribute->set_position( 1 ); + $attribute->set_visible( true ); + $attribute->set_variation( true ); + $attributes[] = $attribute; + + $product->set_attributes( $attributes ); + $product->save(); + + $variation_1 = new WC_Product_Variation(); + $variation_1->set_props( + array( + 'parent_id' => $product->get_id(), + 'sku' => 'DUMMY SKU VARIABLE SMALL', + 'regular_price' => 10, + ) + ); + $variation_1->set_attributes( array( 'pa_size' => 'small' ) ); + $variation_1->save(); + + $variation_2 = new WC_Product_Variation(); + $variation_2->set_props( + array( + 'parent_id' => $product->get_id(), + 'sku' => 'DUMMY SKU VARIABLE LARGE', + 'regular_price' => 15, + ) + ); + $variation_2->set_attributes( array( 'pa_size' => 'large' ) ); + $variation_2->save(); + + return \wc_get_product( $product->get_id() ); + } + + /** + * Create a dummy attribute. + * + * @since 2.3 + * + * @param string $raw_name Name of attribute to create. + * @param array(string) $terms Terms to create for the attribute. + * @return array + */ + public static function create_attribute( $raw_name = 'size', $terms = array( 'small' ) ) { + global $wpdb, $wc_product_attributes; + + // Make sure caches are clean. + \delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' ); + + // These are exported as labels, so convert the label to a name if possible first. + $attribute_labels = \wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name' ); + $attribute_name = \array_search( $raw_name, $attribute_labels, true ); + + if ( ! $attribute_name ) { + $attribute_name = \wc_sanitize_taxonomy_name( $raw_name ); + } + + $attribute_id = \wc_attribute_taxonomy_id_by_name( $attribute_name ); + + if ( ! $attribute_id ) { + $taxonomy_name = \wc_attribute_taxonomy_name( $attribute_name ); + + // Degister taxonomy which other tests may have created... + \unregister_taxonomy( $taxonomy_name ); + + $attribute_id = \wc_create_attribute( + array( + 'name' => $raw_name, + 'slug' => $attribute_name, + 'type' => 'select', + 'order_by' => 'menu_order', + 'has_archives' => 0, + ) + ); + + // Register as taxonomy. + \register_taxonomy( + $taxonomy_name, + apply_filters( 'woocommerce_taxonomy_objects_' . $taxonomy_name, array( 'product' ) ), + apply_filters( + 'woocommerce_taxonomy_args_' . $taxonomy_name, + array( + 'labels' => array( + 'name' => $raw_name, + ), + 'hierarchical' => false, + 'show_ui' => false, + 'query_var' => true, + 'rewrite' => false, + ) + ) + ); + + // Set product attributes global. + $wc_product_attributes = array(); + + foreach ( \wc_get_attribute_taxonomies() as $taxonomy ) { + $wc_product_attributes[ \wc_attribute_taxonomy_name( $taxonomy->attribute_name ) ] = $taxonomy; + } + } + + $attribute = \wc_get_attribute( $attribute_id ); + $return = array( + 'attribute_name' => $attribute->name, + 'attribute_taxonomy' => $attribute->slug, + 'attribute_id' => $attribute_id, + 'term_ids' => array(), + ); + + foreach ( $terms as $term ) { + $result = \term_exists( $term, $attribute->slug ); + + if ( ! $result ) { + $result = wp_insert_term( $term, $attribute->slug ); + $return['term_ids'][] = $result['term_id']; + } else { + $return['term_ids'][] = $result['term_id']; + } + } + + return $return; + } + + /** + * Delete an attribute. + * + * @param int $attribute_id ID to delete. + * + * @since 2.3 + */ + public static function delete_attribute( $attribute_id ) { + global $wpdb; + + $attribute_id = \absint( $attribute_id ); + + $wpdb->query( + $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = %d", $attribute_id ) + ); + } + + /** + * Creates a new product review on a specific product. + * + * @since 3.0 + * @param int $product_id integer Product ID that the review is for. + * @param string $review_content string Content to use for the product review. + * @return integer Product Review ID. + */ + public static function create_product_review( $product_id, $review_content = 'Review content here' ) { + $data = array( + 'comment_post_ID' => $product_id, + 'comment_author' => 'admin', + 'comment_author_email' => 'woo@woo.local', + 'comment_author_url' => '', + 'comment_date' => '2016-01-01T11:11:11', + 'comment_content' => $review_content, + 'comment_approved' => 1, + 'comment_type' => 'review', + ); + return \wp_insert_comment( $data ); + } + + /** + * A helper function for hooking into save_post during the test_product_meta_save_post test. + * @since 3.0.1 + * + * @param int $id ID to update. + */ + public static function save_post_test_update_meta_data_direct( $id ) { + \update_post_meta( $id, '_test2', 'world' ); + } +} diff --git a/unit-tests/Helpers/QueueHelper.php b/unit-tests/Helpers/QueueHelper.php new file mode 100644 index 00000000000..3b233ab5db3 --- /dev/null +++ b/unit-tests/Helpers/QueueHelper.php @@ -0,0 +1,62 @@ +queue()->search( + array( + 'per_page' => -1, + 'status' => 'pending', + 'claimed' => false, + ) + ); + + return $jobs; + } + + /** + * Run all pending queued actions. + * + * @return void + */ + public static function run_all_pending() { + $jobs = self::get_all_pending(); + + foreach ( $jobs as $job ) { + $job->execute(); + } + } + + /** + * Run all pending queued actions. + * + * @return void + */ + public static function process_pending() { + $jobs = self::get_all_pending(); + + $queue_runner = new ActionScheduler_QueueRunner(); + foreach ( $jobs as $job_id => $job ) { + $queue_runner->process_action( $job_id ); + } + } +} diff --git a/unit-tests/Helpers/ReportsHelper.php b/unit-tests/Helpers/ReportsHelper.php new file mode 100644 index 00000000000..0c2027699a7 --- /dev/null +++ b/unit-tests/Helpers/ReportsHelper.php @@ -0,0 +1,27 @@ +query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Orders_Stats_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Products_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Coupons_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Customers_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + } +} diff --git a/unit-tests/Helpers/SettingsHelper.php b/unit-tests/Helpers/SettingsHelper.php new file mode 100644 index 00000000000..928c69faa2a --- /dev/null +++ b/unit-tests/Helpers/SettingsHelper.php @@ -0,0 +1,82 @@ + 'test', + 'bad' => 'value', + 'label' => 'Test extension', + 'description' => 'My awesome test settings.', + 'option_key' => '', + ); + $groups[] = array( + 'id' => 'sub-test', + 'parent_id' => 'test', + 'label' => 'Sub test', + 'description' => '', + 'option_key' => '', + ); + $groups[] = array( + 'id' => 'coupon-data', + 'label' => 'Coupon data', + 'option_key' => '', + ); + $groups[] = array( + 'id' => 'invalid', + 'option_key' => '', + ); + return $groups; + } + + /** + * Registers some example settings. + * + * @since 3.0.0 + * @param array $settings + * @return array + */ + public static function register_test_settings( $settings ) { + $settings[] = array( + 'id' => 'woocommerce_shop_page_display', + 'label' => 'Shop page display', + 'description' => 'This controls what is shown on the product archive.', + 'default' => '', + 'type' => 'select', + 'options' => array( + '' => 'Show products', + 'subcategories' => 'Show categories & subcategories', + 'both' => 'Show both', + ), + 'option_key' => 'woocommerce_shop_page_display', + ); + return $settings; + } +} diff --git a/unit-tests/Helpers/ShippingHelper.php b/unit-tests/Helpers/ShippingHelper.php new file mode 100644 index 00000000000..8d8a2d03c6e --- /dev/null +++ b/unit-tests/Helpers/ShippingHelper.php @@ -0,0 +1,50 @@ + 'yes', + 'title' => 'Flat rate', + 'availability' => 'all', + 'countries' => '', + 'tax_status' => 'taxable', + 'cost' => '10', + ); + + update_option( 'woocommerce_flat_rate_settings', $flat_rate_settings ); + update_option( 'woocommerce_flat_rate', array() ); + WC_Cache_Helper::get_transient_version( 'shipping', true ); + WC()->shipping()->load_shipping_methods(); + } + + /** + * Delete the simple flat rate. + * + * @since 2.3 + */ + public static function delete_simple_flat_rate() { + delete_option( 'woocommerce_flat_rate_settings' ); + delete_option( 'woocommerce_flat_rate' ); + WC_Cache_Helper::get_transient_version( 'shipping', true ); + WC()->shipping()->unregister_shipping_methods(); + } +} diff --git a/tests/Blocks/products-attributes-terms.php b/unit-tests/Tests/Blocks/products-attributes-terms.php similarity index 92% rename from tests/Blocks/products-attributes-terms.php rename to unit-tests/Tests/Blocks/products-attributes-terms.php index 8a85261c08a..afe8cd3c4d8 100644 --- a/tests/Blocks/products-attributes-terms.php +++ b/unit-tests/Tests/Blocks/products-attributes-terms.php @@ -38,8 +38,8 @@ class WC_Tests_API_Products_Attributes_Terms_Controller extends WC_REST_Unit_Tes ); // Create 2 product attributes with terms. - $this->attr_color = WC_Helper_Product::create_attribute( 'color', array( 'red', 'yellow', 'blue' ) ); - $this->attr_size = WC_Helper_Product::create_attribute( 'size', array( 'small', 'medium', 'large', 'xlarge' ) ); + $this->attr_color = ProductHelper::create_attribute( 'color', array( 'red', 'yellow', 'blue' ) ); + $this->attr_size = ProductHelper::create_attribute( 'size', array( 'small', 'medium', 'large', 'xlarge' ) ); } /** diff --git a/tests/Blocks/products-attributes.php b/unit-tests/Tests/Blocks/products-attributes.php similarity index 92% rename from tests/Blocks/products-attributes.php rename to unit-tests/Tests/Blocks/products-attributes.php index 8a03a7b02e7..b21990dc0c2 100644 --- a/tests/Blocks/products-attributes.php +++ b/unit-tests/Tests/Blocks/products-attributes.php @@ -38,8 +38,8 @@ class WC_Tests_API_Products_Attributes_Controller extends WC_REST_Unit_Test_Case ); // Create 2 product attributes with terms. - $this->attr_color = WC_Helper_Product::create_attribute( 'color', array( 'red', 'yellow', 'blue' ) ); - $this->attr_size = WC_Helper_Product::create_attribute( 'size', array( 'small', 'medium', 'large', 'xlarge' ) ); + $this->attr_color = ProductHelper::create_attribute( 'color', array( 'red', 'yellow', 'blue' ) ); + $this->attr_size = ProductHelper::create_attribute( 'size', array( 'small', 'medium', 'large', 'xlarge' ) ); } /** diff --git a/tests/Blocks/products-categories.php b/unit-tests/Tests/Blocks/products-categories.php similarity index 95% rename from tests/Blocks/products-categories.php rename to unit-tests/Tests/Blocks/products-categories.php index 455f6857bcd..3aca14621c5 100644 --- a/tests/Blocks/products-categories.php +++ b/unit-tests/Tests/Blocks/products-categories.php @@ -53,11 +53,11 @@ class WC_Tests_API_Products_Categories_Controller extends WC_REST_Unit_Test_Case // Create two products for the parent category. $this->products = array(); - $this->products[0] = WC_Helper_Product::create_simple_product( false ); + $this->products[0] = ProductHelper::create_simple_product( false ); $this->products[0]->set_category_ids( array( $parent['term_id'] ) ); $this->products[0]->save(); - $this->products[3] = WC_Helper_Product::create_simple_product( false ); + $this->products[3] = ProductHelper::create_simple_product( false ); $this->products[3]->set_category_ids( array( $parent['term_id'], $single['term_id'] ) ); $this->products[3]->save(); } diff --git a/tests/Blocks/products.php b/unit-tests/Tests/Blocks/products.php similarity index 90% rename from tests/Blocks/products.php rename to unit-tests/Tests/Blocks/products.php index 1ce12330e1f..e8062c9c6a9 100644 --- a/tests/Blocks/products.php +++ b/unit-tests/Tests/Blocks/products.php @@ -57,19 +57,19 @@ class WC_Tests_API_Products_Controller extends WC_REST_Unit_Test_Case { // Create two products, one with 'parent', and one with 'single'. $this->products = array(); - $this->products[0] = WC_Helper_Product::create_simple_product( false ); + $this->products[0] = ProductHelper::create_simple_product( false ); $this->products[0]->set_category_ids( array( $parent['term_id'] ) ); $this->products[0]->save(); - $this->products[1] = WC_Helper_Product::create_simple_product( false ); + $this->products[1] = ProductHelper::create_simple_product( false ); $this->products[1]->set_category_ids( array( $single['term_id'] ) ); $this->products[1]->save(); - $this->products[2] = WC_Helper_Product::create_simple_product( false ); + $this->products[2] = ProductHelper::create_simple_product( false ); $this->products[2]->set_category_ids( array( $child['term_id'], $single['term_id'] ) ); $this->products[2]->save(); - $this->products[3] = WC_Helper_Product::create_simple_product( false ); + $this->products[3] = ProductHelper::create_simple_product( false ); $this->products[3]->set_category_ids( array( $parent['term_id'], $single['term_id'] ) ); $this->products[3]->save(); } @@ -93,9 +93,9 @@ class WC_Tests_API_Products_Controller extends WC_REST_Unit_Test_Case { */ public function test_get_products() { wp_set_current_user( $this->user ); - WC_Helper_Product::create_external_product(); + ProductHelper::create_external_product(); sleep( 1 ); // So both products have different timestamps. - $product = WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); $products = $response->get_data(); @@ -111,7 +111,7 @@ class WC_Tests_API_Products_Controller extends WC_REST_Unit_Test_Case { */ public function test_get_products_as_contributor() { wp_set_current_user( $this->contributor ); - WC_Helper_Product::create_simple_product(); + ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); $this->assertEquals( 200, $response->get_status() ); } @@ -123,7 +123,7 @@ class WC_Tests_API_Products_Controller extends WC_REST_Unit_Test_Case { */ public function test_get_products_as_subscriber() { wp_set_current_user( $this->subscriber ); - WC_Helper_Product::create_simple_product(); + ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); $this->assertEquals( 403, $response->get_status() ); } @@ -135,9 +135,9 @@ class WC_Tests_API_Products_Controller extends WC_REST_Unit_Test_Case { */ public function test_get_products_order_by_price() { wp_set_current_user( $this->user ); - WC_Helper_Product::create_external_product(); + ProductHelper::create_external_product(); sleep( 1 ); // So both products have different timestamps. - $product = WC_Helper_Product::create_simple_product( false ); // Prevent saving, since we save here. + $product = ProductHelper::create_simple_product( false ); // Prevent saving, since we save here. // Customize the price, otherwise both are 10. $product->set_props( array( @@ -167,22 +167,22 @@ class WC_Tests_API_Products_Controller extends WC_REST_Unit_Test_Case { */ public function test_product_visibility() { wp_set_current_user( $this->user ); - $visible_product = WC_Helper_Product::create_simple_product(); + $visible_product = ProductHelper::create_simple_product(); $visible_product->set_name( 'Visible Product' ); $visible_product->set_catalog_visibility( 'visible' ); $visible_product->save(); - $catalog_product = WC_Helper_Product::create_simple_product(); + $catalog_product = ProductHelper::create_simple_product(); $catalog_product->set_name( 'Catalog Product' ); $catalog_product->set_catalog_visibility( 'catalog' ); $catalog_product->save(); - $search_product = WC_Helper_Product::create_simple_product(); + $search_product = ProductHelper::create_simple_product(); $search_product->set_name( 'Search Product' ); $search_product->set_catalog_visibility( 'search' ); $search_product->save(); - $hidden_product = WC_Helper_Product::create_simple_product(); + $hidden_product = ProductHelper::create_simple_product(); $hidden_product->set_name( 'Hidden Product' ); $hidden_product->set_catalog_visibility( 'hidden' ); $hidden_product->save(); diff --git a/tests/Version2/coupons.php b/unit-tests/Tests/Version2/coupons.php similarity index 92% rename from tests/Version2/coupons.php rename to unit-tests/Tests/Version2/coupons.php index 592357327f7..1be88f1ee4e 100644 --- a/tests/Version2/coupons.php +++ b/unit-tests/Tests/Version2/coupons.php @@ -40,9 +40,9 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { public function test_get_coupons() { wp_set_current_user( $this->user ); - $coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post_1 = get_post( $coupon_1->get_id() ); - $coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' ); + $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons' ) ); $coupons = $response->get_data(); @@ -111,7 +111,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_coupon() { wp_set_current_user( $this->user ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); $data = $response->get_data(); @@ -167,7 +167,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -275,7 +275,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_coupon() { wp_set_current_user( $this->user ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); @@ -326,7 +326,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v2/coupons/' . $coupon->get_id() ); @@ -347,7 +347,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_coupon() { wp_set_current_user( $this->user ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/' . $coupon->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -373,7 +373,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/' . $coupon->get_id() ); $response = $this->server->dispatch( $request ); @@ -387,10 +387,10 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { public function test_batch_coupon() { wp_set_current_user( $this->user ); - $coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); - $coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' ); - $coupon_3 = WC_Helper_Coupon::create_coupon( 'dummycoupon-3' ); - $coupon_4 = WC_Helper_Coupon::create_coupon( 'dummycoupon-4' ); + $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); + $coupon_3 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-3' ); + $coupon_4 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-4' ); $request = new WP_REST_Request( 'POST', '/wc/v2/coupons/batch' ); $request->set_body_params( diff --git a/tests/Version2/customers.php b/unit-tests/Tests/Version2/customers.php similarity index 90% rename from tests/Version2/customers.php rename to unit-tests/Tests/Version2/customers.php index d6519cd246c..054aadbb5fe 100644 --- a/tests/Version2/customers.php +++ b/unit-tests/Tests/Version2/customers.php @@ -37,8 +37,8 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { public function test_get_customers() { wp_set_current_user( 1 ); - $customer_1 = WC_Helper_Customer::create_customer(); - WC_Helper_Customer::create_customer( 'test2', 'test2', 'test2@woo.local' ); + $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); + \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v2/customers' ); $request->set_query_params( @@ -296,7 +296,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_customer() { wp_set_current_user( 1 ); - $customer = WC_Helper_Customer::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -353,7 +353,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_customer_without_permission() { wp_set_current_user( 0 ); - $customer = WC_Helper_Customer::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -376,7 +376,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_customer() { wp_set_current_user( 1 ); - $customer = WC_Helper_Customer::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -404,7 +404,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_customer_without_permission() { wp_set_current_user( 0 ); - $customer = WC_Helper_Customer::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -428,7 +428,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_customer() { wp_set_current_user( 1 ); - $customer = WC_Helper_Customer::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -455,7 +455,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_customer_without_permission() { wp_set_current_user( 0 ); - $customer = WC_Helper_Customer::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -470,10 +470,10 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { public function test_batch_customer() { wp_set_current_user( 1 ); - $customer_1 = WC_Helper_Customer::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); - $customer_2 = WC_Helper_Customer::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); - $customer_3 = WC_Helper_Customer::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); - $customer_4 = WC_Helper_Customer::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); + $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); + $customer_2 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); + $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); + $customer_4 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); $request = new WP_REST_Request( 'POST', '/wc/v2/customers/batch' ); $request->set_body_params( diff --git a/tests/Version2/orders.php b/unit-tests/Tests/Version2/orders.php similarity index 91% rename from tests/Version2/orders.php rename to unit-tests/Tests/Version2/orders.php index 49df3ce98f7..f8cd8d497c6 100644 --- a/tests/Version2/orders.php +++ b/unit-tests/Tests/Version2/orders.php @@ -46,7 +46,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { // Create 10 orders. for ( $i = 0; $i < 10; $i++ ) { - $this->orders[] = WC_Helper_Order::create_order( $this->user ); + $this->orders[] = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); } $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders' ) ); @@ -63,7 +63,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_items_without_permission() { wp_set_current_user( 0 ); - $this->orders[] = WC_Helper_Order::create_order(); + $this->orders[] = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -74,7 +74,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_item() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order->add_meta_data( 'key', 'value' ); $order->add_meta_data( 'key2', 'value2' ); $order->save(); @@ -98,7 +98,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_item_without_permission() { wp_set_current_user( 0 ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $this->orders[] = $order; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $order->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); @@ -120,7 +120,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_item_refund_id() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $refund = wc_create_refund( array( 'order_id' => $order->get_id(), @@ -136,7 +136,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_order() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); $request->set_body_params( array( @@ -217,7 +217,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_update_order_payment_method_title_sanitize() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Test when creating order. $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); @@ -292,7 +292,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_order_invalid_fields() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // non-existent customer $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); @@ -351,7 +351,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); $request->set_body_params( array( @@ -378,7 +378,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order_remove_items() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $fee = new WC_Order_Item_Fee(); $fee->set_props( array( @@ -418,9 +418,9 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order_add_coupons() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); @@ -457,9 +457,9 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order_remove_coupons() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); @@ -504,7 +504,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order_without_permission() { wp_set_current_user( 0 ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); $request->set_body_params( array( @@ -545,7 +545,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_order() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/' . $order->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -559,7 +559,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_order_without_permission() { wp_set_current_user( 0 ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/' . $order->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -585,9 +585,9 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { public function test_orders_batch() { wp_set_current_user( $this->user ); - $order1 = WC_Helper_Order::create_order(); - $order2 = WC_Helper_Order::create_order(); - $order3 = WC_Helper_Order::create_order(); + $order1 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order2 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order3 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'POST', '/wc/v2/orders/batch' ); $request->set_body_params( @@ -623,7 +623,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_order_schema() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/orders/' . $order->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version2/payment-gateways.php b/unit-tests/Tests/Version2/payment-gateways.php similarity index 100% rename from tests/Version2/payment-gateways.php rename to unit-tests/Tests/Version2/payment-gateways.php diff --git a/tests/Version2/product-reviews.php b/unit-tests/Tests/Version2/product-reviews.php similarity index 81% rename from tests/Version2/product-reviews.php rename to unit-tests/Tests/Version2/product-reviews.php index bf30b5a41f2..770a890beeb 100644 --- a/tests/Version2/product-reviews.php +++ b/unit-tests/Tests/Version2/product-reviews.php @@ -39,10 +39,10 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_reviews() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Create 10 products reviews for the product for ( $i = 0; $i < 10; $i++ ) { - $review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); } $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); @@ -92,7 +92,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_reviews_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -115,8 +115,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_review() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -147,8 +147,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_review_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -160,7 +160,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/0' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -172,7 +172,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_product_review() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); $request->set_body_params( array( @@ -212,7 +212,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_product_review_invalid_fields() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // missing review $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); @@ -261,8 +261,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_review() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -295,8 +295,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_review_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); $request->set_body_params( @@ -319,7 +319,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/0' ); $request->set_body_params( @@ -342,8 +342,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product_review() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); $request->set_param( 'force', true ); @@ -358,8 +358,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); $response = $this->server->dispatch( $request ); @@ -374,8 +374,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/0' ); $request->set_param( 'force', true ); @@ -389,12 +389,12 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_product_reviews_batch() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $review_1_id = WC_Helper_Product::create_product_review( $product->get_id() ); - $review_2_id = WC_Helper_Product::create_product_review( $product->get_id() ); - $review_3_id = WC_Helper_Product::create_product_review( $product->get_id() ); - $review_4_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_1_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_2_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_3_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_4_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews/batch' ); $request->set_body_params( @@ -443,7 +443,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/reviews' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version2/product-variations.php b/unit-tests/Tests/Version2/product-variations.php similarity index 91% rename from tests/Version2/product-variations.php rename to unit-tests/Tests/Version2/product-variations.php index 7e268a7c657..b58e9076dd7 100644 --- a/tests/Version2/product-variations.php +++ b/unit-tests/Tests/Version2/product-variations.php @@ -40,7 +40,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_variations() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -56,7 +56,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_variations_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -68,7 +68,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_variation() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -87,7 +87,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_variation_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ) ); @@ -101,7 +101,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_variation() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -122,7 +122,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -139,7 +139,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_with_invalid_id() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() . '/variations/0' ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -153,7 +153,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_variation() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -205,7 +205,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_variation_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -226,7 +226,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_variation_with_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/0' ); $request->set_body_params( array( @@ -244,7 +244,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_variation() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); @@ -286,7 +286,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_variation_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations' ); $request->set_body_params( @@ -311,7 +311,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_product_variations_batch() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations/batch' ); $request->set_body_params( @@ -367,7 +367,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_variation_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/products/' . $product->get_id() . '/variations' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -419,7 +419,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { public function test_update_variation_manage_stock() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $product->set_manage_stock( false ); $product->save(); diff --git a/tests/Version2/products.php b/unit-tests/Tests/Version2/products.php similarity index 91% rename from tests/Version2/products.php rename to unit-tests/Tests/Version2/products.php index e45f51d7f4b..a6089fffa3a 100644 --- a/tests/Version2/products.php +++ b/unit-tests/Tests/Version2/products.php @@ -43,9 +43,9 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_products() { wp_set_current_user( $this->user ); - WC_Helper_Product::create_external_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); sleep( 1 ); // So both products have different timestamps. - WC_Helper_Product::create_simple_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); $products = $response->get_data(); @@ -65,7 +65,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_products_without_permission() { wp_set_current_user( 0 ); - WC_Helper_Product::create_simple_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -77,7 +77,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product() { wp_set_current_user( $this->user ); - $simple = WC_Helper_Product::create_external_product(); + $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $simple->get_id() ) ); $product = $response->get_data(); @@ -102,7 +102,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -114,7 +114,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() ); $request->set_param( 'force', true ); @@ -133,7 +133,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -162,7 +162,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // test simple products. - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -198,7 +198,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { $product->delete( true ); // test variable product (variations are tested in product-variations.php). - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -240,7 +240,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { $product->delete( true ); // test external product. - $product = WC_Helper_Product::create_external_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -268,7 +268,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); $request->set_body_params( array( @@ -286,7 +286,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_with_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' ); $request->set_body_params( array( @@ -419,8 +419,8 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_products_batch() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_2 = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v2/products/batch' ); $request->set_body_params( array( @@ -477,7 +477,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { public function test_products_filter_post_status() { wp_set_current_user( $this->user ); for ( $i = 0; $i < 8; $i++ ) { - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); if ( 0 === $i % 2 ) { wp_update_post( array( @@ -525,7 +525,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_product_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/products/' . $product->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version2/settings.php b/unit-tests/Tests/Version2/settings.php similarity index 99% rename from tests/Version2/settings.php rename to unit-tests/Tests/Version2/settings.php index f88abaa1588..52728d03461 100644 --- a/tests/Version2/settings.php +++ b/unit-tests/Tests/Version2/settings.php @@ -14,7 +14,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function setUp() { parent::setUp(); $this->endpoint = new WC_REST_Setting_Options_Controller(); - WC_Helper_Settings::register(); + \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', @@ -110,7 +110,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings' ) ); $this->assertEquals( 500, $response->get_status() ); - WC_Helper_Settings::register(); + \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); } /** @@ -370,7 +370,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $controller ->expects( $this->any() ) ->method( 'get_group_settings' ) - ->will( $this->returnValue( WC_Helper_Settings::register_test_settings( array() ) ) ); + ->will( $this->returnValue( \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); $controller ->expects( $this->any() ) diff --git a/tests/Version2/shipping-methods.php b/unit-tests/Tests/Version2/shipping-methods.php similarity index 100% rename from tests/Version2/shipping-methods.php rename to unit-tests/Tests/Version2/shipping-methods.php diff --git a/tests/Version2/shipping-zones.php b/unit-tests/Tests/Version2/shipping-zones.php similarity index 100% rename from tests/Version2/shipping-zones.php rename to unit-tests/Tests/Version2/shipping-zones.php diff --git a/tests/Version2/system-status.php b/unit-tests/Tests/Version2/system-status.php similarity index 100% rename from tests/Version2/system-status.php rename to unit-tests/Tests/Version2/system-status.php diff --git a/tests/Version3/coupons.php b/unit-tests/Tests/Version3/coupons.php similarity index 92% rename from tests/Version3/coupons.php rename to unit-tests/Tests/Version3/coupons.php index 40f9eaee25f..027117ede7e 100644 --- a/tests/Version3/coupons.php +++ b/unit-tests/Tests/Version3/coupons.php @@ -40,9 +40,9 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { public function test_get_coupons() { wp_set_current_user( $this->user ); - $coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post_1 = get_post( $coupon_1->get_id() ); - $coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' ); + $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons' ) ); $coupons = $response->get_data(); @@ -111,7 +111,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_get_coupon() { wp_set_current_user( $this->user ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); $data = $response->get_data(); @@ -167,7 +167,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_get_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -275,7 +275,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_update_coupon() { wp_set_current_user( $this->user ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); @@ -326,7 +326,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_update_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v3/coupons/' . $coupon->get_id() ); @@ -347,7 +347,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_delete_coupon() { wp_set_current_user( $this->user ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/' . $coupon->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -373,7 +373,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_delete_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/' . $coupon->get_id() ); $response = $this->server->dispatch( $request ); @@ -387,10 +387,10 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { public function test_batch_coupon() { wp_set_current_user( $this->user ); - $coupon_1 = WC_Helper_Coupon::create_coupon( 'dummycoupon-1' ); - $coupon_2 = WC_Helper_Coupon::create_coupon( 'dummycoupon-2' ); - $coupon_3 = WC_Helper_Coupon::create_coupon( 'dummycoupon-3' ); - $coupon_4 = WC_Helper_Coupon::create_coupon( 'dummycoupon-4' ); + $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); + $coupon_3 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-3' ); + $coupon_4 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-4' ); $request = new WP_REST_Request( 'POST', '/wc/v3/coupons/batch' ); $request->set_body_params( diff --git a/tests/Version3/customers.php b/unit-tests/Tests/Version3/customers.php similarity index 90% rename from tests/Version3/customers.php rename to unit-tests/Tests/Version3/customers.php index 5995045bb85..05ee7357d6f 100644 --- a/tests/Version3/customers.php +++ b/unit-tests/Tests/Version3/customers.php @@ -43,8 +43,8 @@ class Customers extends WC_REST_Unit_Test_Case { public function test_get_customers() { wp_set_current_user( 1 ); - $customer_1 = WC_Helper_Customer::create_customer(); - WC_Helper_Customer::create_customer( 'test2', 'test2', 'test2@woo.local' ); + $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); + \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); $request->set_query_params( @@ -115,7 +115,7 @@ class Customers extends WC_REST_Unit_Test_Case { ); update_option( 'timezone_tring', 'America/New York' ); - $customer_3 = WC_Helper_Customer::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); + $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); $request->set_query_params( @@ -368,7 +368,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_get_customer() { wp_set_current_user( 1 ); - $customer = WC_Helper_Customer::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -423,7 +423,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_get_customer_without_permission() { wp_set_current_user( 0 ); - $customer = WC_Helper_Customer::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -446,7 +446,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_update_customer() { wp_set_current_user( 1 ); - $customer = WC_Helper_Customer::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -474,7 +474,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_update_customer_without_permission() { wp_set_current_user( 0 ); - $customer = WC_Helper_Customer::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -498,7 +498,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_delete_customer() { wp_set_current_user( 1 ); - $customer = WC_Helper_Customer::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -525,7 +525,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_delete_customer_without_permission() { wp_set_current_user( 0 ); - $customer = WC_Helper_Customer::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -540,10 +540,10 @@ class Customers extends WC_REST_Unit_Test_Case { public function test_batch_customer() { wp_set_current_user( 1 ); - $customer_1 = WC_Helper_Customer::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); - $customer_2 = WC_Helper_Customer::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); - $customer_3 = WC_Helper_Customer::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); - $customer_4 = WC_Helper_Customer::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); + $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); + $customer_2 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); + $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); + $customer_4 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); $request = new WP_REST_Request( 'POST', '/wc/v3/customers/batch' ); $request->set_body_params( diff --git a/tests/Version3/functions.php b/unit-tests/Tests/Version3/functions.php similarity index 100% rename from tests/Version3/functions.php rename to unit-tests/Tests/Version3/functions.php diff --git a/tests/Version3/orders.php b/unit-tests/Tests/Version3/orders.php similarity index 90% rename from tests/Version3/orders.php rename to unit-tests/Tests/Version3/orders.php index d34a97bb80d..1e748674375 100644 --- a/tests/Version3/orders.php +++ b/unit-tests/Tests/Version3/orders.php @@ -50,7 +50,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { // Create 10 orders. for ( $i = 0; $i < 10; $i++ ) { - $this->orders[] = WC_Helper_Order::create_order( $this->user ); + $this->orders[] = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); } $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders' ) ); @@ -67,7 +67,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_items_without_permission() { wp_set_current_user( 0 ); - $this->orders[] = WC_Helper_Order::create_order(); + $this->orders[] = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -78,7 +78,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_item() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order->add_meta_data( 'key', 'value' ); $order->add_meta_data( 'key2', 'value2' ); $order->save(); @@ -102,7 +102,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_item_without_permission() { wp_set_current_user( 0 ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $this->orders[] = $order; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $order->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); @@ -124,7 +124,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_item_refund_id() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $refund = wc_create_refund( array( 'order_id' => $order->get_id(), @@ -140,7 +140,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_create_order() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); $request->set_body_params( array( @@ -221,7 +221,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_create_update_order_payment_method_title_sanitize() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Test when creating order. $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); @@ -296,7 +296,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_create_order_invalid_fields() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Non-existent customer. $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); @@ -355,7 +355,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_update_order() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); $request->set_body_params( array( @@ -382,7 +382,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_update_order_remove_items() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $fee = new WC_Order_Item_Fee(); $fee->set_props( array( @@ -423,9 +423,9 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { public function test_update_order_add_coupons() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); @@ -454,9 +454,9 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_update_order_remove_coupons() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); @@ -501,7 +501,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_invalid_coupon() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); $request->set_body_params( @@ -528,7 +528,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_update_order_without_permission() { wp_set_current_user( 0 ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); $request->set_body_params( array( @@ -571,7 +571,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_delete_order() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/' . $order->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -586,7 +586,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_delete_order_without_permission() { wp_set_current_user( 0 ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/' . $order->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -614,9 +614,9 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { public function test_orders_batch() { wp_set_current_user( $this->user ); - $order1 = WC_Helper_Order::create_order(); - $order2 = WC_Helper_Order::create_order(); - $order3 = WC_Helper_Order::create_order(); + $order1 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order2 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order3 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'POST', '/wc/v3/orders/batch' ); $request->set_body_params( @@ -653,7 +653,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_order_schema() { wp_set_current_user( $this->user ); - $order = WC_Helper_Order::create_order(); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/orders/' . $order->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version3/payment-gateways.php b/unit-tests/Tests/Version3/payment-gateways.php similarity index 100% rename from tests/Version3/payment-gateways.php rename to unit-tests/Tests/Version3/payment-gateways.php diff --git a/tests/Version3/product-reviews.php b/unit-tests/Tests/Version3/product-reviews.php similarity index 81% rename from tests/Version3/product-reviews.php rename to unit-tests/Tests/Version3/product-reviews.php index f34fd15626c..f99916fcce4 100644 --- a/tests/Version3/product-reviews.php +++ b/unit-tests/Tests/Version3/product-reviews.php @@ -39,10 +39,10 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_reviews() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Create 10 products reviews for the product for ( $i = 0; $i < 10; $i++ ) { - $review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); } $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); @@ -92,7 +92,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_reviews_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -115,8 +115,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_review() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -147,8 +147,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_review_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -160,7 +160,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/0' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -172,7 +172,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_create_product_review() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); $request->set_body_params( array( @@ -212,7 +212,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_create_product_review_invalid_fields() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // missing review $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); @@ -261,8 +261,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_update_product_review() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -295,8 +295,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_update_product_review_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); $request->set_body_params( @@ -319,7 +319,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_update_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/0' ); $request->set_body_params( @@ -342,8 +342,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_delete_product_review() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); $request->set_param( 'force', true ); @@ -358,8 +358,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); $response = $this->server->dispatch( $request ); @@ -374,8 +374,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_delete_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_review_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/0' ); $request->set_param( 'force', true ); @@ -391,12 +391,12 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_product_reviews_batch() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $review_1_id = WC_Helper_Product::create_product_review( $product->get_id() ); - $review_2_id = WC_Helper_Product::create_product_review( $product->get_id() ); - $review_3_id = WC_Helper_Product::create_product_review( $product->get_id() ); - $review_4_id = WC_Helper_Product::create_product_review( $product->get_id() ); + $review_1_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_2_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_3_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_4_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews/batch' ); $request->set_body_params( @@ -445,7 +445,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/reviews' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version3/product-variations.php b/unit-tests/Tests/Version3/product-variations.php similarity index 91% rename from tests/Version3/product-variations.php rename to unit-tests/Tests/Version3/product-variations.php index ab1b810be43..b5afb865176 100644 --- a/tests/Version3/product-variations.php +++ b/unit-tests/Tests/Version3/product-variations.php @@ -40,7 +40,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_get_variations() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -56,7 +56,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_get_variations_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -68,7 +68,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_get_variation() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -87,7 +87,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_get_variation_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ) ); @@ -101,7 +101,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_delete_variation() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -122,7 +122,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -139,7 +139,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_with_invalid_id() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() . '/variations/0' ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -153,7 +153,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_update_variation() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -205,7 +205,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_update_variation_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -226,7 +226,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_update_variation_with_invalid_id() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/0' ); $request->set_body_params( array( @@ -244,7 +244,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_create_variation() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); @@ -286,7 +286,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_create_variation_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations' ); $request->set_body_params( @@ -313,7 +313,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_product_variations_batch() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations/batch' ); $request->set_body_params( @@ -369,7 +369,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_variation_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() . '/variations' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -420,7 +420,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { public function test_update_variation_manage_stock() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $product->set_manage_stock( false ); $product->save(); diff --git a/tests/Version3/products.php b/unit-tests/Tests/Version3/products.php similarity index 90% rename from tests/Version3/products.php rename to unit-tests/Tests/Version3/products.php index 6b8cff59db2..9ef37759cbb 100644 --- a/tests/Version3/products.php +++ b/unit-tests/Tests/Version3/products.php @@ -43,9 +43,9 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_get_products() { wp_set_current_user( $this->user ); - WC_Helper_Product::create_external_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); sleep( 1 ); // So both products have different timestamps. - WC_Helper_Product::create_simple_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); $products = $response->get_data(); @@ -65,7 +65,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_get_products_without_permission() { wp_set_current_user( 0 ); - WC_Helper_Product::create_simple_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -77,7 +77,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_get_product() { wp_set_current_user( $this->user ); - $simple = WC_Helper_Product::create_external_product(); + $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $simple->get_id() ) ); $product = $response->get_data(); @@ -102,7 +102,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_get_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -114,7 +114,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_delete_product() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() ); $request->set_param( 'force', true ); @@ -133,7 +133,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -162,7 +162,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // test simple products. - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); $data = $response->get_data(); $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); @@ -201,7 +201,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $product->delete( true ); // test variable product (variations are tested in product-variations.php). - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -247,7 +247,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $product->delete( true ); // test external product. - $product = WC_Helper_Product::create_external_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -275,7 +275,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_update_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); $request->set_body_params( array( @@ -427,8 +427,8 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_products_batch() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_2 = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/batch' ); $request->set_body_params( array( @@ -485,7 +485,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { public function test_products_filter_post_status() { wp_set_current_user( $this->user ); for ( $i = 0; $i < 8; $i++ ) { - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); if ( 0 === $i % 2 ) { wp_update_post( array( @@ -533,7 +533,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_product_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -594,10 +594,10 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { public function test_get_products_by_type() { wp_set_current_user( $this->user ); - $simple = WC_Helper_Product::create_simple_product(); - $external = WC_Helper_Product::create_external_product(); - $grouped = WC_Helper_Product::create_grouped_product(); - $variable = WC_Helper_Product::create_variation_product(); + $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $external = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $grouped = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_grouped_product(); + $variable = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $product_ids_for_type = array( 'simple' => array( $simple->get_id() ), @@ -636,12 +636,12 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // Create a featured product. - $feat_product = WC_Helper_Product::create_simple_product(); + $feat_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $feat_product->set_featured( true ); $feat_product->save(); // Create a non-featured product. - $nonfeat_product = WC_Helper_Product::create_simple_product(); + $nonfeat_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $nonfeat_product->save(); $query_params = array( @@ -710,12 +710,12 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' ); // Product with a tag. - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $product->set_tag_ids( array( $test_tag_1['term_id'] ) ); $product->save(); // Product without a tag. - $product_2 = WC_Helper_Product::create_simple_product(); + $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $query_params = array( 'tag' => (string) $test_tag_1['term_id'], @@ -741,17 +741,17 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // Variable product with 2 different variations. - $variable_product = WC_Helper_Product::create_variation_product(); + $variable_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); // Terms created by variable product. $term_large = get_term_by( 'slug', 'large', 'pa_size' ); $term_small = get_term_by( 'slug', 'small', 'pa_size' ); // Simple product without attribute. - $product_1 = WC_Helper_Product::create_simple_product(); + $product_1 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Simple product with attribute size = large. - $product_2 = WC_Helper_Product::create_simple_product(); + $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $product_2->set_attributes( array( 'pa_size' => 'large' ) ); $product_2->save(); diff --git a/tests/Version3/reports-coupons-totals.php b/unit-tests/Tests/Version3/reports-coupons-totals.php similarity index 96% rename from tests/Version3/reports-coupons-totals.php rename to unit-tests/Tests/Version3/reports-coupons-totals.php index cc4e1ef2de0..10ce18f7ede 100644 --- a/tests/Version3/reports-coupons-totals.php +++ b/unit-tests/Tests/Version3/reports-coupons-totals.php @@ -89,7 +89,7 @@ class WC_Tests_API_Reports_Coupons_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/coupons/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version3/reports-customers-totals.php b/unit-tests/Tests/Version3/reports-customers-totals.php similarity index 96% rename from tests/Version3/reports-customers-totals.php rename to unit-tests/Tests/Version3/reports-customers-totals.php index 5b58d995d57..248f348d068 100644 --- a/tests/Version3/reports-customers-totals.php +++ b/unit-tests/Tests/Version3/reports-customers-totals.php @@ -105,7 +105,7 @@ class WC_Tests_API_Reports_Customers_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/customers/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version3/reports-orders-totals.php b/unit-tests/Tests/Version3/reports-orders-totals.php similarity index 96% rename from tests/Version3/reports-orders-totals.php rename to unit-tests/Tests/Version3/reports-orders-totals.php index 51508045e54..2c2834ea43a 100644 --- a/tests/Version3/reports-orders-totals.php +++ b/unit-tests/Tests/Version3/reports-orders-totals.php @@ -78,7 +78,7 @@ class WC_Tests_API_Reports_Orders_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/orders/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version3/reports-products-totals.php b/unit-tests/Tests/Version3/reports-products-totals.php similarity index 96% rename from tests/Version3/reports-products-totals.php rename to unit-tests/Tests/Version3/reports-products-totals.php index 30e6c34c865..a178b492381 100644 --- a/tests/Version3/reports-products-totals.php +++ b/unit-tests/Tests/Version3/reports-products-totals.php @@ -85,7 +85,7 @@ class WC_Tests_API_Reports_Products_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/products/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version3/reports-reviews-totals.php b/unit-tests/Tests/Version3/reports-reviews-totals.php similarity index 96% rename from tests/Version3/reports-reviews-totals.php rename to unit-tests/Tests/Version3/reports-reviews-totals.php index ab5f7a4bd33..6c477e97a9c 100644 --- a/tests/Version3/reports-reviews-totals.php +++ b/unit-tests/Tests/Version3/reports-reviews-totals.php @@ -84,7 +84,7 @@ class WC_Tests_API_Reports_Reviews_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/reviews/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version3/settings.php b/unit-tests/Tests/Version3/settings.php similarity index 99% rename from tests/Version3/settings.php rename to unit-tests/Tests/Version3/settings.php index aa4f67cd02e..db8b8480536 100644 --- a/tests/Version3/settings.php +++ b/unit-tests/Tests/Version3/settings.php @@ -14,7 +14,7 @@ class Settings extends WC_REST_Unit_Test_Case { public function setUp() { parent::setUp(); $this->endpoint = new WC_REST_Setting_Options_Controller(); - WC_Helper_Settings::register(); + \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', @@ -110,7 +110,7 @@ class Settings extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings' ) ); $this->assertEquals( 500, $response->get_status() ); - WC_Helper_Settings::register(); + \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); } /** @@ -371,7 +371,7 @@ class Settings extends WC_REST_Unit_Test_Case { $controller ->expects( $this->any() ) ->method( 'get_group_settings' ) - ->will( $this->returnValue( WC_Helper_Settings::register_test_settings( array() ) ) ); + ->will( $this->returnValue( \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); $controller ->expects( $this->any() ) diff --git a/tests/Version3/shipping-methods.php b/unit-tests/Tests/Version3/shipping-methods.php similarity index 100% rename from tests/Version3/shipping-methods.php rename to unit-tests/Tests/Version3/shipping-methods.php diff --git a/tests/Version3/shipping-zones.php b/unit-tests/Tests/Version3/shipping-zones.php similarity index 100% rename from tests/Version3/shipping-zones.php rename to unit-tests/Tests/Version3/shipping-zones.php diff --git a/tests/Version3/system-status.php b/unit-tests/Tests/Version3/system-status.php similarity index 100% rename from tests/Version3/system-status.php rename to unit-tests/Tests/Version3/system-status.php diff --git a/tests/Version4/admin-notes.php b/unit-tests/Tests/Version4/AdminNotes.php similarity index 96% rename from tests/Version4/admin-notes.php rename to unit-tests/Tests/Version4/AdminNotes.php index 54b63a23c94..e6544b1cff5 100644 --- a/tests/Version4/admin-notes.php +++ b/unit-tests/Tests/Version4/AdminNotes.php @@ -5,10 +5,17 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4; + +defined( 'ABSPATH' ) || exit; + +use \WooCommerce\RestApi\UnitTests\Helpers\AdminNotesHelper; +use \WC_REST_Unit_Test_Case; + /** - * Class WC_Tests_API_Admin_Notes + * Class AdminNotes */ -class WC_Tests_API_Admin_Notes extends WC_REST_Unit_Test_Case { +class AdminNotes extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -31,8 +38,8 @@ class WC_Tests_API_Admin_Notes extends WC_REST_Unit_Test_Case { ) ); - WC_Helper_Admin_Notes::reset_notes_dbs(); - WC_Helper_Admin_Notes::add_notes_for_tests(); + AdminNotesHelper::reset_notes_dbs(); + AdminNotesHelper::add_notes_for_tests(); } /** diff --git a/tests/Version4/Coupons.php b/unit-tests/Tests/Version4/Coupons.php similarity index 86% rename from tests/Version4/Coupons.php rename to unit-tests/Tests/Version4/Coupons.php index b456b2ded0f..6b2548f631b 100644 --- a/tests/Version4/Coupons.php +++ b/unit-tests/Tests/Version4/Coupons.php @@ -5,11 +5,11 @@ * @package WooCommerce/RestApi/Tests */ -namespace WooCommerce\RestApi\Tests\Version4; +namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Tests\AbstractRestApiTest; +use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; /** * Abstract Rest API Test Class @@ -101,10 +101,10 @@ class Coupons extends AbstractRestApiTest { * Test read. */ public function test_read() { - $coupon1 = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); - $coupon2 = \WC_Helper_Coupon::create_coupon( 'testcoupon-2' ); - $coupon3 = \WC_Helper_Coupon::create_coupon( 'anothertestcoupon-3' ); - $coupon4 = \WC_Helper_Coupon::create_coupon( 'anothertestcoupon-4' ); + $coupon1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); + $coupon2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-2' ); + $coupon3 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'anothertestcoupon-3' ); + $coupon4 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'anothertestcoupon-4' ); // Collection. $response = $this->do_request( '/wc/v4/coupons', 'GET' ); @@ -142,7 +142,7 @@ class Coupons extends AbstractRestApiTest { $this->assertExpectedResponse( $response, 404 ); // Update existing. - $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); $response = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'POST', @@ -171,14 +171,14 @@ class Coupons extends AbstractRestApiTest { $this->assertEquals( 404, $result->status ); // Trash. - $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); $this->assertEquals( 200, $result->status ); $this->assertEquals( 'trash', get_post_status( $coupon->get_id() ) ); // Force. - $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-2' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-2' ); $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => true ] ); $this->assertEquals( 200, $result->status ); @@ -234,7 +234,7 @@ class Coupons extends AbstractRestApiTest { */ public function test_guest_update() { wp_set_current_user( 0 ); - $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); $response = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'POST', @@ -251,7 +251,7 @@ class Coupons extends AbstractRestApiTest { */ public function test_guest_delete() { wp_set_current_user( 0 ); - $coupon = \WC_Helper_Coupon::create_coupon( 'testcoupon-1' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); $this->assertEquals( 401, $result->status ); } @@ -278,10 +278,10 @@ class Coupons extends AbstractRestApiTest { * Test a batch update. */ public function test_batch() { - $coupon_1 = \WC_Helper_Coupon::create_coupon( 'batchcoupon-1' ); - $coupon_2 = \WC_Helper_Coupon::create_coupon( 'batchcoupon-2' ); - $coupon_3 = \WC_Helper_Coupon::create_coupon( 'batchcoupon-3' ); - $coupon_4 = \WC_Helper_Coupon::create_coupon( 'batchcoupon-4' ); + $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'batchcoupon-1' ); + $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'batchcoupon-2' ); + $coupon_3 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'batchcoupon-3' ); + $coupon_4 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'batchcoupon-4' ); $result = $this->do_request( '/wc/v4/coupons/batch', diff --git a/unit-tests/Tests/Version4/Customers.php b/unit-tests/Tests/Version4/Customers.php new file mode 100644 index 00000000000..3bbda740f09 --- /dev/null +++ b/unit-tests/Tests/Version4/Customers.php @@ -0,0 +1,640 @@ +endpoint = new WC_REST_Customers_Controller(); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( '/wc/v4/customers', $routes ); + $this->assertArrayHasKey( '/wc/v4/customers/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v4/customers/batch', $routes ); + } + + /** + * Test getting customers. + * + * @since 3.5.0 + */ + public function test_get_customers() { + wp_set_current_user( 1 ); + + $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); + \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/customers' ); + $request->set_query_params( + array( + 'orderby' => 'id', + ) + ); + $response = $this->server->dispatch( $request ); + $customers = $response->get_data(); + $date_created = get_date_from_gmt( date( 'Y-m-d H:i:s', strtotime( $customer_1->get_date_created() ) ) ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $customers ) ); + + $this->assertContains( + array( + 'id' => $customer_1->get_id(), + 'date_created' => wc_rest_prepare_date_response( $date_created, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $date_created ), + 'date_modified' => wc_rest_prepare_date_response( $customer_1->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_1->get_date_modified() ), + 'email' => 'test@woo.local', + 'first_name' => 'Justin', + 'last_name' => '', + 'role' => 'customer', + 'username' => 'testcustomer', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'avatar_url' => $customer_1->get_avatar_url(), + 'meta_data' => array(), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/customers/' . $customer_1->get_id() . '' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/customers' ), + ), + ), + ), + ), + $customers + ); + + update_option( 'timezone_tring', 'America/New York' ); + $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/customers' ); + $request->set_query_params( + array( + 'orderby' => 'id', + ) + ); + $response = $this->server->dispatch( $request ); + $customers = $response->get_data(); + $date_created = get_date_from_gmt( date( 'Y-m-d H:i:s', strtotime( $customer_3->get_date_created() ) ) ); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertContains( + array( + 'id' => $customer_3->get_id(), + 'date_created' => wc_rest_prepare_date_response( $date_created, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $date_created ), + 'date_modified' => wc_rest_prepare_date_response( $customer_3->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_3->get_date_modified() ), + 'email' => 'timezonetest@woo.local', + 'first_name' => 'Justin', + 'last_name' => '', + 'role' => 'customer', + 'username' => 'timezonetest', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'avatar_url' => $customer_3->get_avatar_url(), + 'meta_data' => array(), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/customers/' . $customer_3->get_id() . '' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/customers' ), + ), + ), + ), + ), + $customers + ); + + } + + /** + * Test getting customers without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_customers_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test creating a new customer. + * + * @since 3.5.0 + */ + public function test_create_customer() { + wp_set_current_user( 1 ); + + // Test just the basics first.. + $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test', + 'password' => 'test123', + 'email' => 'create_customer_test@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'create_customer_test@woo.local', + 'first_name' => '', + 'last_name' => '', + 'role' => 'customer', + 'username' => 'create_customer_test', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + + // Test extra data. + $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test2', + 'password' => 'test123', + 'email' => 'create_customer_test2@woo.local', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + 'billing' => array( + 'country' => 'US', + 'state' => 'WA', + ), + 'shipping' => array( + 'state' => 'CA', + 'country' => 'US', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'create_customer_test2@woo.local', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + 'role' => 'customer', + 'username' => 'create_customer_test2', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => 'WA', + 'postcode' => '', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => 'CA', + 'postcode' => '', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + + // Test without required field. + $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test3', + 'first_name' => 'Test', + 'last_name' => 'McTestFace', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating customers without valid permissions. + * + * @since 3.5.0 + */ + public function test_create_customer_without_permission() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); + $request->set_body_params( + array( + 'username' => 'create_customer_test_without_permission', + 'password' => 'test123', + 'email' => 'create_customer_test_without_permission@woo.local', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single customer. + * + * @since 3.5.0 + */ + public function test_get_customer() { + wp_set_current_user( 1 ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( + array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => 'get_customer_test@woo.local', + 'first_name' => 'Justin', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '123 South Street', + 'address_2' => 'Apt 1', + 'city' => 'Philadelphia', + 'state' => 'PA', + 'postcode' => '19123', + 'country' => 'US', + ), + 'is_paying_customer' => false, + 'meta_data' => array(), + 'last_name' => '', + 'role' => 'customer', + 'username' => 'get_customer_test', + 'avatar_url' => $data['avatar_url'], + ), + $data + ); + } + + /** + * Test getting a single customer without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single customer with an invalid ID. + * + * @since 3.5.0 + */ + public function test_get_customer_invalid_id() { + wp_set_current_user( 1 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a customer. + * + * @since 3.5.0 + */ + public function test_update_customer() { + wp_set_current_user( 1 ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); + $data = $response->get_data(); + $this->assertEquals( 'update_customer_test', $data['username'] ); + $this->assertEquals( 'update_customer_test@woo.local', $data['email'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v4/customers/' . $customer->get_id() ); + $request->set_body_params( + array( + 'email' => 'updated_email@woo.local', + 'first_name' => 'UpdatedTest', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'updated_email@woo.local', $data['email'] ); + $this->assertEquals( 'UpdatedTest', $data['first_name'] ); + } + + /** + * Test updating a customer without valid permissions. + * + * @since 3.5.0 + */ + public function test_update_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a customer with an invalid ID. + * + * @since 3.5.0 + */ + public function test_update_customer_invalid_id() { + wp_set_current_user( 1 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + + /** + * Test deleting a customer. + * + * @since 3.5.0 + */ + public function test_delete_customer() { + wp_set_current_user( 1 ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/' . $customer->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test deleting a customer with an invalid ID. + * + * @since 3.5.0 + */ + public function test_delete_customer_invalid_id() { + wp_set_current_user( 1 ); + $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test deleting a customer without valid permissions. + * + * @since 3.5.0 + */ + public function test_delete_customer_without_permission() { + wp_set_current_user( 0 ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); + $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/' . $customer->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test customer batch endpoint. + * + * @since 3.5.0 + */ + public function test_batch_customer() { + wp_set_current_user( 1 ); + + $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); + $customer_2 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); + $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); + $customer_4 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/customers/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $customer_1->get_id(), + 'last_name' => 'McTest', + ), + ), + 'delete' => array( + $customer_2->get_id(), + $customer_3->get_id(), + ), + 'create' => array( + array( + 'username' => 'newuser', + 'password' => 'test123', + 'email' => 'newuser@woo.local', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'McTest', $data['update'][0]['last_name'] ); + $this->assertEquals( 'newuser', $data['create'][0]['username'] ); + $this->assertEmpty( $data['create'][0]['last_name'] ); + $this->assertEquals( $customer_2->get_id(), $data['delete'][0]['id'] ); + $this->assertEquals( $customer_3->get_id(), $data['delete'][1]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/customers' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + + /** + * Test customer schema. + * + * @since 3.5.0 + */ + public function test_customer_schema() { + wp_set_current_user( 1 ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/customers' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 16, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_created_gmt', $properties ); + $this->assertArrayHasKey( 'date_modified', $properties ); + $this->assertArrayHasKey( 'date_modified_gmt', $properties ); + $this->assertArrayHasKey( 'email', $properties ); + $this->assertArrayHasKey( 'first_name', $properties ); + $this->assertArrayHasKey( 'last_name', $properties ); + $this->assertArrayHasKey( 'role', $properties ); + $this->assertArrayHasKey( 'username', $properties ); + $this->assertArrayHasKey( 'password', $properties ); + $this->assertArrayHasKey( 'avatar_url', $properties ); + $this->assertArrayHasKey( 'billing', $properties ); + $this->assertArrayHasKey( 'first_name', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'last_name', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'company', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'address_1', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'address_2', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'city', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'state', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'postcode', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'country', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'email', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'phone', $properties['billing']['properties'] ); + $this->assertArrayHasKey( 'shipping', $properties ); + $this->assertArrayHasKey( 'first_name', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'last_name', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'company', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'address_1', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'address_2', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'city', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'state', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'postcode', $properties['shipping']['properties'] ); + $this->assertArrayHasKey( 'country', $properties['shipping']['properties'] ); + } +} diff --git a/tests/Version4/data.php b/unit-tests/Tests/Version4/Data.php similarity index 90% rename from tests/Version4/data.php rename to unit-tests/Tests/Version4/Data.php index 88e4704eff3..c7f689cb946 100644 --- a/tests/Version4/data.php +++ b/unit-tests/Tests/Version4/Data.php @@ -5,10 +5,16 @@ * @package WooCommerce Admin\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; + /** * WC Tests API Data */ -class WC_Tests_API_Data extends WC_REST_Unit_Test_Case { +class Data extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -50,7 +56,7 @@ class WC_Tests_API_Data extends WC_REST_Unit_Test_Case { */ public function test_download_ips() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper::reset_stats_dbs(); $prod_download = new WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); @@ -63,7 +69,7 @@ class WC_Tests_API_Data extends WC_REST_Unit_Test_Case { $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); $order->save(); diff --git a/unit-tests/Tests/Version4/Functions.php b/unit-tests/Tests/Version4/Functions.php new file mode 100644 index 00000000000..5d5a01ebadf --- /dev/null +++ b/unit-tests/Tests/Version4/Functions.php @@ -0,0 +1,257 @@ +http_responder = array( $this, 'mock_http_responses' ); + + $upload_dir_info = wp_upload_dir(); + $this->upload_dir_path = $upload_dir_info['path']; + $this->upload_dir_url = $upload_dir_info['url']; + $this->file_name = 'Dr1Bczxq4q.png'; + } + + /** + * Run tear down code for unit tests. + */ + public function tearDown() { + parent::tearDown(); + + // remove files created in the wc_rest_upload_image_from_url() tests. + $file_path = $this->upload_dir_path . '/' . $this->file_name; + + if ( file_exists( $file_path ) ) { + unlink( $file_path ); + } + } + + /** + * Test wc_rest_prepare_date_response(). + * + * @since 2.6.0 + */ + public function test_wc_rest_prepare_date_response() { + $this->assertEquals( '2016-06-06T06:06:06', wc_rest_prepare_date_response( '2016-06-06 06:06:06' ) ); + } + + /** + * Test wc_rest_upload_image_from_url() should return error when unable to download image. + */ + public function test_wc_rest_upload_image_from_url_should_return_error_when_unable_to_download_image() { + $expected_error_message = 'Error getting remote image http://somedomain.com/nonexistent-image.png. Error: Not found.'; + $result = wc_rest_upload_image_from_url( 'http://somedomain.com/nonexistent-image.png' ); + + $this->assertIsWPError( $result ); + $this->assertEquals( $expected_error_message, $result->get_error_message() ); + } + + /** + * Test wc_rest_upload_image_from_url() should return error when invalid image is passed. + * + * @requires PHP 5.4 + */ + public function test_wc_rest_upload_image_from_url_should_return_error_when_invalid_image_is_passed() { + // empty file. + $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; + $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-1.png' ); + + $this->assertIsWPError( $result ); + $this->assertEquals( $expected_error_message, $result->get_error_message() ); + + // unsupported mime type. + $expected_error_message = 'Invalid image: Sorry, this file type is not permitted for security reasons.'; + $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-2.png' ); + + $this->assertIsWPError( $result ); + $this->assertEquals( $expected_error_message, $result->get_error_message() ); + } + + /** + * Test wc_rest_upload_image_from_url() should download image and return an array containing + * information about it. + * + * @requires PHP 5.4 + */ + public function test_wc_rest_upload_image_from_url_should_download_image_and_return_array() { + $expected_result = array( + 'file' => $this->upload_dir_path . '/' . $this->file_name, + 'url' => $this->upload_dir_url . '/' . $this->file_name, + 'type' => 'image/png', + ); + $result = wc_rest_upload_image_from_url( 'http://somedomain.com/' . $this->file_name ); + + $this->assertEquals( $expected_result, $result ); + } + + /** + * Test wc_rest_set_uploaded_image_as_attachment(). + * + * @since 2.6.0 + */ + public function test_wc_rest_set_uploaded_image_as_attachment() { + $this->assertInternalType( + 'int', + wc_rest_set_uploaded_image_as_attachment( + array( + 'file' => '', + 'url' => '', + ) + ) + ); + } + + /** + * Test wc_rest_validate_reports_request_arg(). + * + * @since 2.6.0 + */ + public function test_wc_rest_validate_reports_request_arg() { + $request = new WP_REST_Request( + 'GET', + '/wc/v4/foo', + array( + 'args' => array( + 'date' => array( + 'type' => 'string', + 'format' => 'date', + ), + ), + ) + ); + + // Success. + $this->assertTrue( wc_rest_validate_reports_request_arg( '2016-06-06', $request, 'date' ) ); + + // Error. + $error = wc_rest_validate_reports_request_arg( 'foo', $request, 'date' ); + $this->assertEquals( 'The date you provided is invalid.', $error->get_error_message() ); + } + + /** + * Test wc_rest_urlencode_rfc3986(). + * + * @since 2.6.0 + */ + public function test_wc_rest_urlencode_rfc3986() { + $this->assertEquals( 'https%3A%2F%2Fwoocommerce.com%2F', wc_rest_urlencode_rfc3986( 'https://woocommerce.com/' ) ); + } + + /** + * Test wc_rest_check_post_permissions(). + * + * @since 2.6.0 + */ + public function test_wc_rest_check_post_permissions() { + $this->assertFalse( wc_rest_check_post_permissions( 'shop_order' ) ); + } + + /** + * Test wc_rest_check_user_permissions(). + * + * @since 2.6.0 + */ + public function test_wc_rest_check_user_permissions() { + $this->assertFalse( wc_rest_check_user_permissions() ); + } + + /** + * Test wc_rest_check_product_term_permissions(). + * + * @since 2.6.0 + */ + public function test_wc_rest_check_product_term_permissions() { + $this->assertFalse( wc_rest_check_product_term_permissions( 'product_cat' ) ); + } + + /** + * Test wc_rest_check_manager_permissions(). + * + * @since 2.6.0 + */ + public function test_wc_rest_check_manager_permissions() { + $this->assertFalse( wc_rest_check_manager_permissions( 'reports' ) ); + } + + /** + * Helper method to define mocked HTTP responses using WP_HTTP_TestCase. + * Thanks to WP_HTTP_TestCase, it is not necessary to perform a regular request + * to an external server which would significantly slow down the tests. + * + * This function is called by WP_HTTP_TestCase::http_request_listner(). + * + * @param array $request Request arguments. + * @param string $url URL of the request. + * + * @return array|false mocked response or false to let WP perform a regular request. + */ + protected function mock_http_responses( $request, $url ) { + $mocked_response = false; + + if ( 'http://somedomain.com/nonexistent-image.png' === $url ) { + $mocked_response = array( + 'response' => array( + 'code' => 404, + 'message' => 'Not found.', + ), + ); + } elseif ( 'http://somedomain.com/invalid-image-1.png' === $url ) { + // empty image. + $mocked_response = array( + 'response' => array( 'code' => 200 ), + ); + } elseif ( 'http://somedomain.com/invalid-image-2.png' === $url ) { + // image with an unsupported mime type. + // we need to manually copy the file as we are mocking the request. without this an empty file is created. + copy( WC_Unit_Tests_Bootstrap::instance()->tests_dir . '/data/file.txt', $request['filename'] ); + + $mocked_response = array( + 'response' => array( 'code' => 200 ), + ); + } elseif ( 'http://somedomain.com/' . $this->file_name === $url ) { + // we need to manually copy the file as we are mocking the request. without this an empty file is created. + copy( WC_Unit_Tests_Bootstrap::instance()->tests_dir . '/data/Dr1Bczxq4q.png', $request['filename'] ); + + $mocked_response = array( + 'response' => array( 'code' => 200 ), + ); + } + + return $mocked_response; + } +} diff --git a/tests/Version4/leaderboards.php b/unit-tests/Tests/Version4/Leaderboards.php similarity index 96% rename from tests/Version4/leaderboards.php rename to unit-tests/Tests/Version4/Leaderboards.php index e2e0a0ac696..8cd8407b62f 100644 --- a/tests/Version4/leaderboards.php +++ b/unit-tests/Tests/Version4/Leaderboards.php @@ -5,10 +5,16 @@ * @package WooCommerce Admin\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; + /** * WC Tests API Leaderboards */ -class WC_Tests_API_Leaderboards extends WC_REST_Unit_Test_Case { +class Leaderboards extends WC_REST_Unit_Test_Case { /** * Endpoints. * diff --git a/tests/Version4/Orders.php b/unit-tests/Tests/Version4/Orders.php similarity index 92% rename from tests/Version4/Orders.php rename to unit-tests/Tests/Version4/Orders.php index 55ceeb59d1d..849fb8a7e12 100644 --- a/tests/Version4/Orders.php +++ b/unit-tests/Tests/Version4/Orders.php @@ -5,11 +5,14 @@ * @package WooCommerce/RestApi/Tests */ -namespace WooCommerce\RestApi\Tests\Version4; +namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Tests\AbstractRestApiTest; +use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; /** * Abstract Rest API Test Class @@ -83,7 +86,7 @@ class Orders extends AbstractRestApiTest { * Test create. */ public function test_create() { - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $data = [ 'currency' => 'ZAR', 'customer_id' => 1, @@ -140,7 +143,7 @@ class Orders extends AbstractRestApiTest { * @since 3.5.2 */ public function test_create_update_order_payment_method_title_sanitize() { - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $data = [ 'payment_method' => 'bacs', 'payment_method_title' => '

Sanitize this

', @@ -206,7 +209,7 @@ class Orders extends AbstractRestApiTest { * @since 3.5.0 */ public function test_create_order_invalid_fields() { - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $data = [ 'payment_method' => 'bacs', 'payment_method_title' => 'Direct Bank Transfer', @@ -256,17 +259,17 @@ class Orders extends AbstractRestApiTest { * Test read. */ public function test_read() { - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $product->set_regular_price( 10.95 ); $product->set_sale_price( false ); $product->save(); - $customer = \WC_Helper_Customer::create_customer(); + $customer = CustomerHelper::create_customer(); $orders = []; - $orders[] = \WC_Helper_Order::create_order( $customer->get_id(), $product ); + $orders[] = OrderHelper::create_order( $customer->get_id(), $product ); // Create orders. for ( $i = 0; $i < 9; $i++ ) { - $orders[] = \WC_Helper_Order::create_order( $this->user ); + $orders[] = OrderHelper::create_order( $this->user ); } $orders[5]->set_status( 'on-hold' ); @@ -326,7 +329,7 @@ class Orders extends AbstractRestApiTest { $this->assertExpectedResponse( $response, 404 ); // Update existing. - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $data = [ 'payment_method' => 'test-update', 'billing' => array( @@ -355,13 +358,13 @@ class Orders extends AbstractRestApiTest { $this->assertEquals( 404, $result->status ); // Trash. - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $result = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => false ] ); $this->assertEquals( 200, $result->status ); $this->assertEquals( 'trash', get_post_status( $order->get_id() ) ); // Force. - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $result = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => true ] ); $this->assertEquals( 200, $result->status ); $this->assertEquals( false, get_post( $order->get_id() ) ); @@ -372,7 +375,7 @@ class Orders extends AbstractRestApiTest { */ public function test_guest_create() { wp_set_current_user( 0 ); - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $data = [ 'currency' => 'ZAR', 'customer_id' => 1, @@ -437,7 +440,7 @@ class Orders extends AbstractRestApiTest { */ public function test_guest_update() { wp_set_current_user( 0 ); - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $data = [ 'payment_method' => 'test-update', 'billing' => array( @@ -458,7 +461,7 @@ class Orders extends AbstractRestApiTest { */ public function test_guest_delete() { wp_set_current_user( 0 ); - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $response = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => true ] ); $this->assertEquals( 401, $response->status ); } @@ -467,7 +470,7 @@ class Orders extends AbstractRestApiTest { * Test validation. */ public function test_enums() { - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $response = $this->do_request( '/wc/v4/orders/' . $order->get_id(), @@ -494,9 +497,9 @@ class Orders extends AbstractRestApiTest { * Test a batch update. */ public function test_batch() { - $order1 = \WC_Helper_Order::create_order(); - $order2 = \WC_Helper_Order::create_order(); - $order3 = \WC_Helper_Order::create_order(); + $order1 = OrderHelper::create_order(); + $order2 = OrderHelper::create_order(); + $order3 = OrderHelper::create_order(); $result = $this->do_request( '/wc/v4/orders/batch', @@ -528,7 +531,7 @@ class Orders extends AbstractRestApiTest { * @since 3.5.0 */ public function test_update_order_remove_items() { - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $fee = new \WC_Order_Item_Fee(); $fee->set_props( array( @@ -564,9 +567,9 @@ class Orders extends AbstractRestApiTest { * @since 3.5.0 */ public function test_update_order_add_coupons() { - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = \WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); @@ -592,9 +595,9 @@ class Orders extends AbstractRestApiTest { * @since 3.5.0 */ public function test_update_order_remove_coupons() { - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = \WC_Helper_Coupon::create_coupon( 'fake-coupon' ); + $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); $order->apply_coupon( $coupon ); @@ -634,7 +637,7 @@ class Orders extends AbstractRestApiTest { * @since 3.5.0 */ public function test_invalid_coupon() { - $order = \WC_Helper_Order::create_order(); + $order = OrderHelper::create_order(); $response = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'PUT', diff --git a/unit-tests/Tests/Version4/PaymentGateways.php b/unit-tests/Tests/Version4/PaymentGateways.php new file mode 100644 index 00000000000..c3a01700918 --- /dev/null +++ b/unit-tests/Tests/Version4/PaymentGateways.php @@ -0,0 +1,352 @@ +endpoint = new WC_REST_Payment_Gateways_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v4/payment_gateways', $routes ); + $this->assertArrayHasKey( '/wc/v4/payment_gateways/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all payment gateways. + * + * @since 3.5.0 + */ + public function test_get_payment_gateways() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways' ) ); + $gateways = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( + array( + 'id' => 'cheque', + 'title' => 'Check payments', + 'description' => 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', + 'order' => '', + 'enabled' => false, + 'method_title' => 'Check payments', + 'method_description' => 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', + 'method_supports' => array( + 'products', + ), + 'settings' => array_diff_key( + $this->get_settings( 'WC_Gateway_Cheque' ), + array( + 'enabled' => false, + 'description' => false, + ) + ), + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/payment_gateways/cheque' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/payment_gateways' ), + ), + ), + ), + ), + $gateways + ); + } + + /** + * Tests to make sure payment gateways cannot viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_payment_gateways_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single payment gateway. + * + * @since 3.5.0 + */ + public function test_get_payment_gateway() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/paypal' ) ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => 'paypal', + 'title' => 'PayPal', + 'description' => "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account.", + 'order' => '', + 'enabled' => false, + 'method_title' => 'PayPal', + 'method_description' => 'PayPal Standard redirects customers to PayPal to enter their payment information.', + 'method_supports' => array( + 'products', + 'refunds', + ), + 'settings' => array_diff_key( + $this->get_settings( 'WC_Gateway_Paypal' ), + array( + 'enabled' => false, + 'description' => false, + ) + ), + ), + $paypal + ); + } + + /** + * Test getting a payment gateway without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_payment_gateway_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/paypal' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a payment gateway with an invalid id. + * + * @since 3.5.0 + */ + public function test_get_payment_gateway_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/totally_fake_method' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a single payment gateway. + * + * @since 3.5.0 + */ + public function test_update_payment_gateway() { + wp_set_current_user( $this->user ); + + // Test defaults + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/paypal' ) ); + $paypal = $response->get_data(); + + $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'admin@example.org', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); + + // test updating single setting + $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'email' => 'woo@woo.local', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); + + // test updating multiple settings + $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'testmode' => 'yes', + 'title' => 'PayPal - New Title', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); + + // Test other parameters, and recheck settings + $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + + $this->assertFalse( $paypal['enabled'] ); + $this->assertEquals( 2, $paypal['order'] ); + $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); + $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); + $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); + + // test bogus + $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'paymentaction' => 'afasfasf', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'paymentaction' => 'authorization', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $paypal = $response->get_data(); + $this->assertEquals( 'authorization', $paypal['settings']['paymentaction']['value'] ); + } + + /** + * Test updating a payment gateway without valid permissions. + * + * @since 3.5.0 + */ + public function test_update_payment_gateway_without_permission() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); + $request->set_body_params( + array( + 'settings' => array( + 'testmode' => 'yes', + 'title' => 'PayPal - New Title', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a payment gateway with an invalid id. + * + * @since 3.5.0 + */ + public function test_update_payment_gateway_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/totally_fake_method' ); + $request->set_body_params( + array( + 'enabled' => true, + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test the payment gateway schema. + * + * @since 3.5.0 + */ + public function test_payment_gateway_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/payment_gateways' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 9, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'title', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'order', $properties ); + $this->assertArrayHasKey( 'enabled', $properties ); + $this->assertArrayHasKey( 'method_title', $properties ); + $this->assertArrayHasKey( 'method_description', $properties ); + $this->assertArrayHasKey( 'method_supports', $properties ); + $this->assertArrayHasKey( 'settings', $properties ); + } + + /** + * Loads a particular gateway's settings so we can correctly test API output. + * + * @since 3.5.0 + * @param string $gateway_class Name of WC_Payment_Gateway class. + */ + private function get_settings( $gateway_class ) { + $gateway = new $gateway_class(); + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + // Ignore 'enabled' and 'description', to be in line with \WC_REST_Payment_Gateways_Controller::get_settings. + if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { + continue; + } + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + +} diff --git a/tests/Version4/ProductReviews.php b/unit-tests/Tests/Version4/ProductReviews.php similarity index 86% rename from tests/Version4/ProductReviews.php rename to unit-tests/Tests/Version4/ProductReviews.php index f0548796fb1..f45203d5aad 100644 --- a/tests/Version4/ProductReviews.php +++ b/unit-tests/Tests/Version4/ProductReviews.php @@ -5,11 +5,12 @@ * @package WooCommerce/RestApi/Tests */ -namespace WooCommerce\RestApi\Tests\Version4; +namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Tests\AbstractRestApiTest; +use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; /** * Abstract Rest API Test Class @@ -52,7 +53,7 @@ class ProductReviews extends AbstractRestApiTest { * If read-only, test to confirm this. */ public function test_create() { - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $data = [ 'review' => 'Hello world.', 'reviewer' => 'Admin', @@ -84,9 +85,9 @@ class ProductReviews extends AbstractRestApiTest { * Test get/read using this method. */ public function test_read() { - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); for ( $i = 0; $i < 10; $i++ ) { - $review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $review_id = ProductHelper::create_product_review( $product->get_id() ); } // Invalid. @@ -140,8 +141,8 @@ class ProductReviews extends AbstractRestApiTest { * If read-only, test to confirm this. */ public function test_update() { - $product = \WC_Helper_Product::create_simple_product(); - $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $product = ProductHelper::create_simple_product(); + $product_review_id = ProductHelper::create_product_review( $product->get_id() ); $response = $this->do_request( '/wc/v4/products/reviews/' . $product_review_id ); $this->assertEquals( 200, $response->status ); @@ -175,8 +176,8 @@ class ProductReviews extends AbstractRestApiTest { $this->assertEquals( 404, $result->status ); // Valid. - $product = \WC_Helper_Product::create_simple_product(); - $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $product = ProductHelper::create_simple_product(); + $product_review_id = ProductHelper::create_product_review( $product->get_id() ); $result = $this->do_request( '/wc/v4/products/reviews/' . $product_review_id, 'DELETE', [ 'force' => true ] ); $this->assertEquals( 200, $result->status ); } @@ -196,8 +197,8 @@ class ProductReviews extends AbstractRestApiTest { * @since 3.5.0 */ public function test_get_product_review() { - $product = \WC_Helper_Product::create_simple_product(); - $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $product = ProductHelper::create_simple_product(); + $product_review_id = ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v4/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -227,7 +228,7 @@ class ProductReviews extends AbstractRestApiTest { * @since 3.5.0 */ public function test_get_product_review_invalid_id() { - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v4/products/reviews/0' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -238,7 +239,7 @@ class ProductReviews extends AbstractRestApiTest { * @since 3.5.0 */ public function test_create_product_review_invalid_fields() { - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); // missing review $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews' ); @@ -287,8 +288,8 @@ class ProductReviews extends AbstractRestApiTest { */ public function test_update_product_review_without_permission() { wp_set_current_user( 0 ); - $product = \WC_Helper_Product::create_simple_product(); - $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $product = ProductHelper::create_simple_product(); + $product_review_id = ProductHelper::create_product_review( $product->get_id() ); $request = new \WP_REST_Request( 'PUT', '/wc/v4/products/reviews/' . $product_review_id ); $request->set_body_params( @@ -311,7 +312,7 @@ class ProductReviews extends AbstractRestApiTest { */ public function test_update_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); $request = new \WP_REST_Request( 'PUT', '/wc/v4/products/reviews/0' ); $request->set_body_params( @@ -334,8 +335,8 @@ class ProductReviews extends AbstractRestApiTest { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = \WC_Helper_Product::create_simple_product(); - $product_review_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $product = ProductHelper::create_simple_product(); + $product_review_id = ProductHelper::create_product_review( $product->get_id() ); $request = new \WP_REST_Request( 'DELETE', '/wc/v4/products/reviews/' . $product_review_id ); $response = $this->server->dispatch( $request ); @@ -350,12 +351,12 @@ class ProductReviews extends AbstractRestApiTest { */ public function test_product_reviews_batch() { wp_set_current_user( $this->user ); - $product = \WC_Helper_Product::create_simple_product(); + $product = ProductHelper::create_simple_product(); - $review_1_id = \WC_Helper_Product::create_product_review( $product->get_id() ); - $review_2_id = \WC_Helper_Product::create_product_review( $product->get_id() ); - $review_3_id = \WC_Helper_Product::create_product_review( $product->get_id() ); - $review_4_id = \WC_Helper_Product::create_product_review( $product->get_id() ); + $review_1_id = ProductHelper::create_product_review( $product->get_id() ); + $review_2_id = ProductHelper::create_product_review( $product->get_id() ); + $review_3_id = ProductHelper::create_product_review( $product->get_id() ); + $review_4_id = ProductHelper::create_product_review( $product->get_id() ); $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews/batch' ); $request->set_body_params( diff --git a/unit-tests/Tests/Version4/ProductVariations.php b/unit-tests/Tests/Version4/ProductVariations.php new file mode 100644 index 00000000000..d2ebff95dcc --- /dev/null +++ b/unit-tests/Tests/Version4/ProductVariations.php @@ -0,0 +1,480 @@ +endpoint = new WC_REST_Product_Variations_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v4/products/(?P[\d]+)/variations', $routes ); + $this->assertArrayHasKey( '/wc/v4/products/(?P[\d]+)/variations/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v4/products/(?P[\d]+)/variations/batch', $routes ); + } + + /** + * Test getting variations. + * + * @since 3.5.0 + */ + public function test_get_variations() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $variations ) ); + $this->assertEquals( 'DUMMY SKU VARIABLE LARGE', $variations[0]['sku'] ); + $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); + } + + /** + * Test getting variations without permission. + * + * @since 3.5.0 + */ + public function test_get_variations_without_permission() { + wp_set_current_user( 0 ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting a single variation. + * + * @since 3.5.0 + */ + public function test_get_variation() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $variation_id, $variation['id'] ); + $this->assertEquals( 'size', $variation['attributes'][0]['name'] ); + } + + /** + * Test getting single variation without permission. + * + * @since 3.5.0 + */ + public function test_get_variation_without_permission() { + wp_set_current_user( 0 ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single variation. + * + * @since 3.5.0 + */ + public function test_delete_variation() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 1, count( $variations ) ); + } + + /** + * Test deleting a single variation without permission. + * + * @since 3.5.0 + */ + public function test_delete_variation_without_permission() { + wp_set_current_user( 0 ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a single variation with an invalid ID. + * + * @since 3.5.0 + */ + public function test_delete_variation_with_invalid_id() { + wp_set_current_user( 0 ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() . '/variations/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test editing a single variation. + * + * @since 3.5.0 + */ + public function test_update_variation() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ) ); + $variation = $response->get_data(); + + $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variation['sku'] ); + $this->assertEquals( 10, $variation['regular_price'] ); + $this->assertEmpty( $variation['sale_price'] ); + $this->assertEquals( 'small', $variation['attributes'][0]['option'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'sku' => 'FIXED-\'SKU', + 'sale_price' => '8', + 'description' => 'O_O', + 'image' => array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertTrue( isset( $variation['description'] ), print_r( $variation, true ) ); + $this->assertContains( 'O_O', $variation['description'], print_r( $variation, true ) ); + $this->assertEquals( '8', $variation['price'], print_r( $variation, true ) ); + $this->assertEquals( '8', $variation['sale_price'], print_r( $variation, true ) ); + $this->assertEquals( '10', $variation['regular_price'], print_r( $variation, true ) ); + $this->assertEquals( 'FIXED-\'SKU', $variation['sku'], print_r( $variation, true ) ); + $this->assertEquals( 'medium', $variation['attributes'][0]['option'], print_r( $variation, true ) ); + $this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'], print_r( $variation, true ) ); + $this->assertContains( 'test upload image', $variation['image']['alt'], print_r( $variation, true ) ); + } + + /** + * Test updating a single variation without permission. + * + * @since 3.5.0 + */ + public function test_update_variation_without_permission() { + wp_set_current_user( 0 ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $children = $product->get_children(); + $variation_id = $children[0]; + + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single variation with an invalid ID. + * + * @since 3.5.0 + */ + public function test_update_variation_with_invalid_id() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/0' ); + $request->set_body_params( + array( + 'sku' => 'FIXED-SKU-NO-PERMISSION', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Test creating a single variation. + * + * @since 3.5.0 + */ + public function test_create_variation() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 2, count( $variations ) ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/products/' . $product->get_id() . '/variations' ); + $request->set_body_params( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertContains( 'A medium size.', $variation['description'] ); + $this->assertEquals( '12', $variation['price'] ); + $this->assertEquals( '12', $variation['regular_price'] ); + $this->assertTrue( $variation['purchasable'] ); + $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $variation['sku'] ); + $this->assertEquals( 'medium', $variation['attributes'][0]['option'] ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); + $variations = $response->get_data(); + $this->assertEquals( 3, count( $variations ) ); + } + + /** + * Test creating a single variation without permission. + * + * @since 3.5.0 + */ + public function test_create_variation_without_permission() { + wp_set_current_user( 0 ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + + $request = new WP_REST_Request( 'POST', '/wc/v4/products/' . $product->get_id() . '/variations' ); + $request->set_body_params( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test batch managing product variations. + * + * @since 3.5.0 + */ + public function test_product_variations_batch() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $children = $product->get_children(); + $request = new WP_REST_Request( 'POST', '/wc/v4/products/' . $product->get_id() . '/variations/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => $children[0], + 'description' => 'Updated description.', + 'image' => array( + 'position' => 0, + 'src' => 'http://cldup.com/Dr1Bczxq4q.png', + 'alt' => 'test upload image', + ), + ), + ), + 'delete' => array( + $children[1], + ), + 'create' => array( + array( + 'sku' => 'DUMMY SKU VARIABLE MEDIUM', + 'regular_price' => '12', + 'description' => 'A medium size.', + 'attributes' => array( + array( + 'name' => 'pa_size', + 'option' => 'medium', + ), + ), + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); + $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $data['create'][0]['sku'] ); + $this->assertEquals( 'medium', $data['create'][0]['attributes'][0]['option'] ); + $this->assertEquals( $children[1], $data['delete'][0]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 2, count( $data ) ); + } + + /** + * Test variation schema. + * + * @since 3.5.0 + */ + public function test_variation_schema() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() . '/variations' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 37, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'date_modified', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'permalink', $properties ); + $this->assertArrayHasKey( 'sku', $properties ); + $this->assertArrayHasKey( 'price', $properties ); + $this->assertArrayHasKey( 'regular_price', $properties ); + $this->assertArrayHasKey( 'sale_price', $properties ); + $this->assertArrayHasKey( 'date_on_sale_from', $properties ); + $this->assertArrayHasKey( 'date_on_sale_to', $properties ); + $this->assertArrayHasKey( 'on_sale', $properties ); + $this->assertArrayHasKey( 'purchasable', $properties ); + $this->assertArrayHasKey( 'virtual', $properties ); + $this->assertArrayHasKey( 'downloadable', $properties ); + $this->assertArrayHasKey( 'downloads', $properties ); + $this->assertArrayHasKey( 'download_limit', $properties ); + $this->assertArrayHasKey( 'download_expiry', $properties ); + $this->assertArrayHasKey( 'tax_status', $properties ); + $this->assertArrayHasKey( 'tax_class', $properties ); + $this->assertArrayHasKey( 'manage_stock', $properties ); + $this->assertArrayHasKey( 'stock_quantity', $properties ); + $this->assertArrayHasKey( 'stock_status', $properties ); + $this->assertArrayHasKey( 'backorders', $properties ); + $this->assertArrayHasKey( 'backorders_allowed', $properties ); + $this->assertArrayHasKey( 'backordered', $properties ); + $this->assertArrayHasKey( 'weight', $properties ); + $this->assertArrayHasKey( 'dimensions', $properties ); + $this->assertArrayHasKey( 'shipping_class', $properties ); + $this->assertArrayHasKey( 'shipping_class_id', $properties ); + $this->assertArrayHasKey( 'image', $properties ); + $this->assertArrayHasKey( 'attributes', $properties ); + $this->assertArrayHasKey( 'menu_order', $properties ); + $this->assertArrayHasKey( 'meta_data', $properties ); + } + + /** + * Test updating a variation stock. + * + * @since 3.5.0 + */ + public function test_update_variation_manage_stock() { + wp_set_current_user( $this->user ); + + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product->set_manage_stock( false ); + $product->save(); + + $children = $product->get_children(); + $variation_id = $children[0]; + + // Set stock to true. + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => true, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( true, $variation['manage_stock'] ); + + // Set stock to false. + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => false, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( false, $variation['manage_stock'] ); + + // Set stock to false but parent is managing stock. + $product->set_manage_stock( true ); + $product->save(); + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); + $request->set_body_params( + array( + 'manage_stock' => false, + ) + ); + + $response = $this->server->dispatch( $request ); + $variation = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'parent', $variation['manage_stock'] ); + } +} diff --git a/tests/Version4/products.php b/unit-tests/Tests/Version4/Products.php similarity index 86% rename from tests/Version4/products.php rename to unit-tests/Tests/Version4/Products.php index 9d0d30f56d0..b0886febfa5 100644 --- a/tests/Version4/products.php +++ b/unit-tests/Tests/Version4/Products.php @@ -1,62 +1,45 @@ endpoint = new WC_REST_Products_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. * - * @var array + * @since 3.5.0 */ - protected $routes = [ - '/wc/v4/products', - '/wc/v4/products/(?P[\d]+)', - '/wc/v4/products/batch', - ]; - - /** - * Test creation using this method. - * If read-only, test to confirm this. - */ - public function test_create() { - - } - - /** - * Test get/read using this method. - */ - public function test_read() { - - } - - /** - * Test updates using this method. - * If read-only, test to confirm this. - */ - public function test_update() { - - } - - /** - * Test delete using this method. - * If read-only, test to confirm this. - */ - public function test_delete() { - + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v4/products', $routes ); + $this->assertArrayHasKey( '/wc/v4/products/(?P[\d]+)', $routes ); + $this->assertArrayHasKey( '/wc/v4/products/batch', $routes ); } /** @@ -66,9 +49,9 @@ class Products extends AbstractRestApiTest { */ public function test_get_products() { wp_set_current_user( $this->user ); - WC_Helper_Product::create_external_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); sleep( 1 ); // So both products have different timestamps. - WC_Helper_Product::create_simple_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); $products = $response->get_data(); @@ -88,7 +71,7 @@ class Products extends AbstractRestApiTest { */ public function test_get_products_without_permission() { wp_set_current_user( 0 ); - WC_Helper_Product::create_simple_product(); + \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -100,7 +83,7 @@ class Products extends AbstractRestApiTest { */ public function test_get_product() { wp_set_current_user( $this->user ); - $simple = WC_Helper_Product::create_external_product(); + $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $simple->get_id() ) ); $product = $response->get_data(); @@ -125,7 +108,7 @@ class Products extends AbstractRestApiTest { */ public function test_get_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -137,7 +120,7 @@ class Products extends AbstractRestApiTest { */ public function test_delete_product() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() ); $request->set_param( 'force', true ); @@ -156,7 +139,7 @@ class Products extends AbstractRestApiTest { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -185,7 +168,7 @@ class Products extends AbstractRestApiTest { wp_set_current_user( $this->user ); // test simple products. - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); $data = $response->get_data(); $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); @@ -224,7 +207,7 @@ class Products extends AbstractRestApiTest { $product->delete( true ); // test variable product (variations are tested in product-variations.php). - $product = WC_Helper_Product::create_variation_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -270,7 +253,7 @@ class Products extends AbstractRestApiTest { $product->delete( true ); // test external product. - $product = WC_Helper_Product::create_external_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -298,7 +281,7 @@ class Products extends AbstractRestApiTest { */ public function test_update_product_without_permission() { wp_set_current_user( 0 ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); $request->set_body_params( array( @@ -450,8 +433,8 @@ class Products extends AbstractRestApiTest { */ public function test_products_batch() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); - $product_2 = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v4/products/batch' ); $request->set_body_params( array( @@ -508,7 +491,7 @@ class Products extends AbstractRestApiTest { public function test_products_filter_post_status() { wp_set_current_user( $this->user ); for ( $i = 0; $i < 8; $i++ ) { - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); if ( 0 === $i % 2 ) { wp_update_post( array( @@ -549,6 +532,21 @@ class Products extends AbstractRestApiTest { $this->assertEquals( 8, count( $products ) ); } + /** + * Test product schema. + * + * @since 3.5.0 + */ + public function test_product_schema() { + wp_set_current_user( $this->user ); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 65, count( $properties ) ); + } + /** * Test product category. * @@ -602,10 +600,10 @@ class Products extends AbstractRestApiTest { public function test_get_products_by_type() { wp_set_current_user( $this->user ); - $simple = WC_Helper_Product::create_simple_product(); - $external = WC_Helper_Product::create_external_product(); - $grouped = WC_Helper_Product::create_grouped_product(); - $variable = WC_Helper_Product::create_variation_product(); + $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $external = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $grouped = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_grouped_product(); + $variable = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $product_ids_for_type = array( 'simple' => array( $simple->get_id() ), @@ -644,12 +642,12 @@ class Products extends AbstractRestApiTest { wp_set_current_user( $this->user ); // Create a featured product. - $feat_product = WC_Helper_Product::create_simple_product(); + $feat_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $feat_product->set_featured( true ); $feat_product->save(); // Create a non-featured product. - $nonfeat_product = WC_Helper_Product::create_simple_product(); + $nonfeat_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $nonfeat_product->save(); $query_params = array( @@ -718,12 +716,12 @@ class Products extends AbstractRestApiTest { $test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' ); // Product with a tag. - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $product->set_tag_ids( array( $test_tag_1['term_id'] ) ); $product->save(); // Product without a tag. - $product_2 = WC_Helper_Product::create_simple_product(); + $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $query_params = array( 'tag' => (string) $test_tag_1['term_id'], @@ -749,17 +747,17 @@ class Products extends AbstractRestApiTest { wp_set_current_user( $this->user ); // Variable product with 2 different variations. - $variable_product = WC_Helper_Product::create_variation_product(); + $variable_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); // Terms created by variable product. $term_large = get_term_by( 'slug', 'large', 'pa_size' ); $term_small = get_term_by( 'slug', 'small', 'pa_size' ); // Simple product without attribute. - $product_1 = WC_Helper_Product::create_simple_product(); + $product_1 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Simple product with attribute size = large. - $product_2 = WC_Helper_Product::create_simple_product(); + $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $product_2->set_attributes( array( 'pa_size' => 'large' ) ); $product_2->save(); @@ -816,9 +814,9 @@ class Products extends AbstractRestApiTest { /** * Test product schema contains embed fields. */ - public function test_product_schema() { + public function test_product_schema_embed() { wp_set_current_user( $this->user ); - $product = WC_Helper_Product::create_simple_product(); + $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/Version4/Reports/reports-categories.php b/unit-tests/Tests/Version4/Reports/Categories.php similarity index 88% rename from tests/Version4/Reports/reports-categories.php rename to unit-tests/Tests/Version4/Reports/Categories.php index f1a72528768..99f48c69212 100644 --- a/tests/Version4/Reports/reports-categories.php +++ b/unit-tests/Tests/Version4/Reports/Categories.php @@ -6,10 +6,20 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** - * Class WC_Tests_API_Reports_Categories + * Class Categories */ -class WC_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case { +class Categories extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -50,7 +60,7 @@ class WC_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); wp_set_current_user( $this->user ); // Populate all of the data. @@ -59,12 +69,12 @@ class WC_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case { $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' ); @@ -90,7 +100,7 @@ class WC_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports_categories_param() { - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); wp_set_current_user( $this->user ); // Populate all of the data. @@ -99,7 +109,7 @@ class WC_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case { $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); @@ -112,7 +122,7 @@ class WC_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case { $product->set_category_ids( array( $second_category_id ) ); $product->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' ); diff --git a/tests/Version4/Reports/reports-coupons.php b/unit-tests/Tests/Version4/Reports/Coupons.php similarity index 82% rename from tests/Version4/Reports/reports-coupons.php rename to unit-tests/Tests/Version4/Reports/Coupons.php index 5e9ee2675d1..16cd2cb728e 100644 --- a/tests/Version4/Reports/reports-coupons.php +++ b/unit-tests/Tests/Version4/Reports/Coupons.php @@ -5,10 +5,21 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** - * Class WC_Tests_API_Reports_Coupons + * Class Coupons */ -class WC_Tests_API_Reports_Coupons extends WC_REST_Unit_Test_Case { +class Coupons extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -44,7 +55,7 @@ class WC_Tests_API_Reports_Coupons extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Simple product. $product = new WC_Product_Simple(); @@ -54,35 +65,35 @@ class WC_Tests_API_Reports_Coupons extends WC_REST_Unit_Test_Case { // Coupons. $coupon_1_amount = 1; // by default in create_coupon. - $coupon_1 = WC_Helper_Coupon::create_coupon( 'coupon_1' ); + $coupon_1 = CouponHelper::create_coupon( 'coupon_1' ); $coupon_2_amount = 2; - $coupon_2 = WC_Helper_Coupon::create_coupon( 'coupon_2' ); + $coupon_2 = CouponHelper::create_coupon( 'coupon_2' ); $coupon_2->set_amount( $coupon_2_amount ); $coupon_2->save(); // Order without coupon. - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); // Order with 1 coupon. - $order_1c = WC_Helper_Order::create_order( 1, $product ); + $order_1c = OrderHelper::create_order( 1, $product ); $order_1c->set_status( 'completed' ); $order_1c->apply_coupon( $coupon_1 ); $order_1c->calculate_totals(); $order_1c->save(); // Order with 2 coupons. - $order_2c = WC_Helper_Order::create_order( 1, $product ); + $order_2c = OrderHelper::create_order( 1, $product ); $order_2c->set_status( 'completed' ); $order_2c->apply_coupon( $coupon_1 ); $order_2c->apply_coupon( $coupon_2 ); $order_2c->calculate_totals(); $order_2c->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $coupon_reports = $response->get_data(); @@ -108,7 +119,7 @@ class WC_Tests_API_Reports_Coupons extends WC_REST_Unit_Test_Case { */ public function test_get_reports_coupons_param() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Simple product. $product = new WC_Product_Simple(); @@ -118,21 +129,21 @@ class WC_Tests_API_Reports_Coupons extends WC_REST_Unit_Test_Case { // Coupons. $coupon_1_amount = 1; // by default in create_coupon. - $coupon_1 = WC_Helper_Coupon::create_coupon( 'coupon_1' ); + $coupon_1 = CouponHelper::create_coupon( 'coupon_1' ); $coupon_2_amount = 2; - $coupon_2 = WC_Helper_Coupon::create_coupon( 'coupon_2' ); + $coupon_2 = CouponHelper::create_coupon( 'coupon_2' ); $coupon_2->set_amount( $coupon_2_amount ); $coupon_2->save(); // Order with 1 coupon. - $order_1c = WC_Helper_Order::create_order( 1, $product ); + $order_1c = OrderHelper::create_order( 1, $product ); $order_1c->set_status( 'completed' ); $order_1c->apply_coupon( $coupon_1 ); $order_1c->calculate_totals(); $order_1c->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( diff --git a/tests/Version4/Reports/reports-coupons-stats.php b/unit-tests/Tests/Version4/Reports/CouponsStats.php similarity index 85% rename from tests/Version4/Reports/reports-coupons-stats.php rename to unit-tests/Tests/Version4/Reports/CouponsStats.php index a17f10a37db..981c481d7b0 100644 --- a/tests/Version4/Reports/reports-coupons-stats.php +++ b/unit-tests/Tests/Version4/Reports/CouponsStats.php @@ -5,10 +5,21 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** - * Class WC_Tests_API_Reports_Coupons_Stats + * Class CouponsStats */ -class WC_Tests_API_Reports_Coupons_Stats extends WC_REST_Unit_Test_Case { +class CouponsStats extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -43,7 +54,7 @@ class WC_Tests_API_Reports_Coupons_Stats extends WC_REST_Unit_Test_Case { * Test getting reports. */ public function test_get_reports() { - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); wp_set_current_user( $this->user ); // Populate all of the data. @@ -55,15 +66,15 @@ class WC_Tests_API_Reports_Coupons_Stats extends WC_REST_Unit_Test_Case { // Coupons. $coupon_1_amount = 1; // by default in create_coupon. - $coupon_1 = WC_Helper_Coupon::create_coupon( 'coupon_1' ); + $coupon_1 = CouponHelper::create_coupon( 'coupon_1' ); $coupon_2_amount = 2; - $coupon_2 = WC_Helper_Coupon::create_coupon( 'coupon_2' ); + $coupon_2 = CouponHelper::create_coupon( 'coupon_2' ); $coupon_2->set_amount( $coupon_2_amount ); $coupon_2->save(); // Order without coupon. - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); @@ -71,7 +82,7 @@ class WC_Tests_API_Reports_Coupons_Stats extends WC_REST_Unit_Test_Case { $time = time(); // Order with 1 coupon. - $order_1c = WC_Helper_Order::create_order( 1, $product ); + $order_1c = OrderHelper::create_order( 1, $product ); $order_1c->set_status( 'completed' ); $order_1c->apply_coupon( $coupon_1 ); $order_1c->calculate_totals(); @@ -79,7 +90,7 @@ class WC_Tests_API_Reports_Coupons_Stats extends WC_REST_Unit_Test_Case { $order_1c->save(); // Order with 2 coupons. - $order_2c = WC_Helper_Order::create_order( 1, $product ); + $order_2c = OrderHelper::create_order( 1, $product ); $order_2c->set_status( 'completed' ); $order_2c->apply_coupon( $coupon_1 ); $order_2c->apply_coupon( $coupon_2 ); @@ -87,7 +98,7 @@ class WC_Tests_API_Reports_Coupons_Stats extends WC_REST_Unit_Test_Case { $order_2c->set_date_created( $time ); $order_2c->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( diff --git a/tests/Version4/Reports/reports-customers-stats.php b/unit-tests/Tests/Version4/Reports/CustomerStats.php similarity index 82% rename from tests/Version4/Reports/reports-customers-stats.php rename to unit-tests/Tests/Version4/Reports/CustomerStats.php index e31805ce5b4..27dfc5d4030 100644 --- a/tests/Version4/Reports/reports-customers-stats.php +++ b/unit-tests/Tests/Version4/Reports/CustomerStats.php @@ -6,13 +6,24 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; + /** * Reports Customers Stats REST API Test Class * * @package WooCommerce\Tests\API * @since 3.5.0 */ -class WC_Tests_API_Reports_Customers_Stats extends WC_REST_Unit_Test_Case { +class CustomerStats extends WC_REST_Unit_Test_Case { /** * Endpoint. * @@ -86,13 +97,13 @@ class WC_Tests_API_Reports_Customers_Stats extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); $test_customers = array(); // Create 10 test customers. for ( $i = 1; $i <= 10; $i++ ) { - $test_customers[] = WC_Helper_Customer::create_customer( "customer{$i}", 'password', "customer{$i}@example.com" ); + $test_customers[] = CustomerHelper::create_customer( "customer{$i}", 'password', "customer{$i}@example.com" ); } // One differing name. $test_customers[2]->set_first_name( 'Jeff' ); @@ -105,27 +116,27 @@ class WC_Tests_API_Reports_Customers_Stats extends WC_REST_Unit_Test_Case { $product->save(); // Place some test orders. - $order = WC_Helper_Order::create_order( $test_customers[0]->get_id(), $product ); + $order = OrderHelper::create_order( $test_customers[0]->get_id(), $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); $order->save(); - $order = WC_Helper_Order::create_order( $test_customers[0]->get_id(), $product ); + $order = OrderHelper::create_order( $test_customers[0]->get_id(), $product ); $order->set_status( 'completed' ); $order->set_total( 234 ); $order->save(); - $order = WC_Helper_Order::create_order( $test_customers[1]->get_id(), $product ); + $order = OrderHelper::create_order( $test_customers[1]->get_id(), $product ); $order->set_status( 'completed' ); $order->set_total( 55 ); $order->save(); - $order = WC_Helper_Order::create_order( $test_customers[2]->get_id(), $product ); + $order = OrderHelper::create_order( $test_customers[2]->get_id(), $product ); $order->set_status( 'completed' ); $order->set_total( 9.12 ); $order->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $response = $this->server->dispatch( $request ); diff --git a/tests/Version4/Reports/reports-customers.php b/unit-tests/Tests/Version4/Reports/Customers.php similarity index 87% rename from tests/Version4/Reports/reports-customers.php rename to unit-tests/Tests/Version4/Reports/Customers.php index 9cc62060cbc..e270855af72 100644 --- a/tests/Version4/Reports/reports-customers.php +++ b/unit-tests/Tests/Version4/Reports/Customers.php @@ -6,13 +6,24 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; + /** * Reports Customers REST API Test Class * * @package WooCommerce\Tests\API * @since 3.5.0 */ -class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { +class Customers extends WC_REST_Unit_Test_Case { /** * Endpoint. * @@ -102,7 +113,7 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_registered_customer_with_bad_user_id() { - $result = WC_Admin_Reports_Customers_Data_Store::update_registered_customer( 2 ); + $result = \WC_Admin_Reports_Customers_Data_Store::update_registered_customer( 2 ); $this->assertFalse( $result ); } @@ -132,17 +143,17 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { $this->assertCount( 0, $reports ); // Creating an order with admin should return the admin. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( $admin_id, $product ); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $admin_id, $product ); $order->set_status( 'processing' ); $order->set_total( 100 ); $order->save(); - WC_Helper_Queue::run_all_pending(); + \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'per_page' => 10 ) ); @@ -155,7 +166,7 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { $this->assertEquals( $admin_id, $reports[0]['user_id'] ); // Creating a customer should show up regardless of orders. - $customer = WC_Helper_Customer::create_customer( 'customer', 'password', 'customer@example.com' ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'customer', 'password', 'customer@example.com' ); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( @@ -184,7 +195,7 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper::reset_stats_dbs(); $test_customers = array(); @@ -194,7 +205,7 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { for ( $i = 1; $i <= 10; $i++ ) { $name = $customer_names[ $i - 1 ]; $email = 'customer+' . strtolower( $name ) . '@example.com'; - $customer = WC_Helper_Customer::create_customer( "customer{$i}", 'password', $email ); + $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( "customer{$i}", 'password', $email ); $customer->set_first_name( $name ); $customer->save(); $test_customers[] = $customer; @@ -207,12 +218,12 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { $product->save(); // Place an order for the first test customer. - $order = WC_Helper_Order::create_order( $test_customers[0]->get_id(), $product ); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $test_customers[0]->get_id(), $product ); $order->set_status( 'processing' ); $order->set_total( 100 ); $order->save(); - WC_Helper_Queue::run_all_pending(); + \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( @@ -342,7 +353,7 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { ); // Test shipping name and empty billing name. - $order = WC_Helper_Order::create_order( $customer ); + $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $customer ); $order->set_billing_first_name( '' ); $order->set_billing_last_name( '' ); $order->set_shipping_first_name( 'Daenerys' ); @@ -351,7 +362,7 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { $order->set_total( 100 ); $order->save(); - WC_Helper_Queue::run_all_pending(); + \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $response = $this->server->dispatch( $request ); @@ -368,7 +379,7 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { $order->save(); do_action( 'woocommerce_update_customer', $customer ); - WC_Helper_Queue::run_all_pending(); + \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'orderby' => 'username' ) ); // Cache busting. @@ -390,7 +401,7 @@ class WC_Tests_API_Reports_Customers extends WC_REST_Unit_Test_Case { ); do_action( 'woocommerce_update_customer', $customer ); - WC_Helper_Queue::run_all_pending(); + \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'orderby' => 'name' ) ); // Cache busting. diff --git a/tests/Version4/Reports/reports-downloads-stats.php b/unit-tests/Tests/Version4/Reports/DownloadStats.php similarity index 87% rename from tests/Version4/Reports/reports-downloads-stats.php rename to unit-tests/Tests/Version4/Reports/DownloadStats.php index 660057b24b0..cbded71f99d 100644 --- a/tests/Version4/Reports/reports-downloads-stats.php +++ b/unit-tests/Tests/Version4/Reports/DownloadStats.php @@ -5,10 +5,22 @@ * @package WooCommerce Admin\Tests\API. */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; + /** - * WC_Tests_API_Reports_Downloads_Stats + * Reports Customers Stats REST API Test Class + * + * @package WooCommerce\Tests\API + * @since 3.5.0 */ -class WC_Tests_API_Reports_Downloads_Stats extends WC_REST_Unit_Test_Case { +class DownloadStats extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -45,33 +57,33 @@ class WC_Tests_API_Reports_Downloads_Stats extends WC_REST_Unit_Test_Case { public function test_get_report() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $prod_download = new WC_Product_Download(); + $prod_download = new \WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); $prod_download->set_id( 1 ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_downloadable( 'yes' ); $product->set_downloads( array( $prod_download ) ); $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); $order->save(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( $this->user ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); $download->set_download_id( $prod_download->get_id() ); $download->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); @@ -131,28 +143,28 @@ class WC_Tests_API_Reports_Downloads_Stats extends WC_REST_Unit_Test_Case { public function test_get_report_with_user_filter() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); $time = time(); // First set of data. - $prod_download = new WC_Product_Download(); + $prod_download = new \WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); $prod_download->set_id( 1 ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_downloadable( 'yes' ); $product->set_downloads( array( $prod_download ) ); $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 25 ); $order->save(); $order_1 = $order->get_id(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( 1 ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); @@ -160,26 +172,26 @@ class WC_Tests_API_Reports_Downloads_Stats extends WC_REST_Unit_Test_Case { $download->save(); for ( $i = 1; $i < 3; $i++ ) { - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( 1 ); $object->set_user_ip_address( '1.2.3.4' ); $id = $object->save(); } - $order = WC_Helper_Order::create_order( 2, $product ); + $order = OrderHelper::create_order( 2, $product ); $order->set_status( 'completed' ); $order->set_total( 10 ); $order->save(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( 2 ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); $download->set_download_id( $prod_download->get_id() ); $download->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( 2 ); $object->set_user_ip_address( '5.4.3.2.1' ); @@ -225,45 +237,45 @@ class WC_Tests_API_Reports_Downloads_Stats extends WC_REST_Unit_Test_Case { public function test_get_report_orderby() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $prod_download = new WC_Product_Download(); + $prod_download = new \WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); $prod_download->set_id( 1 ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_downloadable( 'yes' ); $product->set_downloads( array( $prod_download ) ); $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); $order->save(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( $this->user ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); $download->set_download_id( $prod_download->get_id() ); $download->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); $object->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); $object->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); @@ -271,7 +283,7 @@ class WC_Tests_API_Reports_Downloads_Stats extends WC_REST_Unit_Test_Case { $three_days_from_now = current_time( 'timestamp', true ) - ( 3 * DAY_IN_SECONDS ); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); diff --git a/tests/Version4/Reports/reports-downloads.php b/unit-tests/Tests/Version4/Reports/Downloads.php similarity index 91% rename from tests/Version4/Reports/reports-downloads.php rename to unit-tests/Tests/Version4/Reports/Downloads.php index 8410dd56352..e169a6531bd 100644 --- a/tests/Version4/Reports/reports-downloads.php +++ b/unit-tests/Tests/Version4/Reports/Downloads.php @@ -5,10 +5,22 @@ * @package WooCommerce Admin\Tests\API. */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; + /** - * WC_Tests_API_Reports_Downloads + * Reports Customers Stats REST API Test Class + * + * @package WooCommerce\Tests\API + * @since 3.5.0 */ -class WC_Tests_API_Reports_Downloads extends WC_REST_Unit_Test_Case { +class Downloads extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -45,33 +57,33 @@ class WC_Tests_API_Reports_Downloads extends WC_REST_Unit_Test_Case { public function test_get_report() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $prod_download = new WC_Product_Download(); + $prod_download = new \WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); $prod_download->set_id( 1 ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_downloadable( 'yes' ); $product->set_downloads( array( $prod_download ) ); $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); $order->save(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( $this->user ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); $download->set_download_id( $prod_download->get_id() ); $download->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); @@ -101,15 +113,15 @@ class WC_Tests_API_Reports_Downloads extends WC_REST_Unit_Test_Case { public function filter_setup() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); $time = time(); // First set of data. - $prod_download = new WC_Product_Download(); + $prod_download = new \WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); $prod_download->set_id( 1 ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_downloadable( 'yes' ); $product->set_downloads( array( $prod_download ) ); @@ -117,31 +129,31 @@ class WC_Tests_API_Reports_Downloads extends WC_REST_Unit_Test_Case { $product->save(); $product_1 = $product->get_id(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 25 ); $order->save(); $order_1 = $order->get_id(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( 1 ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); $download->set_download_id( $prod_download->get_id() ); $download->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( 1 ); $object->set_user_ip_address( '1.2.3.4' ); $id = $object->save(); // Second set of data. - $prod_download = new WC_Product_Download(); + $prod_download = new \WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/test.png' ); $prod_download->set_id( 2 ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product 2' ); $product->set_downloadable( 'yes' ); $product->set_downloads( array( $prod_download ) ); @@ -149,20 +161,20 @@ class WC_Tests_API_Reports_Downloads extends WC_REST_Unit_Test_Case { $product->save(); $product_2 = $product->get_id(); - $order = WC_Helper_Order::create_order( 2, $product ); + $order = OrderHelper::create_order( 2, $product ); $order->set_status( 'completed' ); $order->set_total( 10 ); $order->save(); $order_2 = $order->get_id(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( 2 ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); $download->set_download_id( $prod_download->get_id() ); $download->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( 2 ); $object->set_user_ip_address( '5.4.3.2.1' ); diff --git a/tests/Version4/Reports/reports-import.php b/unit-tests/Tests/Version4/Reports/Import.php similarity index 88% rename from tests/Version4/Reports/reports-import.php rename to unit-tests/Tests/Version4/Reports/Import.php index 846ea5e21d8..249f40ef3e2 100644 --- a/tests/Version4/Reports/reports-import.php +++ b/unit-tests/Tests/Version4/Reports/Import.php @@ -5,12 +5,23 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** - * Reports Import REST API Test Class + * Reports Customers Stats REST API Test Class * * @package WooCommerce\Tests\API + * @since 3.5.0 */ -class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { +class Import extends WC_REST_Unit_Test_Case { + /** * Endpoint. * @@ -90,16 +101,16 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); - $order_1 = WC_Helper_Order::create_order( 1, $product ); + $order_1 = OrderHelper::create_order( 1, $product ); $order_1->set_status( 'completed' ); $order_1->set_date_created( time() - ( 3 * DAY_IN_SECONDS ) ); $order_1->save(); - $order_2 = WC_Helper_Order::create_order( 1, $product ); + $order_2 = OrderHelper::create_order( 1, $product ); $order_2->set_total( 100 ); $order_2->set_status( 'completed' ); $order_2->save(); @@ -118,9 +129,9 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { $this->assertEquals( 'success', $report['status'] ); // Run pending thrice to process batch and order. - WC_Helper_Queue::run_all_pending(); - WC_Helper_Queue::run_all_pending(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); $response = $this->server->dispatch( $request ); @@ -163,9 +174,9 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { $this->assertEquals( 'success', $report['status'] ); // Run pending thrice to process batch and order. - WC_Helper_Queue::run_all_pending(); - WC_Helper_Queue::run_all_pending(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); $response = $this->server->dispatch( $request ); @@ -192,18 +203,18 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_date_created( time() - ( 3 * DAY_IN_SECONDS ) ); $order->save(); // Verify there are actions to cancel. - $pending_actions = WC_Helper_Queue::get_all_pending(); + $pending_actions = QueueHelper::get_all_pending(); $this->assertCount( 1, $pending_actions ); // Cancel outstanding actions. @@ -215,7 +226,7 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { $this->assertEquals( 'success', $report['status'] ); // Verify there are no pending actions. - $pending_actions = WC_Helper_Queue::get_all_pending(); + $pending_actions = QueueHelper::get_all_pending(); $this->assertCount( 0, $pending_actions ); } @@ -227,19 +238,19 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); for ( $i = 0; $i < 25; $i++ ) { - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->save(); } // Check that stats exist before deleting. - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); $request->set_query_params( array( 'per_page' => 25 ) ); @@ -266,9 +277,9 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { $this->assertEquals( 'success', $report['status'] ); // Run pending three times to process batches and dependent actions. - WC_Helper_Queue::run_all_pending(); - WC_Helper_Queue::run_all_pending(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); // Check that stats have been deleted. $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); @@ -291,19 +302,19 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { */ public function test_import_status() { // Delete any pending actions that weren't fully run. - WC_Admin_Reports_Sync::clear_queued_actions(); + \WC_Admin_Reports_Sync::clear_queued_actions(); wp_set_current_user( $this->user ); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); // Create 5 completed orders. for ( $i = 0; $i < 5; $i++ ) { - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_date_created( time() - ( ( $i + 1 ) * DAY_IN_SECONDS ) ); $order->save(); @@ -314,7 +325,7 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { $order->save(); // Create 1 draft order - to be excluded from totals. - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_date_created( time() - ( 5 * DAY_IN_SECONDS ) ); $order->save(); wp_update_post( @@ -328,7 +339,7 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { $request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' ); $response = $this->server->dispatch( $request ); $report = $response->get_data(); - $user_query = new WP_User_Query( + $user_query = new \WP_User_Query( array( 'fields' => 'ID', 'number' => 1, @@ -368,9 +379,9 @@ class WC_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case { $this->assertEquals( 4, $report['orders_total'] ); // Run pending thrice to process batch and order. - WC_Helper_Queue::process_pending(); - WC_Helper_Queue::process_pending(); - WC_Helper_Queue::process_pending(); + QueueHelper::process_pending(); + QueueHelper::process_pending(); + QueueHelper::process_pending(); // Test import status after processing. $request = new WP_REST_Request( 'GET', $this->endpoint . '/status' ); diff --git a/tests/Version4/Reports/reports-orders-stats.php b/unit-tests/Tests/Version4/Reports/OrderStats.php similarity index 94% rename from tests/Version4/Reports/reports-orders-stats.php rename to unit-tests/Tests/Version4/Reports/OrderStats.php index 546bef0de67..e929e89307e 100644 --- a/tests/Version4/Reports/reports-orders-stats.php +++ b/unit-tests/Tests/Version4/Reports/OrderStats.php @@ -5,14 +5,17 @@ * @package WooCommerce\Tests\API */ -/** - * WC_Tests_API_Reports_Orders_Stats - */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; /** - * Class WC_Tests_API_Reports_Orders_Stats + * Class OrderStats */ -class WC_Tests_API_Reports_Orders_Stats extends WC_REST_Unit_Test_Case { +class OrderStats extends WC_REST_Unit_Test_Case { /** * Endpoints. diff --git a/tests/Version4/Reports/reports-orders.php b/unit-tests/Tests/Version4/Reports/Orders.php similarity index 84% rename from tests/Version4/Reports/reports-orders.php rename to unit-tests/Tests/Version4/Reports/Orders.php index cf0315a0795..29f32ab1d67 100644 --- a/tests/Version4/Reports/reports-orders.php +++ b/unit-tests/Tests/Version4/Reports/Orders.php @@ -6,13 +6,23 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** * Reports Orders REST API Test Class * * @package WooCommerce\Tests\API * @since 3.5.0 */ -class WC_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case { +class Orders extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -54,7 +64,7 @@ class WC_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. $product = new WC_Product_Simple(); @@ -62,14 +72,14 @@ class WC_Tests_API_Reports_Orders extends WC_REST_Unit_Test_Case { $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); - $expected_customer_id = WC_Admin_Reports_Customers_Data_Store::get_customer_id_by_user_id( 1 ); + $expected_customer_id = \WC_Admin_Reports_Customers_Data_Store::get_customer_id_by_user_id( 1 ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $reports = $response->get_data(); diff --git a/tests/Version4/Reports/reports-performance-indicators.php b/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php similarity index 86% rename from tests/Version4/Reports/reports-performance-indicators.php rename to unit-tests/Tests/Version4/Reports/PerformanceIndicators.php index 487ba3fb9e6..cf2ee62639d 100644 --- a/tests/Version4/Reports/reports-performance-indicators.php +++ b/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php @@ -5,10 +5,20 @@ * @package WooCommerce Admin\Tests\API. */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** - * WC_Tests_API_Reports_Performance_Indicators + * PerformanceIndicators */ -class WC_Tests_API_Reports_Performance_Indicators extends WC_REST_Unit_Test_Case { +class PerformanceIndicators extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -46,45 +56,45 @@ class WC_Tests_API_Reports_Performance_Indicators extends WC_REST_Unit_Test_Case public function test_get_indicators() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. We'll create an order and a download. - $prod_download = new WC_Product_Download(); + $prod_download = new \WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); $prod_download->set_id( 1 ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_downloadable( 'yes' ); $product->set_downloads( array( $prod_download ) ); $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 25 ); $order->save(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( $this->user ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); $download->set_download_id( $prod_download->get_id() ); $download->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); $object->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); $object->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $time = time(); $request = new WP_REST_Request( 'GET', $this->endpoint ); @@ -120,7 +130,7 @@ class WC_Tests_API_Reports_Performance_Indicators extends WC_REST_Unit_Test_Case public function test_get_indicators_empty_request() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); $time = time(); $request = new WP_REST_Request( 'GET', $this->endpoint ); diff --git a/tests/Version4/Reports/reports-products-stats.php b/unit-tests/Tests/Version4/Reports/ProductStats.php similarity index 88% rename from tests/Version4/Reports/reports-products-stats.php rename to unit-tests/Tests/Version4/Reports/ProductStats.php index 1c5ef5d63b3..551179464e2 100644 --- a/tests/Version4/Reports/reports-products-stats.php +++ b/unit-tests/Tests/Version4/Reports/ProductStats.php @@ -6,10 +6,20 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** - * Class WC_Tests_API_Reports_Products_Stats + * Class ProductStats */ -class WC_Tests_API_Reports_Products_Stats extends WC_REST_Unit_Test_Case { +class ProductStats extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -50,18 +60,18 @@ class WC_Tests_API_Reports_Products_Stats extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); wp_set_current_user( $this->user ); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); $time = time(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_shipping_total( 10 ); $order->set_discount_total( 20 ); @@ -71,7 +81,7 @@ class WC_Tests_API_Reports_Products_Stats extends WC_REST_Unit_Test_Case { $order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax. $order->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( diff --git a/tests/Version4/Reports/reports-products.php b/unit-tests/Tests/Version4/Reports/Products.php similarity index 86% rename from tests/Version4/Reports/reports-products.php rename to unit-tests/Tests/Version4/Reports/Products.php index 6730e010480..989bd9f4ef2 100644 --- a/tests/Version4/Reports/reports-products.php +++ b/unit-tests/Tests/Version4/Reports/Products.php @@ -6,13 +6,22 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; + /** * Reports Products REST API Test Class * * @package WooCommerce\Tests\API * @since 3.5.0 */ -class WC_Tests_API_Reports_Products extends WC_REST_Unit_Test_Case { +class Products extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -54,20 +63,20 @@ class WC_Tests_API_Reports_Products extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $reports = $response->get_data(); @@ -91,25 +100,25 @@ class WC_Tests_API_Reports_Products extends WC_REST_Unit_Test_Case { */ public function test_get_reports_products_param() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); - $product_2 = new WC_Product_Simple(); + $product_2 = new \WC_Product_Simple(); $product_2->set_name( 'Test Product 2' ); $product_2->set_regular_price( 25 ); $product_2->save(); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( diff --git a/tests/Version4/Reports/reports-revenue-stats.php b/unit-tests/Tests/Version4/Reports/RevenueStats.php similarity index 94% rename from tests/Version4/Reports/reports-revenue-stats.php rename to unit-tests/Tests/Version4/Reports/RevenueStats.php index f62a3ad2ced..e2d1b76c67e 100644 --- a/tests/Version4/Reports/reports-revenue-stats.php +++ b/unit-tests/Tests/Version4/Reports/RevenueStats.php @@ -6,10 +6,17 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; + /** - * Class WC_Tests_API_Reports_Revenue_Stats + * Class RevenueStats */ -class WC_Tests_API_Reports_Revenue_Stats extends WC_REST_Unit_Test_Case { +class RevenueStats extends WC_REST_Unit_Test_Case { /** * Endpoints. diff --git a/tests/Version4/Reports/reports-stock.php b/unit-tests/Tests/Version4/Reports/Stock.php similarity index 87% rename from tests/Version4/Reports/reports-stock.php rename to unit-tests/Tests/Version4/Reports/Stock.php index 47303cb3571..bc15ecab33c 100644 --- a/tests/Version4/Reports/reports-stock.php +++ b/unit-tests/Tests/Version4/Reports/Stock.php @@ -6,10 +6,21 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; + /** - * Class WC_Tests_API_Reports_Stock + * Reports Customers Stats REST API Test Class + * + * @package WooCommerce\Tests\API + * @since 3.5.0 */ -class WC_Tests_API_Reports_Stock extends WC_REST_Unit_Test_Case { +class Stock extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -45,10 +56,10 @@ class WC_Tests_API_Reports_Stock extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $low_stock = new WC_Product_Simple(); + $low_stock = new \WC_Product_Simple(); $low_stock->set_name( 'Test low stock' ); $low_stock->set_regular_price( 5 ); $low_stock->set_manage_stock( true ); @@ -56,7 +67,7 @@ class WC_Tests_API_Reports_Stock extends WC_REST_Unit_Test_Case { $low_stock->set_stock_status( 'instock' ); $low_stock->save(); - $out_of_stock = new WC_Product_Simple(); + $out_of_stock = new \WC_Product_Simple(); $out_of_stock->set_name( 'Test out of stock' ); $out_of_stock->set_regular_price( 5 ); $out_of_stock->set_stock_status( 'outofstock' ); diff --git a/tests/Version4/Reports/reports-stock-stats.php b/unit-tests/Tests/Version4/Reports/StockStats.php similarity index 89% rename from tests/Version4/Reports/reports-stock-stats.php rename to unit-tests/Tests/Version4/Reports/StockStats.php index a4e0e95d54e..937e7859c6d 100644 --- a/tests/Version4/Reports/reports-stock-stats.php +++ b/unit-tests/Tests/Version4/Reports/StockStats.php @@ -5,10 +5,18 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; + /** - * Class WC_Tests_API_Reports_Stock_Stats + * Class StockStats */ -class WC_Tests_API_Reports_Stock_Stats extends WC_REST_Unit_Test_Case { +class StockStats extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -44,11 +52,11 @@ class WC_Tests_API_Reports_Stock_Stats extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); $number_of_low_stock = 3; for ( $i = 1; $i <= $number_of_low_stock; $i++ ) { - $low_stock = new WC_Product_Simple(); + $low_stock = new \WC_Product_Simple(); $low_stock->set_name( "Test low stock {$i}" ); $low_stock->set_regular_price( 5 ); $low_stock->set_manage_stock( true ); @@ -59,7 +67,7 @@ class WC_Tests_API_Reports_Stock_Stats extends WC_REST_Unit_Test_Case { $number_of_out_of_stock = 6; for ( $i = 1; $i <= $number_of_out_of_stock; $i++ ) { - $out_of_stock = new WC_Product_Simple(); + $out_of_stock = new \WC_Product_Simple(); $out_of_stock->set_name( "Test out of stock {$i}" ); $out_of_stock->set_regular_price( 5 ); $out_of_stock->set_stock_status( 'outofstock' ); @@ -68,7 +76,7 @@ class WC_Tests_API_Reports_Stock_Stats extends WC_REST_Unit_Test_Case { $number_of_in_stock = 10; for ( $i = 1; $i <= $number_of_in_stock; $i++ ) { - $in_stock = new WC_Product_Simple(); + $in_stock = new \WC_Product_Simple(); $in_stock->set_name( "Test in stock {$i}" ); $in_stock->set_regular_price( 25 ); $in_stock->save(); @@ -88,7 +96,7 @@ class WC_Tests_API_Reports_Stock_Stats extends WC_REST_Unit_Test_Case { $this->assertEquals( 13, $reports['totals']['instock'] ); // Test backorder and cache update. - $backorder_stock = new WC_Product_Simple(); + $backorder_stock = new \WC_Product_Simple(); $backorder_stock->set_name( 'Test backorder' ); $backorder_stock->set_regular_price( 5 ); $backorder_stock->set_stock_status( 'onbackorder' ); diff --git a/tests/Version4/Reports/reports-taxes-stats.php b/unit-tests/Tests/Version4/Reports/TaxStats.php similarity index 89% rename from tests/Version4/Reports/reports-taxes-stats.php rename to unit-tests/Tests/Version4/Reports/TaxStats.php index 8dd54f908d7..93a7ccd0327 100644 --- a/tests/Version4/Reports/reports-taxes-stats.php +++ b/unit-tests/Tests/Version4/Reports/TaxStats.php @@ -6,10 +6,20 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** - * WC_Tests_API_Reports_Taxes_Stats + * TaxStats */ -class WC_Tests_API_Reports_Taxes_Stats extends WC_REST_Unit_Test_Case { +class TaxStats extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -52,7 +62,7 @@ class WC_Tests_API_Reports_Taxes_Stats extends WC_REST_Unit_Test_Case { public function test_get_reports() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. $tax = WC_Tax::_insert_tax_rate( @@ -69,14 +79,14 @@ class WC_Tests_API_Reports_Taxes_Stats extends WC_REST_Unit_Test_Case { ) ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->set_tax_class( 'TestTax' ); $product->save(); update_option( 'woocommerce_calc_taxes', 'yes' ); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->calculate_taxes(); @@ -99,7 +109,7 @@ class WC_Tests_API_Reports_Taxes_Stats extends WC_REST_Unit_Test_Case { $wc_refund = wc_create_refund( $refund ); } - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $reports = $response->get_data(); diff --git a/tests/Version4/Reports/reports-taxes.php b/unit-tests/Tests/Version4/Reports/Taxes.php similarity index 91% rename from tests/Version4/Reports/reports-taxes.php rename to unit-tests/Tests/Version4/Reports/Taxes.php index e0de47dbe73..c22140dab35 100644 --- a/tests/Version4/Reports/reports-taxes.php +++ b/unit-tests/Tests/Version4/Reports/Taxes.php @@ -6,10 +6,23 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; + /** - * WC_Tests_API_Reports_Taxes + * Reports Customers Stats REST API Test Class + * + * @package WooCommerce\Tests\API + * @since 3.5.0 */ -class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { +class Taxes extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -52,10 +65,10 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { public function test_get_reports() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); @@ -73,7 +86,7 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { ) ); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); @@ -91,7 +104,7 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { ) ); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $reports = $response->get_data(); @@ -120,10 +133,10 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { public function test_get_reports_taxes_param() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); @@ -154,7 +167,7 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { ) ); - $order = WC_Helper_Order::create_order( 1, $product ); + $order = OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); @@ -172,7 +185,7 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { ) ); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $request = new WP_REST_Request( 'GET', $this->endpoint ); @@ -220,7 +233,7 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { public function test_get_reports_orderby_tax_rate() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); $wpdb->insert( $wpdb->prefix . 'woocommerce_tax_rates', @@ -277,7 +290,7 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case { public function test_get_reports_orderby_tax_code() { global $wpdb; wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); $wpdb->insert( $wpdb->prefix . 'woocommerce_tax_rates', diff --git a/tests/Version4/Reports/reports-variations.php b/unit-tests/Tests/Version4/Reports/Variations.php similarity index 86% rename from tests/Version4/Reports/reports-variations.php rename to unit-tests/Tests/Version4/Reports/Variations.php index d4b12df1237..0ba93066e45 100644 --- a/tests/Version4/Reports/reports-variations.php +++ b/unit-tests/Tests/Version4/Reports/Variations.php @@ -6,10 +6,22 @@ * @since 3.5.0 */ +namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; + +defined( 'ABSPATH' ) || exit; + +use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; + /** - * Class WC_Tests_API_Reports_Variations + * Reports Customers Stats REST API Test Class + * + * @package WooCommerce\Tests\API + * @since 3.5.0 */ -class WC_Tests_API_Reports_Variations extends WC_REST_Unit_Test_Case { +class Variations extends WC_REST_Unit_Test_Case { /** * Endpoints. @@ -51,21 +63,21 @@ class WC_Tests_API_Reports_Variations extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $variation = new WC_Product_Variation(); + $variation = new \WC_Product_Variation(); $variation->set_name( 'Test Variation' ); $variation->set_regular_price( 25 ); $variation->set_attributes( array( 'color' => 'green' ) ); $variation->save(); - $order = WC_Helper_Order::create_order( 1, $variation ); + $order = OrderHelper::create_order( 1, $variation ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $reports = $response->get_data(); @@ -91,27 +103,27 @@ class WC_Tests_API_Reports_Variations extends WC_REST_Unit_Test_Case { */ public function test_get_reports_variations_param() { wp_set_current_user( $this->user ); - WC_Helper_Reports::reset_stats_dbs(); + ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $variation = new WC_Product_Variation(); + $variation = new \WC_Product_Variation(); $variation->set_name( 'Test Variation' ); $variation->set_regular_price( 25 ); $variation->set_attributes( array( 'color' => 'green' ) ); $variation->save(); - $variation_2 = new WC_Product_Variation(); + $variation_2 = new \WC_Product_Variation(); $variation_2->set_name( 'Test Variation 2' ); $variation_2->set_regular_price( 100 ); $variation_2->set_attributes( array( 'color' => 'red' ) ); $variation_2->save(); - $order = WC_Helper_Order::create_order( 1, $variation ); + $order = OrderHelper::create_order( 1, $variation ); $order->set_status( 'completed' ); $order->set_total( 100 ); // $25 x 4. $order->save(); - WC_Helper_Queue::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( diff --git a/unit-tests/Tests/Version4/Settings.php b/unit-tests/Tests/Version4/Settings.php new file mode 100644 index 00000000000..4e1650eaa79 --- /dev/null +++ b/unit-tests/Tests/Version4/Settings.php @@ -0,0 +1,901 @@ +endpoint = new WC_REST_Setting_Options_Controller(); + \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v4/settings', $routes ); + $this->assertArrayHasKey( '/wc/v4/settings/(?P[\w-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v4/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all groups. + * + * @since 3.5.0 + */ + public function test_get_groups() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertContains( + array( + 'id' => 'test', + 'label' => 'Test extension', + 'parent_id' => '', + 'description' => 'My awesome test settings.', + 'sub_groups' => array( 'sub-test' ), + '_links' => array( + 'options' => array( + array( + 'href' => rest_url( '/wc/v4/settings/test' ), + ), + ), + ), + ), + $data + ); + + $this->assertContains( + array( + 'id' => 'sub-test', + 'label' => 'Sub test', + 'parent_id' => 'test', + 'description' => '', + 'sub_groups' => array(), + '_links' => array( + 'options' => array( + array( + 'href' => rest_url( '/wc/v4/settings/sub-test' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test /settings without valid permissions/creds. + * + * @since 3.5.0 + */ + public function test_get_groups_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test /settings without valid permissions/creds. + * + * @since 3.5.0 + * @covers WC_Rest_Settings_Controller::get_items + */ + public function test_get_groups_none_registered() { + wp_set_current_user( $this->user ); + + remove_all_filters( 'woocommerce_settings_groups' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); + $this->assertEquals( 500, $response->get_status() ); + + \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); + } + + /** + * Test groups schema. + * + * @since 3.5.0 + */ + public function test_get_group_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/settings' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 5, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'parent_id', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'sub_groups', $properties ); + } + + /** + * Test settings schema. + * + * @since 3.5.0 + */ + public function test_get_setting_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/settings/test/woocommerce_shop_page_display' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 10, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'value', $properties ); + $this->assertArrayHasKey( 'default', $properties ); + $this->assertArrayHasKey( 'tip', $properties ); + $this->assertArrayHasKey( 'placeholder', $properties ); + $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'options', $properties ); + $this->assertArrayHasKey( 'group_id', $properties ); + } + + /** + * Test getting a single group. + * + * @since 3.5.0 + */ + public function test_get_group() { + wp_set_current_user( $this->user ); + + // test route callback receiving an empty group id + $result = $this->endpoint->get_group_settings( '' ); + $this->assertIsWPError( $result ); + + // test getting a group that does not exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/not-real' ) ); + $this->assertEquals( 404, $response->get_status() ); + + // test getting the 'invalid' group + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/invalid' ) ); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid group with settings attached to it + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( 1, count( $data ) ); + $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); + $this->assertEmpty( $data[0]['value'] ); + } + + /** + * Test getting a single group without permission. + * + * @since 3.5.0 + */ + public function test_get_group_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/coupon-data' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a single setting. + * + * @since 3.5.0 + */ + public function test_update_setting() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data['value'] ); + + // test updating shop display setting + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'both', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'both', $data['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'subcategories', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'subcategories', $data['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => '', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '', $data['value'] ); + $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); + } + + /** + * Test updating multiple settings at once. + * + * @since 3.5.0 + */ + public function test_update_settings() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data[0]['value'] ); + + // test setting both at once + $request = new WP_REST_Request( 'POST', '/wc/v4/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'both', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'both', $data['update'][0]['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + + // test updating one, but making sure the other value stays the same + $request = new WP_REST_Request( 'POST', '/wc/v4/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + } + + /** + * Test getting a single setting. + * + * @since 3.5.0 + */ + public function test_get_setting() { + wp_set_current_user( $this->user ); + + // test getting an invalid setting from a group that does not exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/not-real/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting an invalid setting from a group that does exist + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/invalid/invalid' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid setting + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'woocommerce_shop_page_display', $data['id'] ); + $this->assertEquals( 'Shop page display', $data['label'] ); + $this->assertEquals( '', $data['default'] ); + $this->assertEquals( 'select', $data['type'] ); + $this->assertEquals( '', $data['value'] ); + } + + /** + * Test getting a single setting without valid user permissions. + * + * @since 3.5.0 + */ + public function test_get_setting_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/woocommerce_shop_page_display' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests the GET single setting route handler receiving an empty setting ID. + * + * @since 3.5.0 + */ + public function test_get_setting_empty_setting_id() { + $result = $this->endpoint->get_setting( 'test', '' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler receiving an invalid setting ID. + * + * @since 3.5.0 + */ + public function test_get_setting_invalid_setting_id() { + $result = $this->endpoint->get_setting( 'test', 'invalid' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler encountering an invalid setting type. + * + * @since 3.5.0 + */ + public function test_get_setting_invalid_setting_type() { + // $controller = $this->getMock( 'WC_Rest_Setting_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); + $controller = $this->getMockBuilder( 'WC_Rest_Setting_Options_Controller' )->setMethods( array( 'get_group_settings', 'is_setting_type_valid' ) )->getMock(); + + $controller + ->expects( $this->any() ) + ->method( 'get_group_settings' ) + ->will( $this->returnValue( \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); + + $controller + ->expects( $this->any() ) + ->method( 'is_setting_type_valid' ) + ->will( $this->returnValue( false ) ); + + $result = $controller->get_setting( 'test', 'woocommerce_shop_page_display' ); + + $this->assertIsWPError( $result ); + } + + /** + * Test updating a single setting without valid user permissions. + * + * @since 3.5.0 + */ + public function test_update_setting_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( + array( + 'value' => 'subcategories', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + + /** + * Test updating multiple settings without valid user permissions. + * + * @since 3.5.0 + */ + public function test_update_settings_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/settings/test/batch' ); + $request->set_body_params( + array( + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test updating a bad setting ID. + * + * @since 3.5.0 + * @covers WC_Rest_Setting_Options_Controller::update_item + */ + public function test_update_setting_bad_setting_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/test/invalid' ); + $request->set_body_params( + array( + 'value' => 'test', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. + * + * @since 3.5.0 + */ + public function test_classic_settings() { + wp_set_current_user( $this->user ); + + // Make sure the group is properly registered + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/products' ) ); + $data = $response->get_data(); + $this->assertTrue( is_array( $data ) ); + $this->assertContains( + array( + 'id' => 'woocommerce_downloads_require_login', + 'label' => 'Access restriction', + 'description' => 'Downloads require login', + 'type' => 'checkbox', + 'default' => 'no', + 'tip' => 'This setting does not apply to guest purchases.', + 'value' => 'no', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/settings/products/woocommerce_downloads_require_login' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/settings/products' ), + ), + ), + ), + ), + $data + ); + + // test get single + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/products/woocommerce_dimension_unit' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'cm', $data['default'] ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); + $request->set_body_params( + array( + 'value' => 'yd', + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'yd', $data['value'] ); + $this->assertEquals( 'yd', get_option( 'woocommerce_dimension_unit' ) ); + } + + /** + * Tests our email etting registration to make sure settings added for WP-Admin are available over the API. + * + * @since 3.5.0 + */ + public function test_email_settings() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/email_new_order' ) ); + $settings = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertContains( + array( + 'id' => 'recipient', + 'label' => 'Recipient(s)', + 'description' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', + 'type' => 'text', + 'default' => '', + 'tip' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', + 'value' => '', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/settings/email_new_order/recipient' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/settings/email_new_order' ), + ), + ), + ), + ), + $settings + ); + + // test get single + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/email_new_order/subject' ) ); + $setting = $response->get_data(); + + $this->assertEquals( + array( + 'id' => 'subject', + 'label' => 'Subject', + 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'type' => 'text', + 'default' => '', + 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'value' => '', + 'group_id' => 'email_new_order', + ), + $setting + ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_new_order', 'subject' ) ); + $request->set_body_params( + array( + 'value' => 'This is my subject', + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEquals( + array( + 'id' => 'subject', + 'label' => 'Subject', + 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'type' => 'text', + 'default' => '', + 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'value' => 'This is my subject', + 'group_id' => 'email_new_order', + ), + $setting + ); + + // test updating another subject and making sure it works with a "similar" id + $request = new WP_REST_Request( 'GET', sprintf( '/wc/v4/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEmpty( $setting['value'] ); + + // test update + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); + $request->set_body_params( + array( + 'value' => 'This is my new subject', + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + + $this->assertEquals( 'This is my new subject', $setting['value'] ); + + // make sure the other is what we left it + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/email_new_order/subject' ) ); + $setting = $response->get_data(); + + $this->assertEquals( 'This is my subject', $setting['value'] ); + } + + /** + * Test validation of checkbox settings. + * + * @since 3.5.0 + */ + public function test_validation_checkbox() { + wp_set_current_user( $this->user ); + + // test bogus value + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'not_yes_or_no', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // test yes + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'yes', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + // test no + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); + $request->set_body_params( + array( + 'value' => 'no', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test validation of radio settings. + * + * @since 3.5.0 + */ + public function test_validation_radio() { + wp_set_current_user( $this->user ); + + // not a valid option + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); + $request->set_body_params( + array( + 'value' => 'billing2', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // valid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); + $request->set_body_params( + array( + 'value' => 'billing', + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test validation of multiselect. + * + * @since 3.5.0 + */ + public function test_validation_multiselect() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v4/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ) ); + $setting = $response->get_data(); + $this->assertEmpty( $setting['value'] ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ); + $request->set_body_params( + array( + 'value' => array( 'AX', 'DZ', 'MMM' ), + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( array( 'AX', 'DZ' ), $setting['value'] ); + } + + /** + * Test validation of select. + * + * @since 3.5.0 + */ + public function test_validation_select() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ) ); + $setting = $response->get_data(); + $this->assertEquals( 'kg', $setting['value'] ); + + // invalid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); + $request->set_body_params( + array( + 'value' => 'pounds', // invalid, should be lbs + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // valid + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); + $request->set_body_params( + array( + 'value' => 'lbs', // invalid, should be lbs + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( 'lbs', $setting['value'] ); + } + + /** + * Test to make sure the 'base location' setting is present in the response. + * That it is returned as 'select' and not 'single_select_country', + * and that both state and country options are returned. + * + * @since 3.5.0 + */ + public function test_woocommerce_default_country() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_default_country' ) ); + $setting = $response->get_data(); + + $this->assertEquals( 'select', $setting['type'] ); + $this->assertArrayHasKey( 'GB', $setting['options'] ); + $this->assertArrayHasKey( 'US:OR', $setting['options'] ); + } + + /** + * Test to make sure the store address setting can be fetched and updated. + * + * @since 3.5.0 + */ + public function test_woocommerce_store_address() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_address' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_address' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_address' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store address 2 (line 2) setting can be fetched and updated. + * + * @since 3.5.0 + */ + public function test_woocommerce_store_address_2() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_address_2' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_address_2' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_address_2' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store city setting can be fetched and updated. + * + * @since 3.5.0 + */ + public function test_woocommerce_store_city() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_city' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_city' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_city' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } + + /** + * Test to make sure the store postcode setting can be fetched and updated. + * + * @since 3.5.0 + */ + public function test_woocommerce_store_postcode() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_postcode' ) ); + $setting = $response->get_data(); + $this->assertEquals( 'text', $setting['type'] ); + + // Repalce the old value with something uniquely new + $old_value = $setting['value']; + $new_value = $old_value . ' ' . rand( 1000, 9999 ); + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_postcode' ); + $request->set_body_params( + array( + 'value' => $new_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $new_value, $setting['value'] ); + + // Put the original value back + $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_postcode' ); + $request->set_body_params( + array( + 'value' => $old_value, + ) + ); + $response = $this->server->dispatch( $request ); + $setting = $response->get_data(); + $this->assertEquals( $old_value, $setting['value'] ); + } +} diff --git a/unit-tests/Tests/Version4/ShippingMethods.php b/unit-tests/Tests/Version4/ShippingMethods.php new file mode 100644 index 00000000000..8a8707d3582 --- /dev/null +++ b/unit-tests/Tests/Version4/ShippingMethods.php @@ -0,0 +1,149 @@ +endpoint = new WC_REST_Shipping_Methods_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v4/shipping_methods', $routes ); + $this->assertArrayHasKey( '/wc/v4/shipping_methods/(?P[\w-]+)', $routes ); + } + + /** + * Test getting all shipping methods. + * + * @since 3.5.0 + */ + public function test_get_shipping_methods() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods' ) ); + $methods = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertContains( + array( + 'id' => 'free_shipping', + 'title' => 'Free shipping', + 'description' => 'Free shipping is a special method which can be triggered with coupons and minimum spends.', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/shipping_methods/free_shipping' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping_methods' ), + ), + ), + ), + ), + $methods + ); + } + + /** + * Tests to make sure shipping methods cannot viewed without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_shipping_methods_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a single shipping method. + * + * @since 3.5.0 + */ + public function test_get_shipping_method() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods/local_pickup' ) ); + $method = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => 'local_pickup', + 'title' => 'Local pickup', + 'description' => 'Allow customers to pick up orders themselves. By default, when using local pickup store base taxes will apply regardless of customer address.', + ), + $method + ); + } + + /** + * Tests getting a single shipping method without the correct permissions. + * + * @since 3.5.0 + */ + public function test_get_shipping_method_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods/local_pickup' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a shipping method with an invalid ID. + * + * @since 3.5.0 + */ + public function test_get_shipping_method_invalid_id() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods/fake_method' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test the shipping method schema. + * + * @since 3.5.0 + */ + public function test_shipping_method_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/shipping_methods' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'title', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + } +} diff --git a/unit-tests/Tests/Version4/ShippingZones.php b/unit-tests/Tests/Version4/ShippingZones.php new file mode 100644 index 00000000000..97034c0449c --- /dev/null +++ b/unit-tests/Tests/Version4/ShippingZones.php @@ -0,0 +1,831 @@ +endpoint = new WC_REST_Shipping_Zones_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + $this->zones = array(); + } + + /** + * Helper method to create a Shipping Zone. + * + * @param string $name Zone name. + * @param int $order Optional. Zone sort order. + * @return WC_Shipping_Zone + */ + protected function create_shipping_zone( $name, $order = 0, $locations = array() ) { + $zone = new WC_Shipping_Zone( null ); + $zone->set_zone_name( $name ); + $zone->set_zone_order( $order ); + $zone->set_locations( $locations ); + $zone->save(); + + $this->zones[] = $zone; + + return $zone; + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v4/shipping/zones', $routes ); + $this->assertArrayHasKey( '/wc/v4/shipping/zones/(?P[\d-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v4/shipping/zones/(?P[\d]+)/locations', $routes ); + $this->assertArrayHasKey( '/wc/v4/shipping/zones/(?P[\d]+)/methods', $routes ); + $this->assertArrayHasKey( '/wc/v4/shipping/zones/(?P[\d]+)/methods/(?P[\d]+)', $routes ); + } + + /** + * Test getting all Shipping Zones. + * + * @since 3.5.0 + */ + public function test_get_zones() { + wp_set_current_user( $this->user ); + + // "Rest of the World" zone exists by default + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( + array( + 'id' => $data[0]['id'], + 'name' => 'Locations not covered by your other zones', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $data[0]['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $data[0]['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + + // Create a zone and make sure it's in the response + $this->create_shipping_zone( 'Zone 1' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 2 ); + $this->assertContains( + array( + 'id' => $data[1]['id'], + 'name' => 'Zone 1', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $data[1]['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $data[1]['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test /shipping/zones without valid permissions/creds. + * + * @since 3.5.0 + */ + public function test_get_shipping_zones_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test /shipping/zones while Shipping is disabled in WooCommerce. + * + * @since 3.5.0 + */ + public function test_get_shipping_zones_disabled_shipping() { + wp_set_current_user( $this->user ); + + add_filter( 'wc_shipping_enabled', '__return_false' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); + $this->assertEquals( 404, $response->get_status() ); + + remove_filter( 'wc_shipping_enabled', '__return_false' ); + } + + /** + * Test Shipping Zone schema. + * + * @since 3.5.0 + */ + public function test_get_shipping_zone_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/shipping/zones' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertTrue( $properties['id']['readonly'] ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'order', $properties ); + } + + /** + * Test Shipping Zone create endpoint. + * + * @since 3.5.0 + */ + public function test_create_shipping_zone() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones' ); + $request->set_body_params( + array( + 'name' => 'Test Zone', + 'order' => 1, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $data['id'], + 'name' => 'Test Zone', + 'order' => 1, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $data['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $data['id'] . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test Shipping Zone create endpoint. + * + * @since 3.5.0 + */ + public function test_create_shipping_zone_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones' ); + $request->set_body_params( + array( + 'name' => 'Test Zone', + 'order' => 1, + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test Shipping Zone update endpoint. + * + * @since 3.5.0 + */ + public function test_update_shipping_zone() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + + $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/' . $zone->get_id() ); + $request->set_body_params( + array( + 'name' => 'Zone Test', + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $zone->get_id(), + 'name' => 'Zone Test', + 'order' => 2, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test Shipping Zone update endpoint with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_update_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/555555' ); + $request->set_body_params( + array( + 'name' => 'Zone Test', + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint. + * + * @since 3.5.0 + */ + public function test_delete_shipping_zone() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/' . $zone->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint without permissions. + * + * @since 3.5.0 + */ + public function test_delete_shipping_zone_without_permission() { + wp_set_current_user( 0 ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/' . $zone->get_id() ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test Shipping Zone delete endpoint with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_delete_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/555555' ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single Shipping Zone. + * + * @since 3.5.0 + */ + public function test_get_single_shipping_zone() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( + array( + 'id' => $zone->get_id(), + 'name' => 'Test Zone', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test getting a single Shipping Zone with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_get_single_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting Shipping Zone Locations. + * + * @since 3.5.0 + */ + public function test_get_locations() { + wp_set_current_user( $this->user ); + + // Create a zone + $zone = $this->create_shipping_zone( + 'Zone 1', + 0, + array( + array( + 'code' => 'US', + 'type' => 'country', + ), + ) + ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertEquals( + array( + array( + 'code' => 'US', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test getting Shipping Zone Locations with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_get_locations_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1/locations' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test Shipping Zone Locations update endpoint. + * + * @since 3.5.0 + */ + public function test_update_locations() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + + $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + json_encode( + array( + array( + 'code' => 'UK', + 'type' => 'country', + ), + array( + 'code' => 'US', // test that locations missing "type" treated as country. + ), + array( + 'code' => 'SW1A0AA', + 'type' => 'postcode', + ), + array( + 'type' => 'continent', // test that locations missing "code" aren't saved + ), + ) + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + $this->assertEquals( + array( + array( + 'code' => 'UK', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + array( + 'code' => 'US', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + array( + 'code' => 'SW1A0AA', + 'type' => 'postcode', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + ), + $data + ); + } + + /** + * Test updating Shipping Zone Locations with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_update_locations_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/1/locations' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting all Shipping Zone Methods and getting a single Shipping Zone Method. + * + * @since 3.5.0 + */ + public function test_get_methods() { + wp_set_current_user( $this->user ); + + // Create a shipping method and make sure it's in the response + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + + $settings = array(); + $method->init_instance_settings(); + foreach ( $method->get_instance_form_fields() as $id => $field ) { + $data = array( + 'id' => $id, + 'label' => $field['title'], + 'description' => ( empty( $field['description'] ) ? '' : $field['description'] ), + 'type' => $field['type'], + 'value' => $method->instance_settings[ $id ], + 'default' => ( empty( $field['default'] ) ? '' : $field['default'] ), + 'tip' => ( empty( $field['description'] ) ? '' : $field['description'] ), + 'placeholder' => ( empty( $field['placeholder'] ) ? '' : $field['placeholder'] ), + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods' ) ); + $data = $response->get_data(); + $expected = array( + 'id' => $instance_id, + 'instance_id' => $instance_id, + 'title' => $method->instance_settings['title'], + 'order' => $method->method_order, + 'enabled' => ( 'yes' === $method->enabled ), + 'method_id' => $method->id, + 'method_title' => $method->method_title, + 'method_description' => $method->method_description, + 'settings' => $settings, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( $expected, $data ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $expected, $data ); + } + + /** + * Test getting all Shipping Zone Methods with a bad zone ID. + * + * @since 3.5.0 + */ + public function test_get_methods_invalid_zone_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1/methods' ) ); + + $this->assertEquals( 404, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1/methods/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single Shipping Zone Method with a bad ID. + * + * @since 3.5.0 + */ + public function test_get_methods_invalid_method_id() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Zone 1' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test updating a Shipping Zone Method. + * + * @since 3.5.0 + */ + public function test_update_methods() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + + // Test defaults + $request = new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '0', $data['settings']['cost']['value'] ); + + // Update a single value + $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 5, + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '5', $data['settings']['cost']['value'] ); + + // Test multiple settings + $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 10, + 'tax_status' => 'none', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'title', $data['settings'] ); + $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); + $this->assertArrayHasKey( 'tax_status', $data['settings'] ); + $this->assertEquals( 'none', $data['settings']['tax_status']['value'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '10', $data['settings']['cost']['value'] ); + + // Test bogus + $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'settings' => array( + 'cost' => 10, + 'tax_status' => 'this_is_not_a_valid_option', + ), + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + + // Test other parameters + $this->assertTrue( $data['enabled'] ); + $this->assertEquals( 1, $data['order'] ); + + $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_body_params( + array( + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertFalse( $data['enabled'] ); + $this->assertEquals( 2, $data['order'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '10', $data['settings']['cost']['value'] ); + } + + /** + * Test creating a Shipping Zone Method. + * + * @since 3.5.0 + */ + public function test_create_method() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods' ); + $request->set_body_params( + array( + 'method_id' => 'flat_rate', + 'enabled' => false, + 'order' => 2, + ) + ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertFalse( $data['enabled'] ); + $this->assertEquals( 2, $data['order'] ); + $this->assertArrayHasKey( 'cost', $data['settings'] ); + $this->assertEquals( '0', $data['settings']['cost']['value'] ); + } + + /** + * Test deleting a Shipping Zone Method. + * + * @since 3.5.0 + */ + public function test_delete_method() { + wp_set_current_user( $this->user ); + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } +} diff --git a/unit-tests/Tests/Version4/SystemStatus.php b/unit-tests/Tests/Version4/SystemStatus.php new file mode 100644 index 00000000000..b056be932d0 --- /dev/null +++ b/unit-tests/Tests/Version4/SystemStatus.php @@ -0,0 +1,473 @@ +endpoint = new WC_REST_System_Status_Controller(); + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + + // Callback used by WP_HTTP_TestCase to decide whether to perform HTTP requests or to provide a mocked response. + $this->http_responder = array( $this, 'mock_http_responses' ); + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v4/system_status', $routes ); + $this->assertArrayHasKey( '/wc/v4/system_status/tools', $routes ); + $this->assertArrayHasKey( '/wc/v4/system_status/tools/(?P[\w-]+)', $routes ); + } + + /** + * Test to make sure system status cannot be accessed without valid creds + * + * @since 3.5.0 + */ + public function test_get_system_status_info_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure root properties are present. + * (environment, theme, database, etc). + * + * @since 3.5.0 + */ + public function test_get_system_status_info_returns_root_properties() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'environment', $data ); + $this->assertArrayHasKey( 'database', $data ); + $this->assertArrayHasKey( 'active_plugins', $data ); + $this->assertArrayHasKey( 'theme', $data ); + $this->assertArrayHasKey( 'settings', $data ); + $this->assertArrayHasKey( 'security', $data ); + $this->assertArrayHasKey( 'pages', $data ); + } + + /** + * Test to make sure environment response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_environment() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + $data = $response->get_data(); + $environment = (array) $data['environment']; + + // Make sure all expected data is present. + $this->assertEquals( 32, count( $environment ) ); + + // Test some responses to make sure they match up. + $this->assertEquals( get_option( 'home' ), $environment['home_url'] ); + $this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] ); + $this->assertEquals( WC()->version, $environment['version'] ); + } + + /** + * Test to make sure database response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_database() { + global $wpdb; + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + $data = $response->get_data(); + $database = (array) $data['database']; + + $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); + $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); + $this->assertEquals( WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); + $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], wc_print_r( $database, true ) ); + $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], wc_print_r( $database, true ) ); + } + + /** + * Test to make sure active plugins response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_active_plugins() { + wp_set_current_user( $this->user ); + + $actual_plugins = array( 'hello.php' ); + update_option( 'active_plugins', $actual_plugins ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + update_option( 'active_plugins', array() ); + + $data = $response->get_data(); + $plugins = (array) $data['active_plugins']; + + $this->assertEquals( 1, count( $plugins ) ); + $this->assertEquals( 'Hello Dolly', $plugins[0]['name'] ); + } + + /** + * Test to make sure theme response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_theme() { + wp_set_current_user( $this->user ); + $active_theme = wp_get_theme(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + $data = $response->get_data(); + $theme = (array) $data['theme']; + + $this->assertEquals( 13, count( $theme ) ); + $this->assertEquals( $active_theme->Name, $theme['name'] ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar + } + + /** + * Test to make sure settings response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_settings() { + wp_set_current_user( $this->user ); + + $term_response = array(); + $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + $data = $response->get_data(); + $settings = (array) $data['settings']; + + $this->assertEquals( 12, count( $settings ) ); + $this->assertEquals( ( 'yes' === get_option( 'woocommerce_api_enabled' ) ), $settings['api_enabled'] ); + $this->assertEquals( get_woocommerce_currency(), $settings['currency'] ); + $this->assertEquals( $term_response, $settings['taxonomies'] ); + } + + /** + * Test to make sure security response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_security() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + $data = $response->get_data(); + $settings = (array) $data['security']; + + $this->assertEquals( 2, count( $settings ) ); + $this->assertEquals( 'https' === substr( wc_get_page_permalink( 'shop' ), 0, 5 ), $settings['secure_connection'] ); + $this->assertEquals( ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), $settings['hide_errors'] ); + } + + /** + * Test to make sure pages response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_status_info_pages() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); + $data = $response->get_data(); + $pages = $data['pages']; + $this->assertEquals( 5, count( $pages ) ); + } + + /** + * Test system status schema. + * + * @since 3.5.0 + */ + public function test_system_status_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/system_status' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 9, count( $properties ) ); + $this->assertArrayHasKey( 'environment', $properties ); + $this->assertArrayHasKey( 'database', $properties ); + $this->assertArrayHasKey( 'active_plugins', $properties ); + $this->assertArrayHasKey( 'theme', $properties ); + $this->assertArrayHasKey( 'settings', $properties ); + $this->assertArrayHasKey( 'security', $properties ); + $this->assertArrayHasKey( 'pages', $properties ); + } + + /** + * Test to make sure get_items (all tools) response is correct. + * + * @since 3.5.0 + */ + public function test_get_system_tools() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $raw_tools ), count( $data ) ); + $this->assertContains( + array( + 'id' => 'regenerate_thumbnails', + 'name' => 'Regenerate shop thumbnails', + 'action' => 'Regenerate', + 'description' => 'This will regenerate all shop thumbnails to match your theme and/or image settings.', + '_links' => array( + 'item' => array( + array( + 'href' => rest_url( '/wc/v4/system_status/tools/regenerate_thumbnails' ), + 'embeddable' => 1, + ), + ), + ), + ), + $data + ); + + $query_params = array( + '_fields' => 'id,name,nonexisting', + ); + $request = new WP_REST_Request( 'GET', '/wc/v4/system_status/tools' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $raw_tools ), count( $data ) ); + $this->assertContains( + array( + 'id' => 'regenerate_thumbnails', + 'name' => 'Regenerate shop thumbnails', + ), + $data + ); + foreach ( $data as $item ) { + // Fields that are not requested are not returned in response. + $this->assertArrayNotHasKey( 'action', $item ); + $this->assertArrayNotHasKey( 'description', $item ); + // Links are part of data in collections, so excluded if not explicitly requested. + $this->assertArrayNotHasKey( '_links', $item ); + // Non existing field is ignored. + $this->assertArrayNotHasKey( 'nonexisting', $item ); + } + + // Links are part of data, not links in collections. + $links = $response->get_links(); + $this->assertEquals( 0, count( $links ) ); + } + + /** + * Test to make sure system status tools cannot be accessed without valid creds + * + * @since 3.5.0 + */ + public function test_get_system_status_tools_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure we can load a single tool correctly. + * + * @since 3.5.0 + */ + public function test_get_system_tool() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + $raw_tool = $raw_tools['recount_terms']; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools/recount_terms' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertEquals( 'Recount terms', $data['action'] ); + $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); + + // Test for _fields query parameter. + $query_params = array( + '_fields' => 'id,name,nonexisting', + ); + $request = new WP_REST_Request( 'GET', '/wc/v4/system_status/tools/recount_terms' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertArrayNotHasKey( 'action', $data ); + $this->assertArrayNotHasKey( 'description', $data ); + // Links are part of links, not data in single items. + $this->assertArrayNotHasKey( '_links', $data ); + + // Links are part of links, not data in single item response. + $links = $response->get_links(); + $this->assertEquals( 1, count( $links ) ); + } + + /** + * Test to make sure a single system status toolscannot be accessed without valid creds. + * + * @since 3.5.0 + */ + public function test_get_system_status_tool_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools/recount_terms' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure we can RUN a tool correctly. + * + * @since 3.5.0 + */ + public function test_execute_system_tool() { + wp_set_current_user( $this->user ); + + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + $raw_tools = $tools_controller->get_tools(); + $raw_tool = $raw_tools['recount_terms']; + + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v4/system_status/tools/recount_terms' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertEquals( 'Term counts', $data['name'] ); + $this->assertEquals( 'Recount terms', $data['action'] ); + $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); + $this->assertTrue( $data['success'] ); + $this->assertEquals( 1, did_action( 'woocommerce_rest_insert_system_status_tool' ) ); + + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v4/system_status/tools/not_a_real_tool' ) ); + $this->assertEquals( 404, $response->get_status() ); + + // Test _fields for execute system tool request. + $query_params = array( + '_fields' => 'id,success,nonexisting', + ); + $request = new WP_REST_Request( 'PUT', '/wc/v4/system_status/tools/recount_terms' ); + $request->set_query_params( $query_params ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 'recount_terms', $data['id'] ); + $this->assertTrue( $data['success'] ); + + // Fields that are not requested are not returned in response. + $this->assertArrayNotHasKey( 'action', $data ); + $this->assertArrayNotHasKey( 'name', $data ); + $this->assertArrayNotHasKey( 'description', $data ); + // Links are part of links, not data in single item response. + $this->assertArrayNotHasKey( '_links', $data ); + // Non existing field is ignored. + $this->assertArrayNotHasKey( 'nonexisting', $data ); + + // Links are part of links, not data in single item response. + $links = $response->get_links(); + $this->assertEquals( 1, count( $links ) ); + } + + /** + * Test to make sure a tool cannot be run without valid creds. + * + * @since 3.5.0 + */ + public function test_execute_system_status_tool_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v4/system_status/tools/recount_terms' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test system status schema. + * + * @since 3.5.0 + */ + public function test_system_status_tool_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/system_status/tools' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 6, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'action', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'success', $properties ); + $this->assertArrayHasKey( 'message', $properties ); + } + + /** + * Provides a mocked response for external requests performed by WC_REST_System_Status_Controller. + * This way it is not necessary to perform a regular request to an external server which would + * significantly slow down the tests. + * + * This function is called by WP_HTTP_TestCase::http_request_listner(). + * + * @param array $request Request arguments. + * @param string $url URL of the request. + * + * @return array|false mocked response or false to let WP perform a regular request. + */ + protected function mock_http_responses( $request, $url ) { + $mocked_response = false; + + if ( in_array( $url, array( 'https://www.paypal.com/cgi-bin/webscr', 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=0' ), true ) ) { + $mocked_response = array( + 'response' => array( 'code' => 200 ), + ); + } elseif ( 'https://api.wordpress.org/themes/info/1.0/' === $url ) { + $mocked_response = array( + 'body' => 'O:8:"stdClass":12:{s:4:"name";s:7:"Default";s:4:"slug";s:7:"default";s:7:"version";s:5:"1.7.2";s:11:"preview_url";s:29:"https://wp-themes.com/default";s:6:"author";s:15:"wordpressdotorg";s:14:"screenshot_url";s:61:"//ts.w.org/wp-content/themes/default/screenshot.png?ver=1.7.2";s:6:"rating";d:100;s:11:"num_ratings";s:1:"3";s:10:"downloaded";i:296618;s:12:"last_updated";s:10:"2010-06-14";s:8:"homepage";s:37:"https://wordpress.org/themes/default/";s:13:"download_link";s:55:"https://downloads.wordpress.org/theme/default.1.7.2.zip";}', + 'response' => array( 'code' => 200 ), + ); + } + + return $mocked_response; + } +} From 5d65448e9701869ed8bb0e3308a7872058b0311b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 13:39:46 +0100 Subject: [PATCH 061/440] Fixing tests --- .../Controllers/AbstractController.php | 2 +- .../Controllers/AbstractObjectsController.php | 14 +- .../Controllers/AbstractPostsController.php | 12 +- .../Controllers/AbstractTermsContoller.php | 6 +- src/RestApi/Version4/Controllers/Coupons.php | 6 +- .../Controllers/CustomerDownloads.php | 4 +- .../Version4/Controllers/Customers.php | 16 +- src/RestApi/Version4/Controllers/Data.php | 4 +- .../Version4/Controllers/Data/Continents.php | 8 +- .../Version4/Controllers/Data/Countries.php | 8 +- .../Version4/Controllers/Data/Currencies.php | 10 +- .../Version4/Controllers/Data/DownloadIPs.php | 6 +- .../Version4/Controllers/Leaderboards.php | 6 +- .../Version4/Controllers/NetworkOrders.php | 2 +- .../Version4/Controllers/OrderNotes.php | 14 +- .../Version4/Controllers/OrderRefunds.php | 10 +- src/RestApi/Version4/Controllers/Orders.php | 4 +- .../Version4/Controllers/PaymentGateways.php | 12 +- .../Controllers/ProductAttributeTerms.php | 4 +- .../Controllers/ProductAttributes.php | 10 +- .../Controllers/ProductCategories.php | 4 +- .../Version4/Controllers/ProductReviews.php | 2 +- .../Controllers/ProductShippingClasses.php | 4 +- .../Version4/Controllers/ProductTags.php | 4 +- .../Controllers/ProductVariations.php | 14 +- src/RestApi/Version4/Controllers/Products.php | 12 +- src/RestApi/Version4/Controllers/Reports.php | 4 +- .../Controllers/Reports/Categories.php | 4 +- .../Controllers/Reports/CouponStats.php | 4 +- .../Version4/Controllers/Reports/Coupons.php | 4 +- .../Controllers/Reports/CustomerStats.php | 4 +- .../Controllers/Reports/Customers.php | 4 +- .../Controllers/Reports/DownloadStats.php | 4 +- .../Controllers/Reports/Downloads.php | 4 +- .../Version4/Controllers/Reports/Import.php | 14 +- .../Controllers/Reports/OrderStats.php | 4 +- .../Version4/Controllers/Reports/Orders.php | 4 +- .../Reports/PerformanceIndicators.php | 4 +- .../Controllers/Reports/ProductStats.php | 4 +- .../Version4/Controllers/Reports/Products.php | 4 +- .../Controllers/Reports/RevenueStats.php | 4 +- .../Version4/Controllers/Reports/Stock.php | 4 +- .../Controllers/Reports/StockStats.php | 4 +- .../Version4/Controllers/Reports/TaxStats.php | 4 +- .../Version4/Controllers/Reports/Taxes.php | 4 +- .../Controllers/Reports/Variations.php | 4 +- src/RestApi/Version4/Controllers/Settings.php | 6 +- .../Version4/Controllers/SettingsOptions.php | 10 +- .../Version4/Controllers/ShippingMethods.php | 8 +- .../Controllers/ShippingZoneLocations.php | 6 +- .../Controllers/ShippingZoneMethods.php | 12 +- .../Version4/Controllers/ShippingZones.php | 8 +- .../Version4/Controllers/SystemStatus.php | 6 +- .../Controllers/SystemStatusTools.php | 8 +- .../Version4/Controllers/TaxClasses.php | 12 +- src/RestApi/Version4/Controllers/Taxes.php | 16 +- src/RestApi/Version4/Controllers/Webhooks.php | 18 +- unit-tests/AbstractReportsTest.php | 48 ++++ unit-tests/AbstractRestApiTest.php | 3 + unit-tests/Bootstrap.php | 24 +- unit-tests/Helpers/ReportsHelper.php | 27 -- ...es-terms.php => ProductAttributeTerms.php} | 10 +- ...s-attributes.php => ProductAttributes.php} | 10 +- ...s-categories.php => ProductCategories.php} | 10 +- unit-tests/Tests/Blocks/products.php | 10 +- unit-tests/Tests/Version4/Functions.php | 257 ------------------ unit-tests/Tests/Version4/Orders.php | 3 - .../Tests/Version4/Reports/Categories.php | 33 +-- unit-tests/Tests/Version4/Reports/Coupons.php | 30 +- .../Tests/Version4/Reports/CouponsStats.php | 27 +- .../Tests/Version4/Reports/CustomerStats.php | 29 +- .../Tests/Version4/Reports/Customers.php | 51 +--- .../Tests/Version4/Reports/DownloadStats.php | 29 +- .../Tests/Version4/Reports/Downloads.php | 27 +- unit-tests/Tests/Version4/Reports/Import.php | 7 +- .../Tests/Version4/Reports/OrderStats.php | 24 +- unit-tests/Tests/Version4/Reports/Orders.php | 30 +- .../Reports/PerformanceIndicators.php | 29 +- .../Tests/Version4/Reports/ProductStats.php | 28 +- .../Tests/Version4/Reports/Products.php | 30 +- .../Tests/Version4/Reports/RevenueStats.php | 20 +- unit-tests/Tests/Version4/Reports/Stock.php | 24 +- .../Tests/Version4/Reports/StockStats.php | 24 +- .../Tests/Version4/Reports/TaxStats.php | 29 +- unit-tests/Tests/Version4/Reports/Taxes.php | 33 +-- .../Tests/Version4/Reports/Variations.php | 30 +- unit-tests/Tests/Version4/Settings.php | 8 +- unit-tests/Tests/Version4/ShippingMethods.php | 2 +- unit-tests/Tests/Version4/ShippingZones.php | 6 +- unit-tests/Tests/Version4/SystemStatus.php | 8 +- 90 files changed, 374 insertions(+), 984 deletions(-) create mode 100644 unit-tests/AbstractReportsTest.php delete mode 100644 unit-tests/Helpers/ReportsHelper.php rename unit-tests/Tests/Blocks/{products-attributes-terms.php => ProductAttributeTerms.php} (91%) rename unit-tests/Tests/Blocks/{products-attributes.php => ProductAttributes.php} (91%) rename unit-tests/Tests/Blocks/{products-categories.php => ProductCategories.php} (92%) delete mode 100644 unit-tests/Tests/Version4/Functions.php diff --git a/src/RestApi/Version4/Controllers/AbstractController.php b/src/RestApi/Version4/Controllers/AbstractController.php index e08694599ae..8df2dce939e 100644 --- a/src/RestApi/Version4/Controllers/AbstractController.php +++ b/src/RestApi/Version4/Controllers/AbstractController.php @@ -119,7 +119,7 @@ abstract class AbstractController extends WP_REST_Controller { * Bulk create, update and delete items. * * @param \WP_REST_Request $request Full details about the request. - * @return array Of \WP_Error or WP_REST_Response. + * @return array Of \WP_Error or \WP_REST_Response. */ public function batch_items( $request ) { /** diff --git a/src/RestApi/Version4/Controllers/AbstractObjectsController.php b/src/RestApi/Version4/Controllers/AbstractObjectsController.php index ff1a4d9fd7e..790f26b5e58 100644 --- a/src/RestApi/Version4/Controllers/AbstractObjectsController.php +++ b/src/RestApi/Version4/Controllers/AbstractObjectsController.php @@ -96,7 +96,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * @since 3.0.0 * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. - * @return \WP_Error|WP_REST_Response Response object on success, or \WP_Error object on failure. + * @return \WP_Error|\WP_REST_Response Response object on success, or \WP_Error object on failure. */ protected function prepare_object_for_response( $object, $request ) { // translators: %s: Class method name. @@ -120,7 +120,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Get a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $object = $this->get_object( (int) $request['id'] ); @@ -169,7 +169,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Create a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -215,7 +215,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Update a single post. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function update_item( $request ) { $object = $this->get_object( (int) $request['id'] ); @@ -337,7 +337,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Get a collection of posts. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $query_args = $this->prepare_objects_query( $request ); @@ -397,7 +397,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Delete a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $force = (bool) $request['force']; @@ -456,7 +456,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Fires after a single object is deleted or trashed via the REST API. * * @param WC_Data $object The deleted or trashed object. - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); diff --git a/src/RestApi/Version4/Controllers/AbstractPostsController.php b/src/RestApi/Version4/Controllers/AbstractPostsController.php index d6943abf056..b6609885d54 100644 --- a/src/RestApi/Version4/Controllers/AbstractPostsController.php +++ b/src/RestApi/Version4/Controllers/AbstractPostsController.php @@ -132,7 +132,7 @@ abstract class AbstractPostsController extends AbstractController { * Get a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; @@ -158,7 +158,7 @@ abstract class AbstractPostsController extends AbstractController { * Create a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -239,7 +239,7 @@ abstract class AbstractPostsController extends AbstractController { * Update a single post. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function update_item( $request ) { $id = (int) $request['id']; @@ -293,7 +293,7 @@ abstract class AbstractPostsController extends AbstractController { * Get a collection of posts. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $args = array(); @@ -401,7 +401,7 @@ abstract class AbstractPostsController extends AbstractController { * Delete a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -462,7 +462,7 @@ abstract class AbstractPostsController extends AbstractController { * Fires after a single item is deleted or trashed via the REST API. * * @param object $post The deleted or trashed item. - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); diff --git a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php index 7d431443c3a..513005002f7 100644 --- a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php +++ b/src/RestApi/Version4/Controllers/AbstractTermsContoller.php @@ -266,7 +266,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Get terms associated with a taxonomy. * * @param \WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function get_items( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -530,7 +530,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Delete a single term from a taxonomy. * * @param \WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $taxonomy = $this->get_taxonomy( $request ); @@ -562,7 +562,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Fires after a single term is deleted via the REST API. * * @param WP_Term $term The deleted term. - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$taxonomy}", $term, $response, $request ); diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/RestApi/Version4/Controllers/Coupons.php index ceb62d7766a..f4c4c9b13ac 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/RestApi/Version4/Controllers/Coupons.php @@ -200,7 +200,7 @@ class Coupons extends AbstractObjectsController { * @since 3.0.0 * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { $data = $this->get_formatted_item_data( $object ); @@ -216,7 +216,7 @@ class Coupons extends AbstractObjectsController { * The dynamic portion of the hook name, $this->post_type, * refers to object type being prepared for the response. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ @@ -553,7 +553,7 @@ class Coupons extends AbstractObjectsController { * Get a collection of posts and add the code search option to \WP_Query. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( $this, 'add_wp_query_search_code_filter' ), 10, 2 ); diff --git a/src/RestApi/Version4/Controllers/CustomerDownloads.php b/src/RestApi/Version4/Controllers/CustomerDownloads.php index 24625e464c4..0dcb39cf469 100644 --- a/src/RestApi/Version4/Controllers/CustomerDownloads.php +++ b/src/RestApi/Version4/Controllers/CustomerDownloads.php @@ -93,7 +93,7 @@ class CustomerDownloads extends AbstractController { * * @param stdClass $download Download object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $download, $request ) { $data = array( @@ -122,7 +122,7 @@ class CustomerDownloads extends AbstractController { /** * Filter customer download data returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param stdClass $download Download object used to create response. * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/RestApi/Version4/Controllers/Customers.php index e571d175b1f..616bc60caa9 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -268,7 +268,7 @@ class Customers extends AbstractController { * Get all customers. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $prepared_args = array(); @@ -366,7 +366,7 @@ class Customers extends AbstractController { * * @throws WC_REST_Exception On invalid params. * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function create_item( $request ) { try { @@ -420,7 +420,7 @@ class Customers extends AbstractController { * Get a single customer. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; @@ -441,7 +441,7 @@ class Customers extends AbstractController { * * @throws WC_REST_Exception On invalid params. * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function update_item( $request ) { try { @@ -502,7 +502,7 @@ class Customers extends AbstractController { * Delete a single customer. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -547,7 +547,7 @@ class Customers extends AbstractController { * Fires after a customer is deleted via the REST API. * * @param WP_User $user_data User data. - * @param WP_REST_Response $response The response returned from the API. + * @param \WP_REST_Response $response The response returned from the API. * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_customer', $user_data, $response, $request ); @@ -560,7 +560,7 @@ class Customers extends AbstractController { * * @param WP_User $user_data User object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $user_data, $request ) { $customer = new \WC_Customer( $user_data->ID ); @@ -574,7 +574,7 @@ class Customers extends AbstractController { /** * Filter customer data returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WP_User $user_data User object used to create response. * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/Data.php b/src/RestApi/Version4/Controllers/Data.php index 129d7bfe2b7..bb91d3fa18a 100644 --- a/src/RestApi/Version4/Controllers/Data.php +++ b/src/RestApi/Version4/Controllers/Data.php @@ -77,7 +77,7 @@ class Data extends AbstractController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $data = array(); @@ -113,7 +113,7 @@ class Data extends AbstractController { * * @param stdClass $resource Resource data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $resource, $request ) { $data = array( diff --git a/src/RestApi/Version4/Controllers/Data/Continents.php b/src/RestApi/Version4/Controllers/Data/Continents.php index 6790afdb10a..995196df4e5 100644 --- a/src/RestApi/Version4/Controllers/Data/Continents.php +++ b/src/RestApi/Version4/Controllers/Data/Continents.php @@ -155,7 +155,7 @@ class Continents extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $continents = WC()->countries->get_continents(); @@ -175,7 +175,7 @@ class Continents extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $data = $this->get_continent( strtoupper( $request['location'] ), $request ); @@ -191,7 +191,7 @@ class Continents extends DataController { * @since 3.5.0 * @param object $item Data object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { $data = $this->add_additional_fields_to_object( $item, $request ); @@ -205,7 +205,7 @@ class Continents extends DataController { * * Allows modification of the loction data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param array $item The original list of continent(s), countries, and states. * @param \WP_REST_Request $request Request used to generate the response. */ diff --git a/src/RestApi/Version4/Controllers/Data/Countries.php b/src/RestApi/Version4/Controllers/Data/Countries.php index a7d10eff071..8a76ad37789 100644 --- a/src/RestApi/Version4/Controllers/Data/Countries.php +++ b/src/RestApi/Version4/Controllers/Data/Countries.php @@ -102,7 +102,7 @@ class Countries extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $countries = WC()->countries->get_countries(); @@ -122,7 +122,7 @@ class Countries extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $data = $this->get_country( strtoupper( $request['location'] ), $request ); @@ -138,7 +138,7 @@ class Countries extends DataController { * @since 3.5.0 * @param object $item Data object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { $data = $this->add_additional_fields_to_object( $item, $request ); @@ -152,7 +152,7 @@ class Countries extends DataController { * * Allows modification of the loction data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param array $data The original country's states list. * @param \WP_REST_Request $request Request used to generate the response. */ diff --git a/src/RestApi/Version4/Controllers/Data/Currencies.php b/src/RestApi/Version4/Controllers/Data/Currencies.php index 0634c400c27..f3e5acaa54d 100644 --- a/src/RestApi/Version4/Controllers/Data/Currencies.php +++ b/src/RestApi/Version4/Controllers/Data/Currencies.php @@ -101,7 +101,7 @@ class Currencies extends DataController { * Return the list of currencies. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $currencies = get_woocommerce_currencies(); @@ -118,7 +118,7 @@ class Currencies extends DataController { * Return information for a specific currency. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); @@ -132,7 +132,7 @@ class Currencies extends DataController { * Return information for the current site currency. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_current_item( $request ) { $currency = get_option( 'woocommerce_currency' ); @@ -144,7 +144,7 @@ class Currencies extends DataController { * * @param object $item Data object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { $data = $this->add_additional_fields_to_object( $item, $request ); @@ -156,7 +156,7 @@ class Currencies extends DataController { /** * Filter currency returned from the API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param array $item Currency data. * @param \WP_REST_Request $request Request used to generate the response. */ diff --git a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php index 3279cc46c04..8e7637d4e67 100644 --- a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php +++ b/src/RestApi/Version4/Controllers/Data/DownloadIPs.php @@ -50,7 +50,7 @@ class DownloadIPs extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { global $wpdb; @@ -86,7 +86,7 @@ class DownloadIPs extends DataController { * @since 3.5.0 * @param object $item Data object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { $data = $this->add_additional_fields_to_object( $item, $request ); @@ -98,7 +98,7 @@ class DownloadIPs extends DataController { /** * Filter the list returned from the API. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Leaderboards.php b/src/RestApi/Version4/Controllers/Leaderboards.php index 4b01bc9ad36..7cc3b2d99b2 100644 --- a/src/RestApi/Version4/Controllers/Leaderboards.php +++ b/src/RestApi/Version4/Controllers/Leaderboards.php @@ -347,7 +347,7 @@ class Leaderboards extends Data { * Return all leaderboards. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $persisted_query = json_decode( $request['persisted_query'], true ); @@ -402,7 +402,7 @@ class Leaderboards extends Data { * * @param object $item Data object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { $data = $this->add_additional_fields_to_object( $item, $request ); @@ -412,7 +412,7 @@ class Leaderboards extends Data { /** * Filter the list returned from the API. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/NetworkOrders.php b/src/RestApi/Version4/Controllers/NetworkOrders.php index fa23c096d42..5c3e5cde7ef 100644 --- a/src/RestApi/Version4/Controllers/NetworkOrders.php +++ b/src/RestApi/Version4/Controllers/NetworkOrders.php @@ -105,7 +105,7 @@ class NetworkOrders extends Orders { * * @param \WP_REST_Request $request Full details about the request. * - * @return WP_REST_Response + * @return \WP_REST_Response */ public function network_orders( $request ) { $blog_id = $request->get_param( 'blog_id' ); diff --git a/src/RestApi/Version4/Controllers/OrderNotes.php b/src/RestApi/Version4/Controllers/OrderNotes.php index 0b53a46fdd9..27da4c0ec71 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -225,7 +225,7 @@ class OrderNotes extends AbstractController { * Create a single order note. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -271,7 +271,7 @@ class OrderNotes extends AbstractController { * Get a single order note. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; @@ -297,7 +297,7 @@ class OrderNotes extends AbstractController { * Delete a single order note. * * @param \WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -328,7 +328,7 @@ class OrderNotes extends AbstractController { return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); } - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -340,7 +340,7 @@ class OrderNotes extends AbstractController { * Fires after a order note is deleted or trashed via the REST API. * * @param WP_Comment $note The deleted or trashed order note. - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_order_note', $note, $response, $request ); @@ -353,7 +353,7 @@ class OrderNotes extends AbstractController { * * @param WP_Comment $note Order note object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $note, $request ) { $data = array( @@ -377,7 +377,7 @@ class OrderNotes extends AbstractController { /** * Filter order note object returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WP_Comment $note Order note object used to create response. * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/OrderRefunds.php b/src/RestApi/Version4/Controllers/OrderRefunds.php index 54030afe7b2..7c7fdcffbaa 100644 --- a/src/RestApi/Version4/Controllers/OrderRefunds.php +++ b/src/RestApi/Version4/Controllers/OrderRefunds.php @@ -177,7 +177,7 @@ class OrderRefunds extends Orders { * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { $this->request = $request; @@ -208,7 +208,7 @@ class OrderRefunds extends Orders { * The dynamic portion of the hook name, $this->post_type, * refers to object type being prepared for the response. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ @@ -221,7 +221,7 @@ class OrderRefunds extends Orders { * @param WP_Post $post Post object. * @param \WP_REST_Request $request Request object. * - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function prepare_item_for_response( $post, $request ) { $order = wc_get_order( (int) $request['order_id'] ); @@ -326,7 +326,7 @@ class OrderRefunds extends Orders { * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being * prepared for the response. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WP_Post $post Post object. * @param \WP_REST_Request $request Request object. */ @@ -377,7 +377,7 @@ class OrderRefunds extends Orders { * Create a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index 24ae9a4b24a..33497fe8d57 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -293,7 +293,7 @@ class Orders extends AbstractObjectsController { * @since 3.0.0 * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { $this->request = $request; @@ -311,7 +311,7 @@ class Orders extends AbstractObjectsController { * The dynamic portion of the hook name, $this->post_type, * refers to object type being prepared for the response. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/PaymentGateways.php b/src/RestApi/Version4/Controllers/PaymentGateways.php index 50645ead356..5a1b683820a 100644 --- a/src/RestApi/Version4/Controllers/PaymentGateways.php +++ b/src/RestApi/Version4/Controllers/PaymentGateways.php @@ -114,7 +114,7 @@ class PaymentGateways extends AbstractController { * Get payment gateways. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $payment_gateways = WC()->payment_gateways->payment_gateways(); @@ -132,7 +132,7 @@ class PaymentGateways extends AbstractController { * Get a single payment gateway. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function get_item( $request ) { $gateway = $this->get_gateway( $request ); @@ -149,7 +149,7 @@ class PaymentGateways extends AbstractController { * Update A Single Payment Method. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function update_item( $request ) { $gateway = $this->get_gateway( $request ); @@ -223,7 +223,7 @@ class PaymentGateways extends AbstractController { * Get a gateway based on the current request object. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|null + * @return \WP_REST_Response|null */ public function get_gateway( $request ) { $gateway = null; @@ -243,7 +243,7 @@ class PaymentGateways extends AbstractController { * * @param WC_Payment_Gateway $gateway Payment gateway object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $gateway, $request ) { $order = (array) get_option( 'woocommerce_gateway_order' ); @@ -269,7 +269,7 @@ class PaymentGateways extends AbstractController { /** * Filter payment gateway objects returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WC_Payment_Gateway $gateway Payment gateway object. * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php index a5514d72732..bfa6714bef4 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php +++ b/src/RestApi/Version4/Controllers/ProductAttributeTerms.php @@ -135,7 +135,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { * * @param WP_Term $item Term object. * @param \WP_REST_Request $request Request params. - * @return WP_REST_Response $response + * @return \WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { // Get term order. @@ -163,7 +163,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { * * Allows modification of the term data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param object $item The original term object. * @param \WP_REST_Request $request Request used to generate the response. */ diff --git a/src/RestApi/Version4/Controllers/ProductAttributes.php b/src/RestApi/Version4/Controllers/ProductAttributes.php index 27c8486ca49..cea3491f897 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributes.php +++ b/src/RestApi/Version4/Controllers/ProductAttributes.php @@ -357,7 +357,7 @@ class ProductAttributes extends AbstractController { * Delete a single attribute. * * @param \WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $force = isset( $request['force'] ) ? (bool) $request['force'] : false; @@ -381,7 +381,7 @@ class ProductAttributes extends AbstractController { return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -393,7 +393,7 @@ class ProductAttributes extends AbstractController { * Fires after a single attribute is deleted via the REST API. * * @param stdObject $attribute The deleted attribute. - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_product_attribute', $attribute, $response, $request ); @@ -406,7 +406,7 @@ class ProductAttributes extends AbstractController { * * @param obj $item Term object. * @param \WP_REST_Request $request Request params. - * @return WP_REST_Response $response + * @return \WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { $data = array( @@ -431,7 +431,7 @@ class ProductAttributes extends AbstractController { * * Allows modification of the product attribute data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param object $item The original attribute object. * @param \WP_REST_Request $request Request used to generate the response. */ diff --git a/src/RestApi/Version4/Controllers/ProductCategories.php b/src/RestApi/Version4/Controllers/ProductCategories.php index cdcaaa5920b..6e7ff08fd3b 100644 --- a/src/RestApi/Version4/Controllers/ProductCategories.php +++ b/src/RestApi/Version4/Controllers/ProductCategories.php @@ -35,7 +35,7 @@ class ProductCategories extends AbstractTermsContoller { * * @param WP_Term $item Term object. * @param \WP_REST_Request $request Request instance. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $item, $request ) { // Get category display type. @@ -86,7 +86,7 @@ class ProductCategories extends AbstractTermsContoller { * * Allows modification of the term data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param object $item The original term object. * @param \WP_REST_Request $request Request used to generate the response. */ diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/RestApi/Version4/Controllers/ProductReviews.php index 351ded63a1c..7a52f09481a 100644 --- a/src/RestApi/Version4/Controllers/ProductReviews.php +++ b/src/RestApi/Version4/Controllers/ProductReviews.php @@ -726,7 +726,7 @@ class ProductReviews extends AbstractController { * Filter product reviews object returned from the REST API. * * @param \WP_REST_Response $response The response object. - * @param WP_Comment $review Product review object used to create response. + * @param \WP_Comment $review Product review object used to create response. * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); diff --git a/src/RestApi/Version4/Controllers/ProductShippingClasses.php b/src/RestApi/Version4/Controllers/ProductShippingClasses.php index c39c8536444..d9bc0c8c2de 100644 --- a/src/RestApi/Version4/Controllers/ProductShippingClasses.php +++ b/src/RestApi/Version4/Controllers/ProductShippingClasses.php @@ -35,7 +35,7 @@ class ProductShippingClasses extends AbstractTermsContoller { * * @param obj $item Term object. * @param \WP_REST_Request $request Request params. - * @return WP_REST_Response $response + * @return \WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { $data = array( @@ -59,7 +59,7 @@ class ProductShippingClasses extends AbstractTermsContoller { * * Allows modification of the term data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param object $item The original term object. * @param \WP_REST_Request $request Request used to generate the response. */ diff --git a/src/RestApi/Version4/Controllers/ProductTags.php b/src/RestApi/Version4/Controllers/ProductTags.php index 64137497547..a1491bd3c34 100644 --- a/src/RestApi/Version4/Controllers/ProductTags.php +++ b/src/RestApi/Version4/Controllers/ProductTags.php @@ -35,7 +35,7 @@ class ProductTags extends AbstractTermsContoller { * * @param obj $item Term object. * @param \WP_REST_Request $request Request params. - * @return WP_REST_Response $response + * @return \WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { $data = array( @@ -59,7 +59,7 @@ class ProductTags extends AbstractTermsContoller { * * Allows modification of the term data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param object $item The original term object. * @param \WP_REST_Request $request Request used to generate the response. */ diff --git a/src/RestApi/Version4/Controllers/ProductVariations.php b/src/RestApi/Version4/Controllers/ProductVariations.php index 6e867f4ecfb..762c0c5e19d 100644 --- a/src/RestApi/Version4/Controllers/ProductVariations.php +++ b/src/RestApi/Version4/Controllers/ProductVariations.php @@ -174,7 +174,7 @@ class ProductVariations extends Products { * * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { $data = array( @@ -238,7 +238,7 @@ class ProductVariations extends Products { * The dynamic portion of the hook name, $this->post_type, * refers to object type being prepared for the response. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ @@ -639,7 +639,7 @@ class ProductVariations extends Products { * * @param \WP_REST_Request $request Full details about the request. * - * @return bool|\WP_Error|WP_REST_Response + * @return bool|\WP_Error\WP_REST_Response */ public function delete_item( $request ) { $force = (bool) $request['force']; @@ -684,7 +684,7 @@ class ProductVariations extends Products { $object->delete( true ); $result = 0 === $object->get_id(); - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -733,7 +733,7 @@ class ProductVariations extends Products { * Fires after a single object is deleted or trashed via the REST API. * * @param WC_Data $object The deleted or trashed object. - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); @@ -746,7 +746,7 @@ class ProductVariations extends Products { * * @since 3.0.0 * @param \WP_REST_Request $request Full details about the request. - * @return array Of \WP_Error or WP_REST_Response. + * @return array Of \WP_Error or \WP_REST_Response. */ public function batch_items( $request ) { $items = array_filter( $request->get_params() ); @@ -1210,7 +1210,7 @@ class ProductVariations extends Products { * Get a collection of posts and add the post title filter option to \WP_Query. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10, 2 ); diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/RestApi/Version4/Controllers/Products.php index 18b581426f5..464a0b9c7b8 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -149,7 +149,7 @@ class Products extends AbstractObjectsController { * @param \WP_REST_Request $request Request object. * * @since 3.0.0 - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; @@ -176,7 +176,7 @@ class Products extends AbstractObjectsController { * The dynamic portion of the hook name, $this->post_type, * refers to object type being prepared for the response. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ @@ -597,7 +597,7 @@ class Products extends AbstractObjectsController { * Get a collection of posts and add the post title filter option to \WP_Query. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); @@ -1440,7 +1440,7 @@ class Products extends AbstractObjectsController { * * @param \WP_REST_Request $request Full details about the request. * - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -1500,7 +1500,7 @@ class Products extends AbstractObjectsController { $object->delete( true ); $result = 0 === $object->get_id(); - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -1555,7 +1555,7 @@ class Products extends AbstractObjectsController { * Fires after a single object is deleted or trashed via the REST API. * * @param WC_Data $object The deleted or trashed object. - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/RestApi/Version4/Controllers/Reports.php index 284ff185d14..b187692b9d8 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/RestApi/Version4/Controllers/Reports.php @@ -191,7 +191,7 @@ class Reports extends AbstractController { * * @param stdClass $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = array( @@ -225,7 +225,7 @@ class Reports extends AbstractController { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Categories.php b/src/RestApi/Version4/Controllers/Reports/Categories.php index 7929eb8e936..5d69e501b42 100644 --- a/src/RestApi/Version4/Controllers/Reports/Categories.php +++ b/src/RestApi/Version4/Controllers/Reports/Categories.php @@ -103,7 +103,7 @@ class Categories extends Reports { * * @param stdClass $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -121,7 +121,7 @@ class Categories extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/CouponStats.php b/src/RestApi/Version4/Controllers/Reports/CouponStats.php index b8c40152a71..279ba053350 100644 --- a/src/RestApi/Version4/Controllers/Reports/CouponStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CouponStats.php @@ -100,7 +100,7 @@ class CouponStats extends Reports { * * @param stdClass $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = get_object_vars( $report ); @@ -117,7 +117,7 @@ class CouponStats extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Coupons.php b/src/RestApi/Version4/Controllers/Reports/Coupons.php index 59dd8ac40b4..b4567d8168b 100644 --- a/src/RestApi/Version4/Controllers/Reports/Coupons.php +++ b/src/RestApi/Version4/Controllers/Reports/Coupons.php @@ -91,7 +91,7 @@ class Coupons extends Reports { * * @param stdClass $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -109,7 +109,7 @@ class Coupons extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php index be1c23cda27..def364100b1 100644 --- a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CustomerStats.php @@ -88,7 +88,7 @@ class CustomerStats extends Reports { * * @param Array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -105,7 +105,7 @@ class CustomerStats extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Customers.php b/src/RestApi/Version4/Controllers/Reports/Customers.php index 7177a7b7b4f..e96c3804a03 100644 --- a/src/RestApi/Version4/Controllers/Reports/Customers.php +++ b/src/RestApi/Version4/Controllers/Reports/Customers.php @@ -120,7 +120,7 @@ class Customers extends Reports { * * @param array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; @@ -139,7 +139,7 @@ class Customers extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php index e0811dd72e9..45e23d85e6f 100644 --- a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php +++ b/src/RestApi/Version4/Controllers/Reports/DownloadStats.php @@ -103,7 +103,7 @@ class DownloadStats extends Reports { * * @param Array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -120,7 +120,7 @@ class DownloadStats extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Downloads.php b/src/RestApi/Version4/Controllers/Reports/Downloads.php index e1b3bf61230..dff4cc63491 100644 --- a/src/RestApi/Version4/Controllers/Reports/Downloads.php +++ b/src/RestApi/Version4/Controllers/Reports/Downloads.php @@ -80,7 +80,7 @@ class Downloads extends Reports { * * @param Array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -112,7 +112,7 @@ class Downloads extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Import.php b/src/RestApi/Version4/Controllers/Reports/Import.php index 57c5dc5a544..10e168e3a53 100644 --- a/src/RestApi/Version4/Controllers/Reports/Import.php +++ b/src/RestApi/Version4/Controllers/Reports/Import.php @@ -110,7 +110,7 @@ class Import extends Reports { * Import data based on user request params. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function import_items( $request ) { $query_args = $this->prepare_objects_query( $request ); @@ -153,7 +153,7 @@ class Import extends Reports { * * @param object $item Data object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { $data = $this->add_additional_fields_to_object( $item, $request ); @@ -163,7 +163,7 @@ class Import extends Reports { /** * Filter the list returned from the API. * - * @param WP_REST_Response $response The response object. + * @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. */ @@ -227,7 +227,7 @@ class Import extends Reports { * Cancel all queued import actions. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function cancel_import( $request ) { \WC_Admin_Reports_Sync::clear_queued_actions(); @@ -247,7 +247,7 @@ class Import extends Reports { * Delete all imported items. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function delete_imported_items( $request ) { $delete = \WC_Admin_Reports_Sync::delete_report_data(); @@ -274,7 +274,7 @@ class Import extends Reports { * Get the status of the current import. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_import_status( $request ) { $result = array( @@ -296,7 +296,7 @@ class Import extends Reports { * Get the total orders and customers based on user supplied params. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_import_totals( $request ) { $query_args = $this->prepare_objects_query( $request ); diff --git a/src/RestApi/Version4/Controllers/Reports/OrderStats.php b/src/RestApi/Version4/Controllers/Reports/OrderStats.php index faf23e7a79d..1b0224d2026 100644 --- a/src/RestApi/Version4/Controllers/Reports/OrderStats.php +++ b/src/RestApi/Version4/Controllers/Reports/OrderStats.php @@ -110,7 +110,7 @@ class OrderStats extends Reports { * * @param Array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -127,7 +127,7 @@ class OrderStats extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Orders.php b/src/RestApi/Version4/Controllers/Reports/Orders.php index e0bdb1f1f8a..622b4a18763 100644 --- a/src/RestApi/Version4/Controllers/Reports/Orders.php +++ b/src/RestApi/Version4/Controllers/Reports/Orders.php @@ -99,7 +99,7 @@ class Orders extends Reports { * * @param stdClass $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -117,7 +117,7 @@ class Orders extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php index 88e485eab09..7c4dae39174 100644 --- a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php +++ b/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php @@ -323,7 +323,7 @@ class PerformanceIndicators extends Reports { * * @param stdClass $stat_data Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $stat_data, $request ) { $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; @@ -340,7 +340,7 @@ class PerformanceIndicators extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/ProductStats.php b/src/RestApi/Version4/Controllers/Reports/ProductStats.php index 19c7e5e40a3..2794e7e56d9 100644 --- a/src/RestApi/Version4/Controllers/Reports/ProductStats.php +++ b/src/RestApi/Version4/Controllers/Reports/ProductStats.php @@ -115,7 +115,7 @@ class ProductStats extends Reports { * * @param Array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -132,7 +132,7 @@ class ProductStats extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Products.php b/src/RestApi/Version4/Controllers/Reports/Products.php index 299687f04f1..ba420c494ec 100644 --- a/src/RestApi/Version4/Controllers/Reports/Products.php +++ b/src/RestApi/Version4/Controllers/Reports/Products.php @@ -93,7 +93,7 @@ class Products extends Reports { * * @param Array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -111,7 +111,7 @@ class Products extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php index 38a586e4dff..8d58294c2e4 100644 --- a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php +++ b/src/RestApi/Version4/Controllers/Reports/RevenueStats.php @@ -99,7 +99,7 @@ class RevenueStats extends Reports { * * @param Array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -116,7 +116,7 @@ class RevenueStats extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Stock.php b/src/RestApi/Version4/Controllers/Reports/Stock.php index 4967d31aaba..6bcaeb4d4cd 100644 --- a/src/RestApi/Version4/Controllers/Reports/Stock.php +++ b/src/RestApi/Version4/Controllers/Reports/Stock.php @@ -183,7 +183,7 @@ class Stock extends Reports { * * @param WC_Product $product Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $product, $request ) { $data = array( @@ -209,7 +209,7 @@ class Stock extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/StockStats.php b/src/RestApi/Version4/Controllers/Reports/StockStats.php index df3b371c1cb..db704677959 100644 --- a/src/RestApi/Version4/Controllers/Reports/StockStats.php +++ b/src/RestApi/Version4/Controllers/Reports/StockStats.php @@ -45,7 +45,7 @@ class StockStats extends Reports { * * @param WC_Product $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -62,7 +62,7 @@ class StockStats extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/TaxStats.php b/src/RestApi/Version4/Controllers/Reports/TaxStats.php index 3b15000dacf..1c816c4d857 100644 --- a/src/RestApi/Version4/Controllers/Reports/TaxStats.php +++ b/src/RestApi/Version4/Controllers/Reports/TaxStats.php @@ -126,7 +126,7 @@ class TaxStats extends Reports { * * @param stdClass $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = get_object_vars( $report ); @@ -143,7 +143,7 @@ class TaxStats extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Taxes.php b/src/RestApi/Version4/Controllers/Reports/Taxes.php index 4c59faf3838..9ebc4e29d89 100644 --- a/src/RestApi/Version4/Controllers/Reports/Taxes.php +++ b/src/RestApi/Version4/Controllers/Reports/Taxes.php @@ -91,7 +91,7 @@ class Taxes extends Reports { * * @param stdClass $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; @@ -107,7 +107,7 @@ class Taxes extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Reports/Variations.php b/src/RestApi/Version4/Controllers/Reports/Variations.php index 3d162c472c5..988e40f761e 100644 --- a/src/RestApi/Version4/Controllers/Reports/Variations.php +++ b/src/RestApi/Version4/Controllers/Reports/Variations.php @@ -93,7 +93,7 @@ class Variations extends Reports { * * @param array $report Report data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $report, $request ) { $data = $report; @@ -111,7 +111,7 @@ class Variations extends Reports { * * Allows modification of the report data right before it is returned. * - * @param WP_REST_Response $response The response object. + * @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. */ diff --git a/src/RestApi/Version4/Controllers/Settings.php b/src/RestApi/Version4/Controllers/Settings.php index 28e43e29d54..68aca43c5be 100644 --- a/src/RestApi/Version4/Controllers/Settings.php +++ b/src/RestApi/Version4/Controllers/Settings.php @@ -75,7 +75,7 @@ class Settings extends AbstractController { * Update a setting. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function update_item( $request ) { $options_controller = new \WC_REST_Setting_Options_Controller(); @@ -89,7 +89,7 @@ class Settings extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); @@ -145,7 +145,7 @@ class Settings extends AbstractController { * @since 3.0.0 * @param array $item Group object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { $context = empty( $request['context'] ) ? 'view' : $request['context']; diff --git a/src/RestApi/Version4/Controllers/SettingsOptions.php b/src/RestApi/Version4/Controllers/SettingsOptions.php index f4bbcacde72..20f71ed9db4 100644 --- a/src/RestApi/Version4/Controllers/SettingsOptions.php +++ b/src/RestApi/Version4/Controllers/SettingsOptions.php @@ -106,7 +106,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $setting = $this->get_setting( $request['group_id'], $request['id'] ); @@ -125,7 +125,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $settings = $this->get_group_settings( $request['group_id'] ); @@ -277,7 +277,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Full details about the request. - * @return array Of \WP_Error or WP_REST_Response. + * @return array Of \WP_Error or \WP_REST_Response. */ public function batch_items( $request ) { // Get the request params. @@ -304,7 +304,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function update_item( $request ) { $setting = $this->get_setting( $request['group_id'], $request['id'] ); @@ -347,7 +347,7 @@ class SettingsOptions extends AbstractController { * @since 3.0.0 * @param object $item Setting object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { unset( $item['option_key'] ); diff --git a/src/RestApi/Version4/Controllers/ShippingMethods.php b/src/RestApi/Version4/Controllers/ShippingMethods.php index 3f8174386f0..529c2f92d53 100644 --- a/src/RestApi/Version4/Controllers/ShippingMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingMethods.php @@ -95,7 +95,7 @@ class ShippingMethods extends AbstractController { * Get shipping methods. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $wc_shipping = \WC_Shipping::instance(); @@ -112,7 +112,7 @@ class ShippingMethods extends AbstractController { * Get a single Shipping Method. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function get_item( $request ) { $wc_shipping = \WC_Shipping::instance(); @@ -132,7 +132,7 @@ class ShippingMethods extends AbstractController { * * @param WC_Shipping_Method $method Shipping method object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $method, $request ) { $data = array( @@ -153,7 +153,7 @@ class ShippingMethods extends AbstractController { /** * Filter shipping methods object returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WC_Shipping_Method $method Shipping method object used to create response. * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php index 706b780d2c3..a6c004695ed 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneLocations.php @@ -51,7 +51,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { * Get all Shipping Zone Locations. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function get_items( $request ) { $zone = $this->get_zone( (int) $request['id'] ); @@ -76,7 +76,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { * Update all Shipping Zone Locations. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function update_items( $request ) { $zone = $this->get_zone( (int) $request['id'] ); @@ -120,7 +120,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { * * @param array $item Shipping Zone Location. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response + * @return \WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { $context = empty( $request['context'] ) ? 'view' : $request['context']; diff --git a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php index 2401e4bc37e..d731ad4f45e 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php +++ b/src/RestApi/Version4/Controllers/ShippingZoneMethods.php @@ -102,7 +102,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Get a single Shipping Zone Method. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function get_item( $request ) { $zone = $this->get_zone( $request['zone_id'] ); @@ -135,7 +135,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Get all Shipping Zone Methods. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function get_items( $request ) { $zone = $this->get_zone( $request['zone_id'] ); @@ -235,7 +235,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { // Actually delete. $zone->delete_shipping_method( $instance_id ); - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -247,7 +247,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Fires after a method is deleted via the REST API. * * @param object $method - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_shipping_zone_method', $method, $response, $request ); @@ -259,7 +259,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * Update A Single Shipping Zone Method. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function update_item( $request ) { $zone = $this->get_zone( $request['zone_id'] ); @@ -352,7 +352,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { * * @param array $item Shipping Zone Method. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response + * @return \WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { $method = array( diff --git a/src/RestApi/Version4/Controllers/ShippingZones.php b/src/RestApi/Version4/Controllers/ShippingZones.php index 654c1a6dbde..55732940534 100644 --- a/src/RestApi/Version4/Controllers/ShippingZones.php +++ b/src/RestApi/Version4/Controllers/ShippingZones.php @@ -92,7 +92,7 @@ class ShippingZones extends AbstractShippingZonesController { * Get a single Shipping Zone. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function get_item( $request ) { $zone = $this->get_zone( $request->get_param( 'id' ) ); @@ -112,7 +112,7 @@ class ShippingZones extends AbstractShippingZonesController { * Get all Shipping Zones. * * @param \WP_REST_Request $request Request data. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function get_items( $request ) { $rest_of_the_world = \WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); @@ -218,7 +218,7 @@ class ShippingZones extends AbstractShippingZonesController { $previous = $this->get_item( $request ); $zone->delete(); - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -234,7 +234,7 @@ class ShippingZones extends AbstractShippingZonesController { * * @param array $item Shipping Zone. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response + * @return \WP_REST_Response $response */ public function prepare_item_for_response( $item, $request ) { $data = array( diff --git a/src/RestApi/Version4/Controllers/SystemStatus.php b/src/RestApi/Version4/Controllers/SystemStatus.php index e9c34ae1018..e7da5376d68 100644 --- a/src/RestApi/Version4/Controllers/SystemStatus.php +++ b/src/RestApi/Version4/Controllers/SystemStatus.php @@ -60,7 +60,7 @@ class SystemStatus extends AbstractController { * Get a system status info, by section. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $schema = $this->get_item_schema(); @@ -1162,7 +1162,7 @@ class SystemStatus extends AbstractController { * * @param array $system_status System status data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response + * @return \WP_REST_Response */ public function prepare_item_for_response( $system_status, $request ) { $data = $this->add_additional_fields_to_object( $system_status, $request ); @@ -1173,7 +1173,7 @@ class SystemStatus extends AbstractController { /** * Filter the system status returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param mixed $system_status System status * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/SystemStatusTools.php b/src/RestApi/Version4/Controllers/SystemStatusTools.php index e1edacd817f..9ec0e03a034 100644 --- a/src/RestApi/Version4/Controllers/SystemStatusTools.php +++ b/src/RestApi/Version4/Controllers/SystemStatusTools.php @@ -206,7 +206,7 @@ class SystemStatusTools extends AbstractController { * Get a list of system status tools. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $tools = array(); @@ -232,7 +232,7 @@ class SystemStatusTools extends AbstractController { * Return a single tool. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $tools = $this->get_tools(); @@ -257,7 +257,7 @@ class SystemStatusTools extends AbstractController { * Update (execute) a tool. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function update_item( $request ) { $tools = $this->get_tools(); @@ -294,7 +294,7 @@ class SystemStatusTools extends AbstractController { * * @param array $item Object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { $context = empty( $request['context'] ) ? 'view' : $request['context']; diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/RestApi/Version4/Controllers/TaxClasses.php index d6d90a667de..724640dd646 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/RestApi/Version4/Controllers/TaxClasses.php @@ -158,7 +158,7 @@ class TaxClasses extends AbstractController { * Create a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function create_item( $request ) { $exists = false; @@ -210,7 +210,7 @@ class TaxClasses extends AbstractController { * Delete a single tax class. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function delete_item( $request ) { global $wpdb; @@ -265,7 +265,7 @@ class TaxClasses extends AbstractController { // Delete tax rates in the selected class. $wpdb->delete( $wpdb->prefix . 'woocommerce_tax_rates', array( 'tax_rate_class' => $tax_class['slug'] ), array( '%s' ) ); - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -277,7 +277,7 @@ class TaxClasses extends AbstractController { * Fires after a tax class is deleted via the REST API. * * @param stdClass $tax_class The tax data. - * @param WP_REST_Response $response The response returned from the API. + * @param \WP_REST_Response $response The response returned from the API. * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_tax', (object) $tax_class, $response, $request ); @@ -290,7 +290,7 @@ class TaxClasses extends AbstractController { * * @param array $tax_class Tax class data. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $tax_class, $request ) { $data = $tax_class; @@ -307,7 +307,7 @@ class TaxClasses extends AbstractController { /** * Filter tax object returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param stdClass $tax_class Tax object used to create response. * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/Taxes.php b/src/RestApi/Version4/Controllers/Taxes.php index f5bc66417ee..ca787b552cc 100644 --- a/src/RestApi/Version4/Controllers/Taxes.php +++ b/src/RestApi/Version4/Controllers/Taxes.php @@ -197,7 +197,7 @@ class Taxes extends AbstractController { * Get all taxes and allow filtering by tax code. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { global $wpdb; @@ -376,7 +376,7 @@ class Taxes extends AbstractController { * Create a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -409,7 +409,7 @@ class Taxes extends AbstractController { * Get a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; @@ -429,7 +429,7 @@ class Taxes extends AbstractController { * Update a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function update_item( $request ) { $id = (int) $request['id']; @@ -463,7 +463,7 @@ class Taxes extends AbstractController { * Delete a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function delete_item( $request ) { global $wpdb; @@ -495,7 +495,7 @@ class Taxes extends AbstractController { * Fires after a tax is deleted via the REST API. * * @param stdClass $tax The tax data. - * @param WP_REST_Response $response The response returned from the API. + * @param \WP_REST_Response $response The response returned from the API. * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request ); @@ -508,7 +508,7 @@ class Taxes extends AbstractController { * * @param stdClass $tax Tax object. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $tax, $request ) { global $wpdb; @@ -559,7 +559,7 @@ class Taxes extends AbstractController { /** * Filter tax object returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param stdClass $tax Tax object used to create response. * @param \WP_REST_Request $request Request object. */ diff --git a/src/RestApi/Version4/Controllers/Webhooks.php b/src/RestApi/Version4/Controllers/Webhooks.php index 86e4adc650a..e18dab3ff50 100644 --- a/src/RestApi/Version4/Controllers/Webhooks.php +++ b/src/RestApi/Version4/Controllers/Webhooks.php @@ -222,7 +222,7 @@ class Webhooks extends AbstractController { * Get all webhooks. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { $args = array(); @@ -292,7 +292,7 @@ class Webhooks extends AbstractController { * Get a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; @@ -311,7 +311,7 @@ class Webhooks extends AbstractController { * Create a single webhook. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -371,7 +371,7 @@ class Webhooks extends AbstractController { * Update a single webhook. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|WP_REST_Response + * @return \WP_Error\WP_REST_Response */ public function update_item( $request ) { $id = (int) $request['id']; @@ -445,7 +445,7 @@ class Webhooks extends AbstractController { * Delete a single webhook. * * @param \WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|\WP_Error + * @return \WP_REST_Response|\WP_Error */ public function delete_item( $request ) { $id = (int) $request['id']; @@ -469,7 +469,7 @@ class Webhooks extends AbstractController { /* translators: %s: post type */ return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } - $response = new WP_REST_Response(); + $response = new \WP_REST_Response(); $response->set_data( array( 'deleted' => true, @@ -481,7 +481,7 @@ class Webhooks extends AbstractController { * Fires after a single item is deleted or trashed via the REST API. * * @param WC_Webhook $webhook The deleted or trashed item. - * @param WP_REST_Response $response The response data. + * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ do_action( 'woocommerce_rest_delete_webhook_object', $webhook, $response, $request ); @@ -547,7 +547,7 @@ class Webhooks extends AbstractController { * * @param int $id Webhook ID. * @param \WP_REST_Request $request Request object. - * @return WP_REST_Response $response + * @return \WP_REST_Response $response */ public function prepare_item_for_response( $id, $request ) { $webhook = wc_get_webhook( $id ); @@ -583,7 +583,7 @@ class Webhooks extends AbstractController { /** * Filter webhook object returned from the REST API. * - * @param WP_REST_Response $response The response object. + * @param \WP_REST_Response $response The response object. * @param WC_Webhook $webhook Webhook object used to create response. * @param \WP_REST_Request $request Request object. */ diff --git a/unit-tests/AbstractReportsTest.php b/unit-tests/AbstractReportsTest.php new file mode 100644 index 00000000000..39d7a6a4b41 --- /dev/null +++ b/unit-tests/AbstractReportsTest.php @@ -0,0 +1,48 @@ +markTestSkipped( 'Skipping reports tests - woocommerce-admin not found.' ); + return; + } + + parent::setUp(); + + $this->user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + + wp_set_current_user( $this->user ); + + global $wpdb; + $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Orders_Stats_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Products_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Coupons_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Customers_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + } + +} diff --git a/unit-tests/AbstractRestApiTest.php b/unit-tests/AbstractRestApiTest.php index b40b34d8a88..7b6b897da90 100644 --- a/unit-tests/AbstractRestApiTest.php +++ b/unit-tests/AbstractRestApiTest.php @@ -22,6 +22,9 @@ namespace WooCommerce\RestApi\UnitTests; defined( 'ABSPATH' ) || exit; use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; /** * Abstract Rest API Test Class diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index 337210bca6d..7c3ae49ad40 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -26,7 +26,7 @@ class Bootstrap { */ public static function init() { self::$wc_tests_dir = dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce/tests'; - self::$wp_tests_dir = getenv( 'WP_TESTS_DIR' ); + self::$wp_tests_dir = getenv( 'WP_TESTS_DIR' ); if ( ! self::$wp_tests_dir ) { self::$wp_tests_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; @@ -36,6 +36,15 @@ class Bootstrap { self::load_framework(); } + /** + * Should we skip WC Admin Reports tests? + * + * @return boolean + */ + public static function skip_report_tests() { + return ! file_exists( dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php' ); + } + /** * Setup hooks. */ @@ -46,6 +55,10 @@ class Bootstrap { \tests_add_filter( 'muplugins_loaded', function() { require_once dirname( dirname( __DIR__ ) ) . '/woocommerce/woocommerce.php'; require_once dirname( __DIR__ ) . '/woocommerce-rest-api.php'; + + if ( file_exists( dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php' ) ) { + require_once dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php'; + } } ); \tests_add_filter( 'setup_theme', function() { @@ -57,6 +70,13 @@ class Bootstrap { \WC_Install::install(); + if ( ! self::skip_report_tests() ) { + echo esc_html( 'Installing WooCommerce Admin...' . PHP_EOL ); + require_once dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/includes/class-wc-admin-install.php'; + \WC_Admin_Install::create_tables(); + \WC_Admin_Install::create_events(); + } + $GLOBALS['wp_roles'] = null; // WPCS: override ok. \wp_roles(); } ); @@ -83,9 +103,9 @@ class Bootstrap { require_once __DIR__ . '/Helpers/ProductHelper.php'; require_once __DIR__ . '/Helpers/ShippingHelper.php'; require_once __DIR__ . '/Helpers/SettingsHelper.php'; - require_once __DIR__ . '/Helpers/ReportsHelper.php'; require_once __DIR__ . '/Helpers/QueueHelper.php'; require_once __DIR__ . '/AbstractRestApiTest.php'; + require_once __DIR__ . '/AbstractReportsTest.php'; } } diff --git a/unit-tests/Helpers/ReportsHelper.php b/unit-tests/Helpers/ReportsHelper.php deleted file mode 100644 index 0c2027699a7..00000000000 --- a/unit-tests/Helpers/ReportsHelper.php +++ /dev/null @@ -1,27 +0,0 @@ -query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Orders_Stats_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Products_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Coupons_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Customers_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - } -} diff --git a/unit-tests/Tests/Blocks/products-attributes-terms.php b/unit-tests/Tests/Blocks/ProductAttributeTerms.php similarity index 91% rename from unit-tests/Tests/Blocks/products-attributes-terms.php rename to unit-tests/Tests/Blocks/ProductAttributeTerms.php index afe8cd3c4d8..4febcaf1a72 100644 --- a/unit-tests/Tests/Blocks/products-attributes-terms.php +++ b/unit-tests/Tests/Blocks/ProductAttributeTerms.php @@ -3,12 +3,20 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Blocks; + +defined( 'ABSPATH' ) || exit; + +use \WP_REST_Request; +use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; + /** * Product Controller "products attributes terms" REST API Test * * @since 3.6.0 */ -class WC_Tests_API_Products_Attributes_Terms_Controller extends WC_REST_Unit_Test_Case { +class ProductAttributeTerms extends WC_REST_Unit_Test_Case { /** * Endpoints. diff --git a/unit-tests/Tests/Blocks/products-attributes.php b/unit-tests/Tests/Blocks/ProductAttributes.php similarity index 91% rename from unit-tests/Tests/Blocks/products-attributes.php rename to unit-tests/Tests/Blocks/ProductAttributes.php index b21990dc0c2..6389a097f96 100644 --- a/unit-tests/Tests/Blocks/products-attributes.php +++ b/unit-tests/Tests/Blocks/ProductAttributes.php @@ -3,12 +3,20 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Blocks; + +defined( 'ABSPATH' ) || exit; + +use \WP_REST_Request; +use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; + /** * Product Controller "products attributes" REST API Test * * @since 3.6.0 */ -class WC_Tests_API_Products_Attributes_Controller extends WC_REST_Unit_Test_Case { +class ProductAttributes extends WC_REST_Unit_Test_Case { /** * Endpoints. diff --git a/unit-tests/Tests/Blocks/products-categories.php b/unit-tests/Tests/Blocks/ProductCategories.php similarity index 92% rename from unit-tests/Tests/Blocks/products-categories.php rename to unit-tests/Tests/Blocks/ProductCategories.php index 3aca14621c5..c143942e196 100644 --- a/unit-tests/Tests/Blocks/products-categories.php +++ b/unit-tests/Tests/Blocks/ProductCategories.php @@ -3,12 +3,20 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Blocks; + +defined( 'ABSPATH' ) || exit; + +use \WP_REST_Request; +use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; + /** * Product Categories Controller REST API Test * * @since 3.6.0 */ -class WC_Tests_API_Products_Categories_Controller extends WC_REST_Unit_Test_Case { +class ProductCategories extends WC_REST_Unit_Test_Case { /** * Endpoints. diff --git a/unit-tests/Tests/Blocks/products.php b/unit-tests/Tests/Blocks/products.php index e8062c9c6a9..2da60b143cc 100644 --- a/unit-tests/Tests/Blocks/products.php +++ b/unit-tests/Tests/Blocks/products.php @@ -3,12 +3,20 @@ * @package WooCommerce\Tests\API */ +namespace WooCommerce\RestApi\UnitTests\Tests\Blocks; + +defined( 'ABSPATH' ) || exit; + +use \WP_REST_Request; +use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; + /** * Blocks Product Controller REST API Test * * @since 3.6.0 */ -class WC_Tests_API_Products_Controller extends WC_REST_Unit_Test_Case { +class Products extends WC_REST_Unit_Test_Case { /** * Endpoints. diff --git a/unit-tests/Tests/Version4/Functions.php b/unit-tests/Tests/Version4/Functions.php deleted file mode 100644 index 5d5a01ebadf..00000000000 --- a/unit-tests/Tests/Version4/Functions.php +++ /dev/null @@ -1,257 +0,0 @@ -http_responder = array( $this, 'mock_http_responses' ); - - $upload_dir_info = wp_upload_dir(); - $this->upload_dir_path = $upload_dir_info['path']; - $this->upload_dir_url = $upload_dir_info['url']; - $this->file_name = 'Dr1Bczxq4q.png'; - } - - /** - * Run tear down code for unit tests. - */ - public function tearDown() { - parent::tearDown(); - - // remove files created in the wc_rest_upload_image_from_url() tests. - $file_path = $this->upload_dir_path . '/' . $this->file_name; - - if ( file_exists( $file_path ) ) { - unlink( $file_path ); - } - } - - /** - * Test wc_rest_prepare_date_response(). - * - * @since 2.6.0 - */ - public function test_wc_rest_prepare_date_response() { - $this->assertEquals( '2016-06-06T06:06:06', wc_rest_prepare_date_response( '2016-06-06 06:06:06' ) ); - } - - /** - * Test wc_rest_upload_image_from_url() should return error when unable to download image. - */ - public function test_wc_rest_upload_image_from_url_should_return_error_when_unable_to_download_image() { - $expected_error_message = 'Error getting remote image http://somedomain.com/nonexistent-image.png. Error: Not found.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/nonexistent-image.png' ); - - $this->assertIsWPError( $result ); - $this->assertEquals( $expected_error_message, $result->get_error_message() ); - } - - /** - * Test wc_rest_upload_image_from_url() should return error when invalid image is passed. - * - * @requires PHP 5.4 - */ - public function test_wc_rest_upload_image_from_url_should_return_error_when_invalid_image_is_passed() { - // empty file. - $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-1.png' ); - - $this->assertIsWPError( $result ); - $this->assertEquals( $expected_error_message, $result->get_error_message() ); - - // unsupported mime type. - $expected_error_message = 'Invalid image: Sorry, this file type is not permitted for security reasons.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-2.png' ); - - $this->assertIsWPError( $result ); - $this->assertEquals( $expected_error_message, $result->get_error_message() ); - } - - /** - * Test wc_rest_upload_image_from_url() should download image and return an array containing - * information about it. - * - * @requires PHP 5.4 - */ - public function test_wc_rest_upload_image_from_url_should_download_image_and_return_array() { - $expected_result = array( - 'file' => $this->upload_dir_path . '/' . $this->file_name, - 'url' => $this->upload_dir_url . '/' . $this->file_name, - 'type' => 'image/png', - ); - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/' . $this->file_name ); - - $this->assertEquals( $expected_result, $result ); - } - - /** - * Test wc_rest_set_uploaded_image_as_attachment(). - * - * @since 2.6.0 - */ - public function test_wc_rest_set_uploaded_image_as_attachment() { - $this->assertInternalType( - 'int', - wc_rest_set_uploaded_image_as_attachment( - array( - 'file' => '', - 'url' => '', - ) - ) - ); - } - - /** - * Test wc_rest_validate_reports_request_arg(). - * - * @since 2.6.0 - */ - public function test_wc_rest_validate_reports_request_arg() { - $request = new WP_REST_Request( - 'GET', - '/wc/v4/foo', - array( - 'args' => array( - 'date' => array( - 'type' => 'string', - 'format' => 'date', - ), - ), - ) - ); - - // Success. - $this->assertTrue( wc_rest_validate_reports_request_arg( '2016-06-06', $request, 'date' ) ); - - // Error. - $error = wc_rest_validate_reports_request_arg( 'foo', $request, 'date' ); - $this->assertEquals( 'The date you provided is invalid.', $error->get_error_message() ); - } - - /** - * Test wc_rest_urlencode_rfc3986(). - * - * @since 2.6.0 - */ - public function test_wc_rest_urlencode_rfc3986() { - $this->assertEquals( 'https%3A%2F%2Fwoocommerce.com%2F', wc_rest_urlencode_rfc3986( 'https://woocommerce.com/' ) ); - } - - /** - * Test wc_rest_check_post_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_post_permissions() { - $this->assertFalse( wc_rest_check_post_permissions( 'shop_order' ) ); - } - - /** - * Test wc_rest_check_user_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_user_permissions() { - $this->assertFalse( wc_rest_check_user_permissions() ); - } - - /** - * Test wc_rest_check_product_term_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_product_term_permissions() { - $this->assertFalse( wc_rest_check_product_term_permissions( 'product_cat' ) ); - } - - /** - * Test wc_rest_check_manager_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_manager_permissions() { - $this->assertFalse( wc_rest_check_manager_permissions( 'reports' ) ); - } - - /** - * Helper method to define mocked HTTP responses using WP_HTTP_TestCase. - * Thanks to WP_HTTP_TestCase, it is not necessary to perform a regular request - * to an external server which would significantly slow down the tests. - * - * This function is called by WP_HTTP_TestCase::http_request_listner(). - * - * @param array $request Request arguments. - * @param string $url URL of the request. - * - * @return array|false mocked response or false to let WP perform a regular request. - */ - protected function mock_http_responses( $request, $url ) { - $mocked_response = false; - - if ( 'http://somedomain.com/nonexistent-image.png' === $url ) { - $mocked_response = array( - 'response' => array( - 'code' => 404, - 'message' => 'Not found.', - ), - ); - } elseif ( 'http://somedomain.com/invalid-image-1.png' === $url ) { - // empty image. - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } elseif ( 'http://somedomain.com/invalid-image-2.png' === $url ) { - // image with an unsupported mime type. - // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( WC_Unit_Tests_Bootstrap::instance()->tests_dir . '/data/file.txt', $request['filename'] ); - - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } elseif ( 'http://somedomain.com/' . $this->file_name === $url ) { - // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( WC_Unit_Tests_Bootstrap::instance()->tests_dir . '/data/Dr1Bczxq4q.png', $request['filename'] ); - - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } - - return $mocked_response; - } -} diff --git a/unit-tests/Tests/Version4/Orders.php b/unit-tests/Tests/Version4/Orders.php index 849fb8a7e12..7bb2feb98d3 100644 --- a/unit-tests/Tests/Version4/Orders.php +++ b/unit-tests/Tests/Version4/Orders.php @@ -10,9 +10,6 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; -use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; /** * Abstract Rest API Test Class diff --git a/unit-tests/Tests/Version4/Reports/Categories.php b/unit-tests/Tests/Version4/Reports/Categories.php index 99f48c69212..ce84c1e9deb 100644 --- a/unit-tests/Tests/Version4/Reports/Categories.php +++ b/unit-tests/Tests/Version4/Reports/Categories.php @@ -10,16 +10,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Class Categories */ -class Categories extends WC_REST_Unit_Test_Case { +class Categories extends AbstractReportsTest { /** * Endpoints. @@ -28,21 +24,6 @@ class Categories extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/categories'; - /** - * Setup test reports categories data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -60,9 +41,6 @@ class Categories extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - ReportsHelper::reset_stats_dbs(); - wp_set_current_user( $this->user ); - // Populate all of the data. $product = new WC_Product_Simple(); $product->set_name( 'Test Product' ); @@ -100,11 +78,8 @@ class Categories extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports_categories_param() { - ReportsHelper::reset_stats_dbs(); - wp_set_current_user( $this->user ); - // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); @@ -174,8 +149,6 @@ class Categories extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/Coupons.php b/unit-tests/Tests/Version4/Reports/Coupons.php index 16cd2cb728e..5aecfd0903f 100644 --- a/unit-tests/Tests/Version4/Reports/Coupons.php +++ b/unit-tests/Tests/Version4/Reports/Coupons.php @@ -9,17 +9,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Class Coupons */ -class Coupons extends WC_REST_Unit_Test_Case { +class Coupons extends AbstractReportsTest { /** * Endpoints. @@ -28,19 +23,6 @@ class Coupons extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/coupons'; - /** - * Setup test reports products data. - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. */ @@ -54,9 +36,6 @@ class Coupons extends WC_REST_Unit_Test_Case { * Test getting basic reports. */ public function test_get_reports() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - // Simple product. $product = new WC_Product_Simple(); $product->set_name( 'Test Product' ); @@ -118,9 +97,6 @@ class Coupons extends WC_REST_Unit_Test_Case { * Test getting basic reports with the `coupons` param. */ public function test_get_reports_coupons_param() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - // Simple product. $product = new WC_Product_Simple(); $product->set_name( 'Test Product' ); @@ -183,8 +159,6 @@ class Coupons extends WC_REST_Unit_Test_Case { * Test reports schema. */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/CouponsStats.php b/unit-tests/Tests/Version4/Reports/CouponsStats.php index 981c481d7b0..f59a9d0ba2c 100644 --- a/unit-tests/Tests/Version4/Reports/CouponsStats.php +++ b/unit-tests/Tests/Version4/Reports/CouponsStats.php @@ -9,17 +9,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Class CouponsStats */ -class CouponsStats extends WC_REST_Unit_Test_Case { +class CouponsStats extends AbstractReportsTest { /** * Endpoints. @@ -28,19 +23,6 @@ class CouponsStats extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/coupons/stats'; - /** - * Setup test reports products stats data. - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. */ @@ -54,9 +36,6 @@ class CouponsStats extends WC_REST_Unit_Test_Case { * Test getting reports. */ public function test_get_reports() { - ReportsHelper::reset_stats_dbs(); - wp_set_current_user( $this->user ); - // Populate all of the data. // Simple product. $product = new WC_Product_Simple(); @@ -153,8 +132,6 @@ class CouponsStats extends WC_REST_Unit_Test_Case { * Test reports schema. */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/CustomerStats.php b/unit-tests/Tests/Version4/Reports/CustomerStats.php index 27dfc5d4030..db4e35a14f8 100644 --- a/unit-tests/Tests/Version4/Reports/CustomerStats.php +++ b/unit-tests/Tests/Version4/Reports/CustomerStats.php @@ -10,12 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Customers Stats REST API Test Class @@ -23,7 +18,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class CustomerStats extends WC_REST_Unit_Test_Case { +class CustomerStats extends AbstractReportsTest { /** * Endpoint. * @@ -31,21 +26,6 @@ class CustomerStats extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/customers/stats'; - /** - * Setup test reports products data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -63,8 +43,6 @@ class CustomerStats extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -96,9 +74,6 @@ class CustomerStats extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - $test_customers = array(); // Create 10 test customers. diff --git a/unit-tests/Tests/Version4/Reports/Customers.php b/unit-tests/Tests/Version4/Reports/Customers.php index e270855af72..af136a77e51 100644 --- a/unit-tests/Tests/Version4/Reports/Customers.php +++ b/unit-tests/Tests/Version4/Reports/Customers.php @@ -10,12 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Customers REST API Test Class @@ -23,7 +18,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class Customers extends WC_REST_Unit_Test_Case { +class Customers extends AbstractReportsTest { /** * Endpoint. * @@ -31,21 +26,6 @@ class Customers extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/customers'; - /** - * Setup test reports products data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -148,12 +128,12 @@ class Customers extends WC_REST_Unit_Test_Case { $product->set_regular_price( 25 ); $product->save(); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $admin_id, $product ); + $order = OrderHelper::create_order( $admin_id, $product ); $order->set_status( 'processing' ); $order->set_total( 100 ); $order->save(); - \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'per_page' => 10 ) ); @@ -166,7 +146,7 @@ class Customers extends WC_REST_Unit_Test_Case { $this->assertEquals( $admin_id, $reports[0]['user_id'] ); // Creating a customer should show up regardless of orders. - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'customer', 'password', 'customer@example.com' ); + $customer = CustomerHelper::create_customer( 'customer', 'password', 'customer@example.com' ); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( @@ -194,9 +174,6 @@ class Customers extends WC_REST_Unit_Test_Case { public function test_get_reports() { global $wpdb; - wp_set_current_user( $this->user ); - \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper::reset_stats_dbs(); - $test_customers = array(); $customer_names = array( 'Alice', 'Betty', 'Catherine', 'Dan', 'Eric', 'Fred', 'Greg', 'Henry', 'Ivan', 'Justin' ); @@ -205,25 +182,25 @@ class Customers extends WC_REST_Unit_Test_Case { for ( $i = 1; $i <= 10; $i++ ) { $name = $customer_names[ $i - 1 ]; $email = 'customer+' . strtolower( $name ) . '@example.com'; - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( "customer{$i}", 'password', $email ); + $customer = CustomerHelper::create_customer( "customer{$i}", 'password', $email ); $customer->set_first_name( $name ); $customer->save(); $test_customers[] = $customer; } // Create a test product for use in an order. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); // Place an order for the first test customer. - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $test_customers[0]->get_id(), $product ); + $order = OrderHelper::create_order( $test_customers[0]->get_id(), $product ); $order->set_status( 'processing' ); $order->set_total( 100 ); $order->save(); - \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( @@ -342,8 +319,6 @@ class Customers extends WC_REST_Unit_Test_Case { * Test customer first and last name. */ public function test_customer_name() { - wp_set_current_user( $this->user ); - $customer = wp_insert_user( array( 'user_login' => 'daenerys', @@ -353,7 +328,7 @@ class Customers extends WC_REST_Unit_Test_Case { ); // Test shipping name and empty billing name. - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $customer ); + $order = OrderHelper::create_order( $customer ); $order->set_billing_first_name( '' ); $order->set_billing_last_name( '' ); $order->set_shipping_first_name( 'Daenerys' ); @@ -362,7 +337,7 @@ class Customers extends WC_REST_Unit_Test_Case { $order->set_total( 100 ); $order->save(); - \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $response = $this->server->dispatch( $request ); @@ -379,7 +354,7 @@ class Customers extends WC_REST_Unit_Test_Case { $order->save(); do_action( 'woocommerce_update_customer', $customer ); - \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'orderby' => 'username' ) ); // Cache busting. @@ -401,7 +376,7 @@ class Customers extends WC_REST_Unit_Test_Case { ); do_action( 'woocommerce_update_customer', $customer ); - \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper::run_all_pending(); + QueueHelper::run_all_pending(); $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'orderby' => 'name' ) ); // Cache busting. diff --git a/unit-tests/Tests/Version4/Reports/DownloadStats.php b/unit-tests/Tests/Version4/Reports/DownloadStats.php index cbded71f99d..2940f3a20a8 100644 --- a/unit-tests/Tests/Version4/Reports/DownloadStats.php +++ b/unit-tests/Tests/Version4/Reports/DownloadStats.php @@ -9,10 +9,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Customers Stats REST API Test Class @@ -20,7 +17,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class DownloadStats extends WC_REST_Unit_Test_Case { +class DownloadStats extends AbstractReportsTest { /** * Endpoints. @@ -29,19 +26,6 @@ class DownloadStats extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/downloads/stats'; - /** - * Setup test reports downloads data. - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. */ @@ -56,8 +40,6 @@ class DownloadStats extends WC_REST_Unit_Test_Case { */ public function test_get_report() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); // Populate all of the data. $prod_download = new \WC_Product_Download(); @@ -142,8 +124,7 @@ class DownloadStats extends WC_REST_Unit_Test_Case { */ public function test_get_report_with_user_filter() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); + $time = time(); // First set of data. @@ -236,8 +217,6 @@ class DownloadStats extends WC_REST_Unit_Test_Case { */ public function test_get_report_orderby() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); // Populate all of the data. $prod_download = new \WC_Product_Download(); @@ -346,8 +325,6 @@ class DownloadStats extends WC_REST_Unit_Test_Case { * Test reports schema. */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/Downloads.php b/unit-tests/Tests/Version4/Reports/Downloads.php index e169a6531bd..cf8e3d905e5 100644 --- a/unit-tests/Tests/Version4/Reports/Downloads.php +++ b/unit-tests/Tests/Version4/Reports/Downloads.php @@ -9,10 +9,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Customers Stats REST API Test Class @@ -20,7 +17,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class Downloads extends WC_REST_Unit_Test_Case { +class Downloads extends AbstractReportsTest { /** * Endpoints. @@ -29,19 +26,6 @@ class Downloads extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/downloads'; - /** - * Setup test reports downloads data. - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. */ @@ -56,8 +40,6 @@ class Downloads extends WC_REST_Unit_Test_Case { */ public function test_get_report() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); // Populate all of the data. $prod_download = new \WC_Product_Download(); @@ -112,8 +94,7 @@ class Downloads extends WC_REST_Unit_Test_Case { */ public function filter_setup() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); + $time = time(); // First set of data. @@ -402,8 +383,6 @@ class Downloads extends WC_REST_Unit_Test_Case { * Test reports schema. */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/Import.php b/unit-tests/Tests/Version4/Reports/Import.php index 249f40ef3e2..875c9bfcdf1 100644 --- a/unit-tests/Tests/Version4/Reports/Import.php +++ b/unit-tests/Tests/Version4/Reports/Import.php @@ -9,10 +9,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Customers Stats REST API Test Class @@ -20,7 +17,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class Import extends WC_REST_Unit_Test_Case { +class Import extends AbstractReportsTest { /** * Endpoint. diff --git a/unit-tests/Tests/Version4/Reports/OrderStats.php b/unit-tests/Tests/Version4/Reports/OrderStats.php index e929e89307e..8152df41541 100644 --- a/unit-tests/Tests/Version4/Reports/OrderStats.php +++ b/unit-tests/Tests/Version4/Reports/OrderStats.php @@ -9,13 +9,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Class OrderStats */ -class OrderStats extends WC_REST_Unit_Test_Case { +class OrderStats extends AbstractReportsTest { /** * Endpoints. @@ -24,21 +23,6 @@ class OrderStats extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/orders/stats'; - /** - * Setup test reports orders data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -56,8 +40,6 @@ class OrderStats extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - wp_set_current_user( $this->user ); - // @todo Update after report interface is done. $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $reports = $response->get_data(); @@ -85,8 +67,6 @@ class OrderStats extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/Orders.php b/unit-tests/Tests/Version4/Reports/Orders.php index 29f32ab1d67..2f283602d5e 100644 --- a/unit-tests/Tests/Version4/Reports/Orders.php +++ b/unit-tests/Tests/Version4/Reports/Orders.php @@ -10,11 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Orders REST API Test Class @@ -22,7 +18,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class Orders extends WC_REST_Unit_Test_Case { +class Orders extends AbstractReportsTest { /** * Endpoints. @@ -31,21 +27,6 @@ class Orders extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/orders'; - /** - * Setup test reports orders data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -63,11 +44,8 @@ class Orders extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); @@ -117,8 +95,6 @@ class Orders extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php b/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php index cf2ee62639d..024daa95f8a 100644 --- a/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php +++ b/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php @@ -9,16 +9,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * PerformanceIndicators */ -class PerformanceIndicators extends WC_REST_Unit_Test_Case { +class PerformanceIndicators extends AbstractReportsTest { /** * Endpoints. @@ -27,19 +23,6 @@ class PerformanceIndicators extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/performance-indicators'; - /** - * Setup tests. - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. */ @@ -55,8 +38,6 @@ class PerformanceIndicators extends WC_REST_Unit_Test_Case { */ public function test_get_indicators() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); // Populate all of the data. We'll create an order and a download. $prod_download = new \WC_Product_Download(); @@ -129,8 +110,6 @@ class PerformanceIndicators extends WC_REST_Unit_Test_Case { */ public function test_get_indicators_empty_request() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); $time = time(); $request = new WP_REST_Request( 'GET', $this->endpoint ); @@ -159,8 +138,6 @@ class PerformanceIndicators extends WC_REST_Unit_Test_Case { * Test schema. */ public function test_indicators_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -178,8 +155,6 @@ class PerformanceIndicators extends WC_REST_Unit_Test_Case { * Test schema for /allowed indicators endpoint. */ public function test_indicators_schema_allowed() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint . '/allowed' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/ProductStats.php b/unit-tests/Tests/Version4/Reports/ProductStats.php index 551179464e2..f30b6e0a0de 100644 --- a/unit-tests/Tests/Version4/Reports/ProductStats.php +++ b/unit-tests/Tests/Version4/Reports/ProductStats.php @@ -10,16 +10,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Class ProductStats */ -class ProductStats extends WC_REST_Unit_Test_Case { +class ProductStats extends AbstractReportsTest { /** * Endpoints. @@ -28,21 +24,6 @@ class ProductStats extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/products/stats'; - /** - * Setup test reports products stats data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -60,9 +41,6 @@ class ProductStats extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - ReportsHelper::reset_stats_dbs(); - wp_set_current_user( $this->user ); - // Populate all of the data. $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); @@ -144,8 +122,6 @@ class ProductStats extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/Products.php b/unit-tests/Tests/Version4/Reports/Products.php index 989bd9f4ef2..abcdf5436bb 100644 --- a/unit-tests/Tests/Version4/Reports/Products.php +++ b/unit-tests/Tests/Version4/Reports/Products.php @@ -10,10 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Products REST API Test Class @@ -21,7 +18,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class Products extends WC_REST_Unit_Test_Case { +class Products extends AbstractReportsTest { /** * Endpoints. @@ -30,21 +27,6 @@ class Products extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/products'; - /** - * Setup test reports products data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -62,9 +44,6 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - // Populate all of the data. $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); @@ -99,9 +78,6 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports_products_param() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - // Populate all of the data. $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); @@ -166,8 +142,6 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/RevenueStats.php b/unit-tests/Tests/Version4/Reports/RevenueStats.php index e2d1b76c67e..10e8c44eac2 100644 --- a/unit-tests/Tests/Version4/Reports/RevenueStats.php +++ b/unit-tests/Tests/Version4/Reports/RevenueStats.php @@ -10,13 +10,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Class RevenueStats */ -class RevenueStats extends WC_REST_Unit_Test_Case { +class RevenueStats extends AbstractReportsTest { /** * Endpoints. @@ -32,21 +31,6 @@ class RevenueStats extends WC_REST_Unit_Test_Case { */ protected $orders = array(); - /** - * Setup test reports revenue data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * diff --git a/unit-tests/Tests/Version4/Reports/Stock.php b/unit-tests/Tests/Version4/Reports/Stock.php index bc15ecab33c..a435aea84a0 100644 --- a/unit-tests/Tests/Version4/Reports/Stock.php +++ b/unit-tests/Tests/Version4/Reports/Stock.php @@ -10,9 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Customers Stats REST API Test Class @@ -20,7 +18,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class Stock extends WC_REST_Unit_Test_Case { +class Stock extends AbstractReportsTest { /** * Endpoints. @@ -29,19 +27,6 @@ class Stock extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/stock'; - /** - * Setup test reports stock data. - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. */ @@ -55,9 +40,6 @@ class Stock extends WC_REST_Unit_Test_Case { * Test getting reports. */ public function test_get_reports() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - // Populate all of the data. $low_stock = new \WC_Product_Simple(); $low_stock->set_name( 'Test low stock' ); @@ -111,8 +93,6 @@ class Stock extends WC_REST_Unit_Test_Case { * Test reports schema. */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/StockStats.php b/unit-tests/Tests/Version4/Reports/StockStats.php index 937e7859c6d..55ed6736e2d 100644 --- a/unit-tests/Tests/Version4/Reports/StockStats.php +++ b/unit-tests/Tests/Version4/Reports/StockStats.php @@ -9,14 +9,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Class StockStats */ -class StockStats extends WC_REST_Unit_Test_Case { +class StockStats extends AbstractReportsTest { /** * Endpoints. @@ -25,19 +23,6 @@ class StockStats extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/stock/stats'; - /** - * Setup test reports stock data. - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. */ @@ -51,9 +36,6 @@ class StockStats extends WC_REST_Unit_Test_Case { * Test getting reports. */ public function test_get_reports() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - $number_of_low_stock = 3; for ( $i = 1; $i <= $number_of_low_stock; $i++ ) { $low_stock = new \WC_Product_Simple(); @@ -128,8 +110,6 @@ class StockStats extends WC_REST_Unit_Test_Case { * Test reports schema. */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/TaxStats.php b/unit-tests/Tests/Version4/Reports/TaxStats.php index 93a7ccd0327..607b3d17909 100644 --- a/unit-tests/Tests/Version4/Reports/TaxStats.php +++ b/unit-tests/Tests/Version4/Reports/TaxStats.php @@ -10,16 +10,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * TaxStats */ -class TaxStats extends WC_REST_Unit_Test_Case { +class TaxStats extends AbstractReportsTest { /** * Endpoints. @@ -28,21 +24,6 @@ class TaxStats extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/taxes/stats'; - /** - * Setup test reports taxes data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -61,11 +42,9 @@ class TaxStats extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); // Populate all of the data. - $tax = WC_Tax::_insert_tax_rate( + $tax = \WC_Tax::_insert_tax_rate( array( 'tax_rate_country' => 'US', 'tax_rate_state' => '', @@ -143,8 +122,6 @@ class TaxStats extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/Taxes.php b/unit-tests/Tests/Version4/Reports/Taxes.php index c22140dab35..4f93d8b8ada 100644 --- a/unit-tests/Tests/Version4/Reports/Taxes.php +++ b/unit-tests/Tests/Version4/Reports/Taxes.php @@ -10,11 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Customers Stats REST API Test Class @@ -22,7 +18,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class Taxes extends WC_REST_Unit_Test_Case { +class Taxes extends AbstractReportsTest { /** * Endpoints. @@ -31,21 +27,6 @@ class Taxes extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/taxes'; - /** - * Setup test reports taxes data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -64,8 +45,6 @@ class Taxes extends WC_REST_Unit_Test_Case { */ public function test_get_reports() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); // Populate all of the data. $product = new \WC_Product_Simple(); @@ -132,8 +111,6 @@ class Taxes extends WC_REST_Unit_Test_Case { */ public function test_get_reports_taxes_param() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); // Populate all of the data. $product = new \WC_Product_Simple(); @@ -232,8 +209,6 @@ class Taxes extends WC_REST_Unit_Test_Case { */ public function test_get_reports_orderby_tax_rate() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); $wpdb->insert( $wpdb->prefix . 'woocommerce_tax_rates', @@ -289,8 +264,6 @@ class Taxes extends WC_REST_Unit_Test_Case { */ public function test_get_reports_orderby_tax_code() { global $wpdb; - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); $wpdb->insert( $wpdb->prefix . 'woocommerce_tax_rates', @@ -354,8 +327,6 @@ class Taxes extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/Variations.php b/unit-tests/Tests/Version4/Reports/Variations.php index 0ba93066e45..8997ffcf314 100644 --- a/unit-tests/Tests/Version4/Reports/Variations.php +++ b/unit-tests/Tests/Version4/Reports/Variations.php @@ -10,10 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * Reports Customers Stats REST API Test Class @@ -21,7 +18,7 @@ use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; * @package WooCommerce\Tests\API * @since 3.5.0 */ -class Variations extends WC_REST_Unit_Test_Case { +class Variations extends AbstractReportsTest { /** * Endpoints. @@ -30,21 +27,6 @@ class Variations extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/reports/variations'; - /** - * Setup test reports products data. - * - * @since 3.5.0 - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test route registration. * @@ -62,9 +44,6 @@ class Variations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - // Populate all of the data. $variation = new \WC_Product_Variation(); $variation->set_name( 'Test Variation' ); @@ -102,9 +81,6 @@ class Variations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_reports_variations_param() { - wp_set_current_user( $this->user ); - ReportsHelper::reset_stats_dbs(); - // Populate all of the data. $variation = new \WC_Product_Variation(); $variation->set_name( 'Test Variation' ); @@ -177,8 +153,6 @@ class Variations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Settings.php b/unit-tests/Tests/Version4/Settings.php index 4e1650eaa79..6afa0aaa21c 100644 --- a/unit-tests/Tests/Version4/Settings.php +++ b/unit-tests/Tests/Version4/Settings.php @@ -11,6 +11,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper; class Settings extends WC_REST_Unit_Test_Case { @@ -19,8 +20,7 @@ class Settings extends WC_REST_Unit_Test_Case { */ public function setUp() { parent::setUp(); - $this->endpoint = new WC_REST_Setting_Options_Controller(); - \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); + SettingsHelper::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', @@ -116,7 +116,7 @@ class Settings extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); $this->assertEquals( 500, $response->get_status() ); - \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); + SettingsHelper::register(); } /** @@ -377,7 +377,7 @@ class Settings extends WC_REST_Unit_Test_Case { $controller ->expects( $this->any() ) ->method( 'get_group_settings' ) - ->will( $this->returnValue( \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); + ->will( $this->returnValue( SettingsHelper::register_test_settings( array() ) ) ); $controller ->expects( $this->any() ) diff --git a/unit-tests/Tests/Version4/ShippingMethods.php b/unit-tests/Tests/Version4/ShippingMethods.php index 8a8707d3582..3d59ea2464d 100644 --- a/unit-tests/Tests/Version4/ShippingMethods.php +++ b/unit-tests/Tests/Version4/ShippingMethods.php @@ -19,7 +19,7 @@ class ShippingMethods extends WC_REST_Unit_Test_Case { */ public function setUp() { parent::setUp(); - $this->endpoint = new WC_REST_Shipping_Methods_Controller(); + $this->endpoint = new \WC_REST_Shipping_Methods_Controller(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', diff --git a/unit-tests/Tests/Version4/ShippingZones.php b/unit-tests/Tests/Version4/ShippingZones.php index 97034c0449c..476ab832c7d 100644 --- a/unit-tests/Tests/Version4/ShippingZones.php +++ b/unit-tests/Tests/Version4/ShippingZones.php @@ -10,6 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; class ShippingZones extends WC_REST_Unit_Test_Case { @@ -27,8 +28,7 @@ class ShippingZones extends WC_REST_Unit_Test_Case { */ public function setUp() { parent::setUp(); - $this->endpoint = new WC_REST_Shipping_Zones_Controller(); - $this->user = $this->factory->user->create( + $this->user = $this->factory->user->create( array( 'role' => 'administrator', ) @@ -44,7 +44,7 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @return WC_Shipping_Zone */ protected function create_shipping_zone( $name, $order = 0, $locations = array() ) { - $zone = new WC_Shipping_Zone( null ); + $zone = new \WC_Shipping_Zone( null ); $zone->set_zone_name( $name ); $zone->set_zone_order( $order ); $zone->set_locations( $locations ); diff --git a/unit-tests/Tests/Version4/SystemStatus.php b/unit-tests/Tests/Version4/SystemStatus.php index b056be932d0..97ff7758ec0 100644 --- a/unit-tests/Tests/Version4/SystemStatus.php +++ b/unit-tests/Tests/Version4/SystemStatus.php @@ -9,6 +9,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; /** @@ -24,8 +25,7 @@ class SystemStatus extends WC_REST_Unit_Test_Case { */ public function setUp() { parent::setUp(); - $this->endpoint = new WC_REST_System_Status_Controller(); - $this->user = $this->factory->user->create( + $this->user = $this->factory->user->create( array( 'role' => 'administrator', ) @@ -110,7 +110,7 @@ class SystemStatus extends WC_REST_Unit_Test_Case { $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); - $this->assertEquals( WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); + $this->assertEquals( \WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], wc_print_r( $database, true ) ); $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], wc_print_r( $database, true ) ); } @@ -443,7 +443,7 @@ class SystemStatus extends WC_REST_Unit_Test_Case { } /** - * Provides a mocked response for external requests performed by WC_REST_System_Status_Controller. + * Provides a mocked response for external requests. * This way it is not necessary to perform a regular request to an external server which would * significantly slow down the tests. * From 3efbceeedccd23d353aae814f17f8a44b0e499e4 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 13:58:59 +0100 Subject: [PATCH 062/440] Speed up test by creating user once --- unit-tests/Tests/Version4/SystemStatus.php | 56 ++++++++-------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/unit-tests/Tests/Version4/SystemStatus.php b/unit-tests/Tests/Version4/SystemStatus.php index 97ff7758ec0..82a558b444b 100644 --- a/unit-tests/Tests/Version4/SystemStatus.php +++ b/unit-tests/Tests/Version4/SystemStatus.php @@ -21,15 +21,31 @@ use \WC_REST_Unit_Test_Case; class SystemStatus extends WC_REST_Unit_Test_Case { /** - * Setup our test server. + * User variable. + * + * @var WP_User */ - public function setUp() { - parent::setUp(); - $this->user = $this->factory->user->create( + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( array( 'role' => 'administrator', ) ); + } + + /** + * Setup our test server. + */ + public function setUp() { + parent::setUp(); + wp_set_current_user( self::$user ); // Callback used by WP_HTTP_TestCase to decide whether to perform HTTP requests or to provide a mocked response. $this->http_responder = array( $this, 'mock_http_responses' ); @@ -63,7 +79,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_returns_root_properties() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); $data = $response->get_data(); @@ -82,7 +97,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_environment() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); $data = $response->get_data(); $environment = (array) $data['environment']; @@ -103,7 +117,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { */ public function test_get_system_status_info_database() { global $wpdb; - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); $data = $response->get_data(); $database = (array) $data['database']; @@ -121,8 +134,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_active_plugins() { - wp_set_current_user( $this->user ); - $actual_plugins = array( 'hello.php' ); update_option( 'active_plugins', $actual_plugins ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); @@ -141,7 +152,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_theme() { - wp_set_current_user( $this->user ); $active_theme = wp_get_theme(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); @@ -158,8 +168,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_settings() { - wp_set_current_user( $this->user ); - $term_response = array(); $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); foreach ( $terms as $term ) { @@ -182,8 +190,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_security() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); $data = $response->get_data(); $settings = (array) $data['security']; @@ -199,7 +205,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_pages() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); $data = $response->get_data(); $pages = $data['pages']; @@ -216,7 +221,7 @@ class SystemStatus extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 9, count( $properties ) ); + $this->assertEquals( 10, count( $properties ) ); $this->assertArrayHasKey( 'environment', $properties ); $this->assertArrayHasKey( 'database', $properties ); $this->assertArrayHasKey( 'active_plugins', $properties ); @@ -232,16 +237,10 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_tools() { - wp_set_current_user( $this->user ); - - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $raw_tools ), count( $data ) ); $this->assertContains( array( 'id' => 'regenerate_thumbnails', @@ -269,7 +268,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $raw_tools ), count( $data ) ); $this->assertContains( array( 'id' => 'regenerate_thumbnails', @@ -309,12 +307,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_tool() { - wp_set_current_user( $this->user ); - - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - $raw_tool = $raw_tools['recount_terms']; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools/recount_terms' ) ); $data = $response->get_data(); @@ -365,12 +357,6 @@ class SystemStatus extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_execute_system_tool() { - wp_set_current_user( $this->user ); - - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - $raw_tool = $raw_tools['recount_terms']; - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v4/system_status/tools/recount_terms' ) ); $data = $response->get_data(); From fad61c38ece8cffb9b0409c20f67977baec385b7 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 15:08:29 +0100 Subject: [PATCH 063/440] Further test fixes, incl. admin notes --- src/RestApi/Version4/Controllers.php | 6 +- .../Version4/Controllers/AdminNotes.php | 485 ++++++++++++++++++ .../Version4/Controllers/OrderNotes.php | 6 +- .../Controllers/ProductVariations.php | 1 + unit-tests/AbstractReportsTest.php | 41 +- unit-tests/AbstractRestApiTest.php | 23 +- unit-tests/Bootstrap.php | 10 +- unit-tests/Tests/Version4/AdminNotes.php | 67 +-- unit-tests/Tests/Version4/Coupons.php | 27 +- unit-tests/Tests/Version4/Customers.php | 63 ++- unit-tests/Tests/Version4/Data.php | 40 +- unit-tests/Tests/Version4/Leaderboards.php | 31 +- unit-tests/Tests/Version4/PaymentGateways.php | 38 +- .../Tests/Version4/ProductVariations.php | 69 +-- unit-tests/Tests/Version4/Products.php | 133 +++-- unit-tests/Tests/Version4/Settings.php | 73 ++- unit-tests/Tests/Version4/ShippingMethods.php | 36 +- unit-tests/Tests/Version4/ShippingZones.php | 64 +-- 18 files changed, 861 insertions(+), 352 deletions(-) create mode 100644 src/RestApi/Version4/Controllers/AdminNotes.php diff --git a/src/RestApi/Version4/Controllers.php b/src/RestApi/Version4/Controllers.php index 727c311f70c..703a3ee0b54 100644 --- a/src/RestApi/Version4/Controllers.php +++ b/src/RestApi/Version4/Controllers.php @@ -56,7 +56,11 @@ class Controllers { 'webhooks' => __NAMESPACE__ . '\Controllers\Webhooks', ]; - if ( class_exists( 'WC_Admin_Reports_Sync' ) ) { + if ( class_exists( '\WC_Admin_Note' ) ) { + $controllers['admin-notes'] = __NAMESPACE__ . '\Controllers\AdminNotes'; + } + + if ( class_exists( '\WC_Admin_Reports_Sync' ) ) { $controllers['reports-categories'] = __NAMESPACE__ . '\Controllers\Reports\Categories'; $controllers['reports-coupons'] = __NAMESPACE__ . '\Controllers\Reports\Coupons'; $controllers['reports-coupon-stats'] = __NAMESPACE__ . '\Controllers\Reports\CouponStats'; diff --git a/src/RestApi/Version4/Controllers/AdminNotes.php b/src/RestApi/Version4/Controllers/AdminNotes.php new file mode 100644 index 00000000000..ee39d96d727 --- /dev/null +++ b/src/RestApi/Version4/Controllers/AdminNotes.php @@ -0,0 +1,485 @@ +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/RestApi/Version4/Controllers/OrderNotes.php b/src/RestApi/Version4/Controllers/OrderNotes.php index 27da4c0ec71..af91feec133 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/RestApi/Version4/Controllers/OrderNotes.php @@ -35,7 +35,8 @@ class OrderNotes extends AbstractController { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, + $this->namespace, + '/' . $this->rest_base, array( 'args' => array( 'order_id' => array( @@ -67,7 +68,8 @@ class OrderNotes extends AbstractController { ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( diff --git a/src/RestApi/Version4/Controllers/ProductVariations.php b/src/RestApi/Version4/Controllers/ProductVariations.php index 762c0c5e19d..51236aa91ed 100644 --- a/src/RestApi/Version4/Controllers/ProductVariations.php +++ b/src/RestApi/Version4/Controllers/ProductVariations.php @@ -1197,6 +1197,7 @@ class ProductVariations extends Products { 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); + $params['search'] = array( 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), 'type' => 'string', diff --git a/unit-tests/AbstractReportsTest.php b/unit-tests/AbstractReportsTest.php index 39d7a6a4b41..e74d971fd96 100644 --- a/unit-tests/AbstractReportsTest.php +++ b/unit-tests/AbstractReportsTest.php @@ -20,29 +20,42 @@ use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; abstract class AbstractReportsTest extends WC_REST_Unit_Test_Case { /** - * Setup test reports categories data. + * User variable. + * + * @var WP_User */ - public function setUp() { - if ( Bootstrap::skip_report_tests() ) { - $this->markTestSkipped( 'Skipping reports tests - woocommerce-admin not found.' ); - return; - } + protected static $user; - parent::setUp(); - - $this->user = $this->factory->user->create( + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( array( 'role' => 'administrator', ) ); + } - wp_set_current_user( $this->user ); + /** + * Setup test reports categories data. + */ + public function setUp() { + if ( ! class_exists( '\WC_Admin_Reports_Sync' ) ) { + $this->markTestSkipped( 'Skipping reports tests - WC_Admin_Reports_Sync class not found.' ); + return; + } + + parent::setUp(); + wp_set_current_user( self::$user ); global $wpdb; - $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Orders_Stats_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Products_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Coupons_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . WC_Admin_Reports_Customers_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . \WC_Admin_Reports_Orders_Stats_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . \WC_Admin_Reports_Products_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . \WC_Admin_Reports_Coupons_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. + $wpdb->query( "DELETE FROM $wpdb->prefix" . \WC_Admin_Reports_Customers_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. } } diff --git a/unit-tests/AbstractRestApiTest.php b/unit-tests/AbstractRestApiTest.php index 7b6b897da90..bbf767f0136 100644 --- a/unit-tests/AbstractRestApiTest.php +++ b/unit-tests/AbstractRestApiTest.php @@ -48,18 +48,31 @@ abstract class AbstractRestApiTest extends WC_REST_Unit_Test_Case { protected $routes = []; /** - * Setup test class. + * User variable. + * + * @var WP_User */ - public function setUp() { - parent::setUp(); + protected static $user; - $this->user = $this->factory->user->create( + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( array( 'role' => 'administrator', ) ); + } - wp_set_current_user( $this->user ); + /** + * Setup test class. + */ + public function setUp() { + parent::setUp(); + wp_set_current_user( self::$user ); } /** diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index 7c3ae49ad40..c1120e72a71 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -37,12 +37,12 @@ class Bootstrap { } /** - * Should we skip WC Admin Reports tests? + * Does WC Admin exist? * * @return boolean */ - public static function skip_report_tests() { - return ! file_exists( dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php' ); + protected static function wc_admin_exists() { + return file_exists( dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php' ); } /** @@ -56,7 +56,7 @@ class Bootstrap { require_once dirname( dirname( __DIR__ ) ) . '/woocommerce/woocommerce.php'; require_once dirname( __DIR__ ) . '/woocommerce-rest-api.php'; - if ( file_exists( dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php' ) ) { + if ( self::wc_admin_exists() ) { require_once dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php'; } } ); @@ -70,7 +70,7 @@ class Bootstrap { \WC_Install::install(); - if ( ! self::skip_report_tests() ) { + if ( self::wc_admin_exists() ) { echo esc_html( 'Installing WooCommerce Admin...' . PHP_EOL ); require_once dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/includes/class-wc-admin-install.php'; \WC_Admin_Install::create_tables(); diff --git a/unit-tests/Tests/Version4/AdminNotes.php b/unit-tests/Tests/Version4/AdminNotes.php index e6544b1cff5..090f0cf4b26 100644 --- a/unit-tests/Tests/Version4/AdminNotes.php +++ b/unit-tests/Tests/Version4/AdminNotes.php @@ -11,6 +11,7 @@ defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\Helpers\AdminNotesHelper; use \WC_REST_Unit_Test_Case; +use \WP_REST_Request; /** * Class AdminNotes @@ -24,20 +25,39 @@ class AdminNotes extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/admin/notes'; + /** + * User variable. + * + * @var WP_User + */ + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + /** * Setup test admin notes data. Called before every test. * * @since 3.5.0 */ public function setUp() { + if ( ! class_exists( '\WC_Admin_Note' ) ) { + $this->markTestSkipped( 'Skipping admin notes tests - WC_Admin_Note class not found.' ); + return; + } + parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - + wp_set_current_user( self::$user ); AdminNotesHelper::reset_notes_dbs(); AdminNotesHelper::add_notes_for_tests(); } @@ -59,8 +79,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_note() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); $note = $response->get_data(); @@ -68,7 +86,7 @@ class AdminNotes extends WC_REST_Unit_Test_Case { $this->assertEquals( 1, $note['id'] ); $this->assertEquals( 'PHPUNIT_TEST_NOTE_NAME', $note['name'] ); - $this->assertEquals( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL, $note['type'] ); + $this->assertEquals( \WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL, $note['type'] ); $this->assertArrayHasKey( 'locale', $note ); $this->assertEquals( 'PHPUNIT_TEST_NOTE_1_TITLE', $note['title'] ); @@ -76,7 +94,7 @@ class AdminNotes extends WC_REST_Unit_Test_Case { $this->assertEquals( 'info', $note['icon'] ); $this->assertArrayHasKey( 'content_data', $note ); $this->assertEquals( 1.23, $note['content_data']->amount ); - $this->assertEquals( WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED, $note['status'] ); + $this->assertEquals( \WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED, $note['status'] ); $this->assertEquals( 'PHPUNIT_TEST', $note['source'] ); $this->assertArrayHasKey( 'date_created', $note ); @@ -95,8 +113,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_invalid_note() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/999' ) ); $note = $response->get_data(); @@ -109,6 +125,7 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_note_without_permission() { + wp_set_current_user( 0 ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -117,8 +134,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * Test updating a single note. */ public function test_update_note() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); $note = $response->get_data(); @@ -142,6 +157,7 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * Test updating a single note without permission. It should fail. */ public function test_update_note_without_permission() { + wp_set_current_user( 0 ); $request = new WP_REST_Request( 'PUT', $this->endpoint . '/1' ); $request->set_body_params( array( @@ -158,8 +174,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_notes() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $notes = $response->get_data(); @@ -173,8 +187,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_warning_notes() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'type' => 'warning' ) ); $response = $this->server->dispatch( $request ); @@ -190,8 +202,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * Test getting notes of a certain status. */ public function test_get_actioned_notes() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'status' => 'actioned' ) ); $response = $this->server->dispatch( $request ); @@ -214,8 +224,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * Test note "unsnoozing". */ public function test_note_unsnoozing() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( 'status' => 'snoozed' ) ); $response = $this->server->dispatch( $request ); @@ -226,7 +234,7 @@ class AdminNotes extends WC_REST_Unit_Test_Case { $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_3_TITLE' ); // The test snoozed note's reminder date is an hour ago. - WC_Admin_Notes::unsnooze_notes(); + \WC_Admin_Notes::unsnooze_notes(); $response = $this->server->dispatch( $request ); $notes = $response->get_data(); @@ -239,8 +247,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * Test ordering of notes. */ public function test_order_notes() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( @@ -268,9 +274,9 @@ class AdminNotes extends WC_REST_Unit_Test_Case { $notes = $response->get_data(); $this->assertEquals( 3, count( $notes ) ); - $this->assertEquals( $notes[0]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED ); - $this->assertEquals( $notes[1]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED ); - $this->assertEquals( $notes[2]['status'], WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED ); + $this->assertEquals( $notes[0]['status'], \WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED ); + $this->assertEquals( $notes[1]['status'], \WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED ); + $this->assertEquals( $notes[2]['status'], \WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED ); } /** @@ -279,6 +285,7 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_notes_without_permission() { + wp_set_current_user( 0 ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -289,8 +296,6 @@ class AdminNotes extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_notes_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Coupons.php b/unit-tests/Tests/Version4/Coupons.php index 6b2548f631b..88f77929dd5 100644 --- a/unit-tests/Tests/Version4/Coupons.php +++ b/unit-tests/Tests/Version4/Coupons.php @@ -10,6 +10,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; +use \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; /** * Abstract Rest API Test Class @@ -101,10 +102,10 @@ class Coupons extends AbstractRestApiTest { * Test read. */ public function test_read() { - $coupon1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); - $coupon2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-2' ); - $coupon3 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'anothertestcoupon-3' ); - $coupon4 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'anothertestcoupon-4' ); + $coupon1 = CouponHelper::create_coupon( 'testcoupon-1' ); + $coupon2 = CouponHelper::create_coupon( 'testcoupon-2' ); + $coupon3 = CouponHelper::create_coupon( 'anothertestcoupon-3' ); + $coupon4 = CouponHelper::create_coupon( 'anothertestcoupon-4' ); // Collection. $response = $this->do_request( '/wc/v4/coupons', 'GET' ); @@ -142,7 +143,7 @@ class Coupons extends AbstractRestApiTest { $this->assertExpectedResponse( $response, 404 ); // Update existing. - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); + $coupon = CouponHelper::create_coupon( 'testcoupon-1' ); $response = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'POST', @@ -171,14 +172,14 @@ class Coupons extends AbstractRestApiTest { $this->assertEquals( 404, $result->status ); // Trash. - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); + $coupon = CouponHelper::create_coupon( 'testcoupon-1' ); $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); $this->assertEquals( 200, $result->status ); $this->assertEquals( 'trash', get_post_status( $coupon->get_id() ) ); // Force. - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-2' ); + $coupon = CouponHelper::create_coupon( 'testcoupon-2' ); $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => true ] ); $this->assertEquals( 200, $result->status ); @@ -234,7 +235,7 @@ class Coupons extends AbstractRestApiTest { */ public function test_guest_update() { wp_set_current_user( 0 ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); + $coupon = CouponHelper::create_coupon( 'testcoupon-1' ); $response = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'POST', @@ -251,7 +252,7 @@ class Coupons extends AbstractRestApiTest { */ public function test_guest_delete() { wp_set_current_user( 0 ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'testcoupon-1' ); + $coupon = CouponHelper::create_coupon( 'testcoupon-1' ); $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); $this->assertEquals( 401, $result->status ); } @@ -278,10 +279,10 @@ class Coupons extends AbstractRestApiTest { * Test a batch update. */ public function test_batch() { - $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'batchcoupon-1' ); - $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'batchcoupon-2' ); - $coupon_3 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'batchcoupon-3' ); - $coupon_4 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'batchcoupon-4' ); + $coupon_1 = CouponHelper::create_coupon( 'batchcoupon-1' ); + $coupon_2 = CouponHelper::create_coupon( 'batchcoupon-2' ); + $coupon_3 = CouponHelper::create_coupon( 'batchcoupon-3' ); + $coupon_4 = CouponHelper::create_coupon( 'batchcoupon-4' ); $result = $this->do_request( '/wc/v4/coupons/batch', diff --git a/unit-tests/Tests/Version4/Customers.php b/unit-tests/Tests/Version4/Customers.php index 3bbda740f09..0cb812dfc7b 100644 --- a/unit-tests/Tests/Version4/Customers.php +++ b/unit-tests/Tests/Version4/Customers.php @@ -10,7 +10,9 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Tests for the Customers REST API. @@ -20,12 +22,32 @@ use \WC_REST_Unit_Test_Case; */ class Customers extends WC_REST_Unit_Test_Case { + /** + * User variable. + * + * @var WP_User + */ + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + /** * Setup our test server, endpoints, and user info. */ public function setUp() { parent::setUp(); - $this->endpoint = new WC_REST_Customers_Controller(); + wp_set_current_user( self::$user ); } /** @@ -47,10 +69,8 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_customers() { - wp_set_current_user( 1 ); - - $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); - \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); + $customer_1 = CustomerHelper::create_customer(); + CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v4/customers' ); $request->set_query_params( @@ -121,7 +141,7 @@ class Customers extends WC_REST_Unit_Test_Case { ); update_option( 'timezone_tring', 'America/New York' ); - $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); + $customer_3 = CustomerHelper::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v4/customers' ); $request->set_query_params( @@ -209,8 +229,6 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_create_customer() { - wp_set_current_user( 1 ); - // Test just the basics first.. $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); $request->set_body_params( @@ -373,8 +391,7 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_customer() { - wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); + $customer = CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -429,7 +446,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_get_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); + $customer = CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -440,7 +457,6 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_customer_invalid_id() { - wp_set_current_user( 1 ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/0' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -451,8 +467,7 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_customer() { - wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); + $customer = CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -480,7 +495,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_update_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); + $customer = CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -491,7 +506,6 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_customer_invalid_id() { - wp_set_current_user( 1 ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/0' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -503,8 +517,7 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_delete_customer() { - wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); + $customer = CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -517,7 +530,6 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_delete_customer_invalid_id() { - wp_set_current_user( 1 ); $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/0' ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -531,7 +543,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_delete_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); + $customer = CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -544,12 +556,10 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_batch_customer() { - wp_set_current_user( 1 ); - - $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); - $customer_2 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); - $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); - $customer_4 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); + $customer_1 = CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); + $customer_2 = CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); + $customer_3 = CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); + $customer_4 = CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); $request = new WP_REST_Request( 'POST', '/wc/v4/customers/batch' ); $request->set_body_params( @@ -595,7 +605,6 @@ class Customers extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_customer_schema() { - wp_set_current_user( 1 ); $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/customers' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Data.php b/unit-tests/Tests/Version4/Data.php index c7f689cb946..9916da2ecc2 100644 --- a/unit-tests/Tests/Version4/Data.php +++ b/unit-tests/Tests/Version4/Data.php @@ -9,12 +9,12 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; -use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * WC Tests API Data */ -class Data extends WC_REST_Unit_Test_Case { +class Data extends AbstractReportsTest { /** * Endpoints. @@ -23,26 +23,11 @@ class Data extends WC_REST_Unit_Test_Case { */ protected $endpoint = '/wc/v4/data'; - /** - * Setup test data. Called before every test. - */ - public function setUp() { - parent::setUp(); - - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - /** * Test that the list of data endpoints includes download-ips. */ public function test_get_items_contains_download_ips() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); + $request = new \WP_REST_Request( 'GET', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -55,14 +40,11 @@ class Data extends WC_REST_Unit_Test_Case { * Test download-ips match searching. */ public function test_download_ips() { - wp_set_current_user( $this->user ); - \WooCommerce\RestApi\UnitTests\Helpers\ReportsHelper::reset_stats_dbs(); - - $prod_download = new WC_Product_Download(); + $prod_download = new \WC_Product_Download(); $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); $prod_download->set_id( 1 ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_downloadable( 'yes' ); $product->set_downloads( array( $prod_download ) ); @@ -74,39 +56,39 @@ class Data extends WC_REST_Unit_Test_Case { $order->set_total( 100 ); $order->save(); - $download = new WC_Customer_Download(); + $download = new \WC_Customer_Download(); $download->set_user_id( $this->user ); $download->set_order_id( $order->get_id() ); $download->set_product_id( $product->get_id() ); $download->set_download_id( $prod_download->get_id() ); $download->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '1.2.3.4' ); $id = $object->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '54.2.1.3' ); $id = $object->save(); // Save a second log for the same IP -- only one result for this IP should be returned. - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '54.2.1.3' ); $id = $object->save(); - $object = new WC_Customer_Download_Log(); + $object = new \WC_Customer_Download_Log(); $object->set_permission_id( $download->get_id() ); $object->set_user_id( $this->user ); $object->set_user_ip_address( '54.5.1.7' ); $id = $object->save(); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/download-ips' ); + $request = new \WP_REST_Request( 'GET', $this->endpoint . '/download-ips' ); $request->set_query_params( array( 'match' => '54', diff --git a/unit-tests/Tests/Version4/Leaderboards.php b/unit-tests/Tests/Version4/Leaderboards.php index 8cd8407b62f..4afb7185997 100644 --- a/unit-tests/Tests/Version4/Leaderboards.php +++ b/unit-tests/Tests/Version4/Leaderboards.php @@ -9,6 +9,7 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; /** @@ -23,23 +24,37 @@ class Leaderboards extends WC_REST_Unit_Test_Case { protected $endpoint = '/wc/v4/leaderboards'; /** - * Setup test data. Called before every test. + * User variable. + * + * @var WP_User */ - public function setUp() { - parent::setUp(); - $this->user = $this->factory->user->create( + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( array( 'role' => 'administrator', ) ); } + /** + * Setup our test server, endpoints, and user info. + */ + public function setUp() { + parent::setUp(); + wp_set_current_user( self::$user ); + } + /** * Test that leaderboards are returned by the endpoint. */ public function test_get_leaderboards() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -55,8 +70,6 @@ class Leaderboards extends WC_REST_Unit_Test_Case { * Test reports schema. */ public function test_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -114,8 +127,6 @@ class Leaderboards extends WC_REST_Unit_Test_Case { * Test that leaderboards response changes based on applied filters. */ public function test_filter_leaderboards() { - wp_set_current_user( $this->user ); - add_filter( 'woocommerce_leaderboards', function( $leaderboards, $per_page, $after, $before, $persisted_query ) { diff --git a/unit-tests/Tests/Version4/PaymentGateways.php b/unit-tests/Tests/Version4/PaymentGateways.php index c3a01700918..5ef9e82c7ca 100644 --- a/unit-tests/Tests/Version4/PaymentGateways.php +++ b/unit-tests/Tests/Version4/PaymentGateways.php @@ -11,21 +11,37 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; class PaymentGateways extends WC_REST_Unit_Test_Case { + /** + * User variable. + * + * @var WP_User + */ + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + /** * Setup our test server, endpoints, and user info. */ public function setUp() { parent::setUp(); - $this->endpoint = new WC_REST_Payment_Gateways_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); + wp_set_current_user( self::$user ); } /** @@ -45,8 +61,6 @@ class PaymentGateways extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_payment_gateways() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways' ) ); $gateways = $response->get_data(); @@ -104,8 +118,6 @@ class PaymentGateways extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_payment_gateway() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/paypal' ) ); $paypal = $response->get_data(); @@ -152,7 +164,6 @@ class PaymentGateways extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_payment_gateway_invalid_id() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/totally_fake_method' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -163,8 +174,6 @@ class PaymentGateways extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_payment_gateway() { - wp_set_current_user( $this->user ); - // Test defaults $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/paypal' ) ); $paypal = $response->get_data(); @@ -276,7 +285,6 @@ class PaymentGateways extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_payment_gateway_invalid_id() { - wp_set_current_user( $this->user ); $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/totally_fake_method' ); $request->set_body_params( array( @@ -293,8 +301,6 @@ class PaymentGateways extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_payment_gateway_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/payment_gateways' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/ProductVariations.php b/unit-tests/Tests/Version4/ProductVariations.php index d2ebff95dcc..92a732de21b 100644 --- a/unit-tests/Tests/Version4/ProductVariations.php +++ b/unit-tests/Tests/Version4/ProductVariations.php @@ -10,21 +10,38 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; class ProductVariations extends WC_REST_Unit_Test_Case { + /** + * User variable. + * + * @var WP_User + */ + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + /** * Setup our test server, endpoints, and user info. */ public function setUp() { parent::setUp(); - $this->endpoint = new WC_REST_Product_Variations_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); + wp_set_current_user( self::$user ); } /** @@ -45,8 +62,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_variations() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -62,7 +78,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { */ public function test_get_variations_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -73,8 +89,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_variation() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -93,7 +108,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { */ public function test_get_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ) ); @@ -106,8 +121,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_delete_variation() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -128,7 +142,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -145,7 +159,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_with_invalid_id() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() . '/variations/0' ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -158,8 +172,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_variation() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -211,7 +224,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { */ public function test_update_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -231,8 +244,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_variation_with_invalid_id() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/0' ); $request->set_body_params( array( @@ -249,8 +261,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_create_variation() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); @@ -292,7 +303,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { */ public function test_create_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'POST', '/wc/v4/products/' . $product->get_id() . '/variations' ); $request->set_body_params( @@ -318,8 +329,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_product_variations_batch() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $children = $product->get_children(); $request = new WP_REST_Request( 'POST', '/wc/v4/products/' . $product->get_id() . '/variations/batch' ); $request->set_body_params( @@ -374,8 +384,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_variation_schema() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() . '/variations' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -424,9 +433,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_variation_manage_stock() { - wp_set_current_user( $this->user ); - - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $product->set_manage_stock( false ); $product->save(); diff --git a/unit-tests/Tests/Version4/Products.php b/unit-tests/Tests/Version4/Products.php index b0886febfa5..94585a06e97 100644 --- a/unit-tests/Tests/Version4/Products.php +++ b/unit-tests/Tests/Version4/Products.php @@ -10,7 +10,9 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; /** * Products class. @@ -18,18 +20,33 @@ use \WC_REST_Unit_Test_Case; class Products extends WC_REST_Unit_Test_Case { /** - * Setup our test server, endpoints, and user info. + * User variable. + * + * @var WP_User */ - public function setUp() { - parent::setUp(); - $this->endpoint = new WC_REST_Products_Controller(); - $this->user = $this->factory->user->create( + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( array( 'role' => 'administrator', ) ); } + /** + * Setup our test server, endpoints, and user info. + */ + public function setUp() { + parent::setUp(); + wp_set_current_user( self::$user ); + } + /** * Test route registration. * @@ -48,10 +65,9 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_products() { - wp_set_current_user( $this->user ); - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + ProductHelper::create_external_product(); sleep( 1 ); // So both products have different timestamps. - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); $products = $response->get_data(); @@ -71,7 +87,7 @@ class Products extends WC_REST_Unit_Test_Case { */ public function test_get_products_without_permission() { wp_set_current_user( 0 ); - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -82,8 +98,7 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_product() { - wp_set_current_user( $this->user ); - $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $simple = ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $simple->get_id() ) ); $product = $response->get_data(); @@ -108,7 +123,7 @@ class Products extends WC_REST_Unit_Test_Case { */ public function test_get_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -119,8 +134,7 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_delete_product() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() ); $request->set_param( 'force', true ); @@ -139,7 +153,7 @@ class Products extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -165,10 +179,8 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_product() { - wp_set_current_user( $this->user ); - // test simple products. - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); $data = $response->get_data(); $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); @@ -207,7 +219,7 @@ class Products extends WC_REST_Unit_Test_Case { $product->delete( true ); // test variable product (variations are tested in product-variations.php). - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -253,7 +265,7 @@ class Products extends WC_REST_Unit_Test_Case { $product->delete( true ); // test external product. - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $product = ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -281,7 +293,7 @@ class Products extends WC_REST_Unit_Test_Case { */ public function test_update_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); $request->set_body_params( array( @@ -298,15 +310,14 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_product_with_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' ); + $request = new WP_REST_Request( 'PUT', '/wc/v4/products/0' ); $request->set_body_params( array( 'sku' => 'FIXED-SKU-INVALID-ID', ) ); $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); + $this->assertEquals( 404, $response->get_status() ); } /** @@ -315,7 +326,6 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_create_product() { - wp_set_current_user( $this->user ); $request = new WP_REST_Request( 'POST', '/wc/v4/products/shipping_classes' ); $request->set_body_params( @@ -432,9 +442,8 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_products_batch() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); + $product_2 = ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v4/products/batch' ); $request->set_body_params( array( @@ -473,7 +482,7 @@ class Products extends WC_REST_Unit_Test_Case { $this->assertEquals( 'Test Button', $data['create'][0]['button_text'] ); $this->assertEquals( 'external', $data['create'][0]['type'] ); $this->assertEquals( 'simple', $data['create'][1]['type'] ); - $this->assertEquals( $product_2->get_id(), $data['delete'][0]['id'] ); + $this->assertEquals( $product_2->get_id(), $data['delete'][0]['previous']['id'] ); $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $response = $this->server->dispatch( $request ); @@ -489,9 +498,8 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_products_filter_post_status() { - wp_set_current_user( $this->user ); for ( $i = 0; $i < 8; $i++ ) { - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); if ( 0 === $i % 2 ) { wp_update_post( array( @@ -538,8 +546,7 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_product_schema() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -553,24 +560,22 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_products_by_category() { - wp_set_current_user( $this->user ); - // Create one product with a category. $category = wp_insert_term( 'Some Category', 'product_cat' ); - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_category_ids( array( $category['term_id'] ) ); $product->save(); // Create one product without category, i.e. Uncategorized. - $product_2 = new WC_Product_Simple(); + $product_2 = new \WC_Product_Simple(); $product_2->save(); // Test product assigned to a single category. $query_params = array( 'category' => (string) $category['term_id'], ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $request->set_query_params( $query_params ); $response = $this->server->dispatch( $request ); $response_products = $response->get_data(); @@ -582,7 +587,7 @@ class Products extends WC_REST_Unit_Test_Case { } // Test product without categories. - $request = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product_2->get_id() ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products/' . $product_2->get_id() ); $response = $this->server->dispatch( $request ); $response_product = $response->get_data(); @@ -598,12 +603,10 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_products_by_type() { - wp_set_current_user( $this->user ); - - $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $external = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - $grouped = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_grouped_product(); - $variable = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $simple = ProductHelper::create_simple_product(); + $external = ProductHelper::create_external_product(); + $grouped = ProductHelper::create_grouped_product(); + $variable = ProductHelper::create_variation_product(); $product_ids_for_type = array( 'simple' => array( $simple->get_id() ), @@ -620,7 +623,7 @@ class Products extends WC_REST_Unit_Test_Case { $query_params = array( 'type' => $product_type, ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $request->set_query_params( $query_params ); $response = $this->server->dispatch( $request ); $response_products = $response->get_data(); @@ -639,21 +642,19 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_featured_products() { - wp_set_current_user( $this->user ); - // Create a featured product. - $feat_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $feat_product = ProductHelper::create_simple_product(); $feat_product->set_featured( true ); $feat_product->save(); // Create a non-featured product. - $nonfeat_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $nonfeat_product = ProductHelper::create_simple_product(); $nonfeat_product->save(); $query_params = array( 'featured' => 'true', ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $request->set_query_params( $query_params ); $response = $this->server->dispatch( $request ); $response_products = $response->get_data(); @@ -666,7 +667,7 @@ class Products extends WC_REST_Unit_Test_Case { $query_params = array( 'featured' => 'false', ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $request->set_query_params( $query_params ); $response = $this->server->dispatch( $request ); $response_products = $response->get_data(); @@ -683,18 +684,16 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_products_by_shipping_class() { - wp_set_current_user( $this->user ); - $shipping_class_1 = wp_insert_term( 'Bulky', 'product_shipping_class' ); - $product_1 = new WC_Product_Simple(); + $product_1 = new \WC_Product_Simple(); $product_1->set_shipping_class_id( $shipping_class_1['term_id'] ); $product_1->save(); $query_params = array( 'shipping_class' => (string) $shipping_class_1['term_id'], ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $request->set_query_params( $query_params ); $response = $this->server->dispatch( $request ); $response_products = $response->get_data(); @@ -711,22 +710,20 @@ class Products extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_products_by_tag() { - wp_set_current_user( $this->user ); - $test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' ); // Product with a tag. - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $product->set_tag_ids( array( $test_tag_1['term_id'] ) ); $product->save(); // Product without a tag. - $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = ProductHelper::create_simple_product(); $query_params = array( 'tag' => (string) $test_tag_1['term_id'], ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $request->set_query_params( $query_params ); $response = $this->server->dispatch( $request ); $response_products = $response->get_data(); @@ -744,20 +741,19 @@ class Products extends WC_REST_Unit_Test_Case { */ public function test_get_products_by_attribute() { global $wpdb; - wp_set_current_user( $this->user ); // Variable product with 2 different variations. - $variable_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $variable_product = ProductHelper::create_variation_product(); // Terms created by variable product. $term_large = get_term_by( 'slug', 'large', 'pa_size' ); $term_small = get_term_by( 'slug', 'small', 'pa_size' ); // Simple product without attribute. - $product_1 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_1 = ProductHelper::create_simple_product(); // Simple product with attribute size = large. - $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = ProductHelper::create_simple_product(); $product_2->set_attributes( array( 'pa_size' => 'large' ) ); $product_2->save(); @@ -780,7 +776,7 @@ class Products extends WC_REST_Unit_Test_Case { 'attribute' => 'pa_size', 'attribute_term' => (string) $term_large->term_id, ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $request->set_query_params( $query_params ); $response = $this->server->dispatch( $request ); $response_products = $response->get_data(); @@ -799,7 +795,7 @@ class Products extends WC_REST_Unit_Test_Case { 'attribute' => 'pa_size', 'attribute_term' => (string) $term_small->term_id, ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); + $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); $request->set_query_params( $query_params ); $response = $this->server->dispatch( $request ); $response_products = $response->get_data(); @@ -815,8 +811,7 @@ class Products extends WC_REST_Unit_Test_Case { * Test product schema contains embed fields. */ public function test_product_schema_embed() { - wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Settings.php b/unit-tests/Tests/Version4/Settings.php index 6afa0aaa21c..2ff52c18b9e 100644 --- a/unit-tests/Tests/Version4/Settings.php +++ b/unit-tests/Tests/Version4/Settings.php @@ -10,24 +10,42 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; use \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper; class Settings extends WC_REST_Unit_Test_Case { /** - * Setup our test server, endpoints, and user info. + * User variable. + * + * @var WP_User */ - public function setUp() { - parent::setUp(); - SettingsHelper::register(); - $this->user = $this->factory->user->create( + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( array( 'role' => 'administrator', ) ); } + /** + * Setup our test server, endpoints, and user info. + */ + public function setUp() { + parent::setUp(); + wp_set_current_user( self::$user ); + SettingsHelper::register(); + $this->zones = array(); + } + /** * Test route registration. * @@ -46,8 +64,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_groups() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); $data = $response->get_data(); @@ -109,8 +125,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @covers WC_Rest_Settings_Controller::get_items */ public function test_get_groups_none_registered() { - wp_set_current_user( $this->user ); - remove_all_filters( 'woocommerce_settings_groups' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); @@ -166,11 +180,9 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_group() { - wp_set_current_user( $this->user ); - // test route callback receiving an empty group id - $result = $this->endpoint->get_group_settings( '' ); - $this->assertIsWPError( $result ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/' ) ); + $this->assertEquals( 404, $response->get_status() ); // test getting a group that does not exist $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/not-real' ) ); @@ -206,8 +218,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_setting() { - wp_set_current_user( $this->user ); - // test defaults first $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/woocommerce_shop_page_display' ) ); $data = $response->get_data(); @@ -257,8 +267,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_settings() { - wp_set_current_user( $this->user ); - // test defaults first $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test' ) ); $data = $response->get_data(); @@ -306,8 +314,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_setting() { - wp_set_current_user( $this->user ); - // test getting an invalid setting from a group that does not exist $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/not-real/woocommerce_shop_page_display' ) ); $data = $response->get_data(); @@ -349,9 +355,8 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_setting_empty_setting_id() { - $result = $this->endpoint->get_setting( 'test', '' ); - - $this->assertIsWPError( $result ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/' ) ); + $this->assertEquals( 404, $response->get_status() ); } /** @@ -360,9 +365,8 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_setting_invalid_setting_id() { - $result = $this->endpoint->get_setting( 'test', 'invalid' ); - - $this->assertIsWPError( $result ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/invalid' ) ); + $this->assertEquals( 404, $response->get_status() ); } /** @@ -438,8 +442,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @covers WC_Rest_Setting_Options_Controller::update_item */ public function test_update_setting_bad_setting_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/test/invalid' ); $request->set_body_params( array( @@ -456,8 +458,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_classic_settings() { - wp_set_current_user( $this->user ); - // Make sure the group is properly registered $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/products' ) ); $data = $response->get_data(); @@ -513,8 +513,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_email_settings() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/email_new_order' ) ); $settings = $response->get_data(); @@ -619,8 +617,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_validation_checkbox() { - wp_set_current_user( $this->user ); - // test bogus value $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); $request->set_body_params( @@ -658,8 +654,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_validation_radio() { - wp_set_current_user( $this->user ); - // not a valid option $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); $request->set_body_params( @@ -687,8 +681,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_validation_multiselect() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v4/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ) ); $setting = $response->get_data(); $this->assertEmpty( $setting['value'] ); @@ -710,8 +702,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_validation_select() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ) ); $setting = $response->get_data(); $this->assertEquals( 'kg', $setting['value'] ); @@ -746,7 +736,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_woocommerce_default_country() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_default_country' ) ); $setting = $response->get_data(); @@ -761,7 +750,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_woocommerce_store_address() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_address' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); @@ -797,7 +785,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_woocommerce_store_address_2() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_address_2' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); @@ -833,7 +820,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_woocommerce_store_city() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_city' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); @@ -869,7 +855,6 @@ class Settings extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_woocommerce_store_postcode() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_postcode' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); diff --git a/unit-tests/Tests/Version4/ShippingMethods.php b/unit-tests/Tests/Version4/ShippingMethods.php index 3d59ea2464d..18123f939e5 100644 --- a/unit-tests/Tests/Version4/ShippingMethods.php +++ b/unit-tests/Tests/Version4/ShippingMethods.php @@ -10,21 +10,38 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; +use \WP_REST_Request; use \WC_REST_Unit_Test_Case; class ShippingMethods extends WC_REST_Unit_Test_Case { + /** + * User variable. + * + * @var WP_User + */ + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + /** * Setup our test server, endpoints, and user info. */ public function setUp() { parent::setUp(); - $this->endpoint = new \WC_REST_Shipping_Methods_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); + wp_set_current_user( self::$user ); + $this->zones = array(); } /** @@ -44,8 +61,6 @@ class ShippingMethods extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_shipping_methods() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods' ) ); $methods = $response->get_data(); @@ -89,8 +104,6 @@ class ShippingMethods extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_shipping_method() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods/local_pickup' ) ); $method = $response->get_data(); @@ -123,7 +136,6 @@ class ShippingMethods extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_shipping_method_invalid_id() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods/fake_method' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -134,8 +146,6 @@ class ShippingMethods extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_shipping_method_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/shipping_methods' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/ShippingZones.php b/unit-tests/Tests/Version4/ShippingZones.php index 476ab832c7d..7ee63f08d44 100644 --- a/unit-tests/Tests/Version4/ShippingZones.php +++ b/unit-tests/Tests/Version4/ShippingZones.php @@ -19,21 +19,35 @@ class ShippingZones extends WC_REST_Unit_Test_Case { protected $endpoint; - protected $user; - protected $zones; + /** + * User variable. + * + * @var WP_User + */ + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + /** * Setup our test server, endpoints, and user info. */ public function setUp() { parent::setUp(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - $this->zones = array(); + wp_set_current_user( self::$user ); + $this->zones = array(); } /** @@ -75,8 +89,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_zones() { - wp_set_current_user( $this->user ); - // "Rest of the World" zone exists by default $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); $data = $response->get_data(); @@ -162,8 +174,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_shipping_zones_disabled_shipping() { - wp_set_current_user( $this->user ); - add_filter( 'wc_shipping_enabled', '__return_false' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); @@ -195,8 +205,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_create_shipping_zone() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones' ); $request->set_body_params( array( @@ -260,8 +268,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_shipping_zone() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Test Zone' ); $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/' . $zone->get_id() ); @@ -308,8 +314,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/555555' ); $request->set_body_params( array( @@ -328,7 +332,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_delete_shipping_zone() { - wp_set_current_user( $this->user ); $zone = $this->create_shipping_zone( 'Zone 1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/' . $zone->get_id() ); @@ -360,7 +363,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_delete_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/555555' ); $response = $this->server->dispatch( $request ); $this->assertEquals( 404, $response->get_status() ); @@ -372,8 +374,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_single_shipping_zone() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Test Zone' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() ) ); $data = $response->get_data(); @@ -412,8 +412,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_single_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1' ) ); $this->assertEquals( 404, $response->get_status() ); @@ -425,8 +423,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_locations() { - wp_set_current_user( $this->user ); - // Create a zone $zone = $this->create_shipping_zone( 'Zone 1', @@ -473,8 +469,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_locations_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1/locations' ) ); $this->assertEquals( 404, $response->get_status() ); @@ -486,8 +480,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_locations() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Test Zone' ); $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ); @@ -577,8 +569,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_locations_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/1/locations' ) ); $this->assertEquals( 404, $response->get_status() ); @@ -590,8 +580,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_methods() { - wp_set_current_user( $this->user ); - // Create a shipping method and make sure it's in the response $zone = $this->create_shipping_zone( 'Zone 1' ); $instance_id = $zone->add_shipping_method( 'flat_rate' ); @@ -665,8 +653,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_methods_invalid_zone_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1/methods' ) ); $this->assertEquals( 404, $response->get_status() ); @@ -682,8 +668,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_methods_invalid_method_id() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Zone 1' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/1' ) ); @@ -696,8 +680,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_update_methods() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Zone 1' ); $instance_id = $zone->add_shipping_method( 'flat_rate' ); $methods = $zone->get_shipping_methods(); @@ -793,7 +775,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_create_method() { - wp_set_current_user( $this->user ); $zone = $this->create_shipping_zone( 'Zone 1' ); $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods' ); $request->set_body_params( @@ -818,7 +799,6 @@ class ShippingZones extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_delete_method() { - wp_set_current_user( $this->user ); $zone = $this->create_shipping_zone( 'Zone 1' ); $instance_id = $zone->add_shipping_method( 'flat_rate' ); $methods = $zone->get_shipping_methods(); From 482b985b7723fc82cc481d2674a294aad7d2870c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 16:32:12 +0100 Subject: [PATCH 064/440] All tests passing --- .../Controllers/AbstractController.php | 2 +- .../Controllers/AbstractObjectsController.php | 12 ++-- .../Version4/Controllers/Customers.php | 7 ++- .../Version4/Controllers/OrderRefunds.php | 6 +- src/RestApi/Version4/Controllers/Orders.php | 9 +-- .../Controllers/ProductVariations.php | 26 ++++---- src/RestApi/Version4/Controllers/Products.php | 3 +- .../Controllers/Reports/CouponStats.php | 2 +- .../Controllers/Reports/OrderStats.php | 2 +- .../Controllers/Reports/ProductStats.php | 2 +- src/Utilities/SingletonTrait.php | 2 - unit-tests/AbstractReportsTest.php | 4 -- unit-tests/Bootstrap.php | 58 +++++++++++------- unit-tests/Helpers/QueueHelper.php | 2 +- unit-tests/Tests/Version3/functions.php | 4 +- unit-tests/Tests/Version4/Orders.php | 3 + unit-tests/Tests/Version4/ProductReviews.php | 1 - .../Tests/Version4/ProductVariations.php | 6 +- .../Tests/Version4/Reports/Categories.php | 8 ++- unit-tests/Tests/Version4/Reports/Coupons.php | 9 ++- .../Tests/Version4/Reports/CouponsStats.php | 7 ++- .../Tests/Version4/Reports/CustomerStats.php | 6 +- .../Tests/Version4/Reports/Customers.php | 7 ++- .../Tests/Version4/Reports/DownloadStats.php | 4 ++ .../Tests/Version4/Reports/Downloads.php | 4 ++ unit-tests/Tests/Version4/Reports/Import.php | 18 +----- .../Tests/Version4/Reports/OrderStats.php | 4 ++ unit-tests/Tests/Version4/Reports/Orders.php | 4 ++ .../Reports/PerformanceIndicators.php | 4 ++ .../Tests/Version4/Reports/ProductStats.php | 4 ++ .../Tests/Version4/Reports/Products.php | 4 ++ .../Tests/Version4/Reports/RevenueStats.php | 8 +-- unit-tests/Tests/Version4/Reports/Stock.php | 4 ++ .../Tests/Version4/Reports/StockStats.php | 4 ++ .../Tests/Version4/Reports/TaxStats.php | 4 ++ unit-tests/Tests/Version4/Reports/Taxes.php | 4 ++ .../Tests/Version4/Reports/Variations.php | 4 ++ unit-tests/data/Dr1Bczxq4q.png | Bin 0 -> 10325 bytes unit-tests/data/file.txt | 1 + 39 files changed, 167 insertions(+), 96 deletions(-) create mode 100644 unit-tests/data/Dr1Bczxq4q.png create mode 100644 unit-tests/data/file.txt diff --git a/src/RestApi/Version4/Controllers/AbstractController.php b/src/RestApi/Version4/Controllers/AbstractController.php index 8df2dce939e..d381bceef54 100644 --- a/src/RestApi/Version4/Controllers/AbstractController.php +++ b/src/RestApi/Version4/Controllers/AbstractController.php @@ -8,7 +8,7 @@ * It's required to follow "Controller Classes" guide before extending this class: * * - * @class WC_REST_Controller + * @class \WC_REST_Controller * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ * @package WooCommerce/RestApi */ diff --git a/src/RestApi/Version4/Controllers/AbstractObjectsController.php b/src/RestApi/Version4/Controllers/AbstractObjectsController.php index 790f26b5e58..6959d0127b5 100644 --- a/src/RestApi/Version4/Controllers/AbstractObjectsController.php +++ b/src/RestApi/Version4/Controllers/AbstractObjectsController.php @@ -158,9 +158,9 @@ abstract class AbstractObjectsController extends AbstractPostsController { $object->save(); return $this->get_object( $object->get_id() ); - } catch ( WC_Data_Exception $e ) { + } catch ( \WC_Data_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { + } catch ( \WC_REST_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } @@ -185,10 +185,10 @@ abstract class AbstractObjectsController extends AbstractPostsController { try { $this->update_additional_fields_for_object( $object, $request ); - } catch ( WC_Data_Exception $e ) { + } catch ( \WC_Data_Exception $e ) { $object->delete(); return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { + } catch ( \WC_REST_Exception $e ) { $object->delete(); return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } @@ -232,9 +232,9 @@ abstract class AbstractObjectsController extends AbstractPostsController { try { $this->update_additional_fields_for_object( $object, $request ); - } catch ( WC_Data_Exception $e ) { + } catch ( \WC_Data_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { + } catch ( \WC_REST_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/RestApi/Version4/Controllers/Customers.php index 616bc60caa9..4194b7d8ebf 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/RestApi/Version4/Controllers/Customers.php @@ -364,7 +364,7 @@ class Customers extends AbstractController { /** * Create a single customer. * - * @throws WC_REST_Exception On invalid params. + * @throws \WC_REST_Exception On invalid params. * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error\WP_REST_Response */ @@ -411,7 +411,7 @@ class Customers extends AbstractController { $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ) ); return $response; - } catch ( Exception $e ) { + } catch ( \Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } @@ -439,7 +439,8 @@ class Customers extends AbstractController { /** * Update a single user. * - * @throws WC_REST_Exception On invalid params. + * @throws \WC_REST_Exception On invalid params. + * * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error\WP_REST_Response */ diff --git a/src/RestApi/Version4/Controllers/OrderRefunds.php b/src/RestApi/Version4/Controllers/OrderRefunds.php index 7c7fdcffbaa..16af7ef6dba 100644 --- a/src/RestApi/Version4/Controllers/OrderRefunds.php +++ b/src/RestApi/Version4/Controllers/OrderRefunds.php @@ -500,7 +500,7 @@ class OrderRefunds extends Orders { * @since 3.0.0 * @param \WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. - * @return WC_Data|\WP_Error + * @return \WC_Data|\WP_Error */ protected function save_object( $request, $creating = false ) { try { @@ -511,9 +511,9 @@ class OrderRefunds extends Orders { } return $this->get_object( $object->get_id() ); - } catch ( WC_Data_Exception $e ) { + } catch ( \WC_Data_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { + } catch ( \WC_REST_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/RestApi/Version4/Controllers/Orders.php index 33497fe8d57..efbdb199951 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/RestApi/Version4/Controllers/Orders.php @@ -589,9 +589,9 @@ class Orders extends AbstractObjectsController { } return $this->get_object( $object->get_id() ); - } catch ( WC_Data_Exception $e ) { + } catch ( \WC_Data_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { + } catch ( \WC_REST_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } } @@ -1749,9 +1749,10 @@ class Orders extends AbstractObjectsController { /** * Calculate coupons. * - * @throws WC_REST_Exception When fails to set any item. + * @throws \WC_REST_Exception When fails to set any item. + * * @param \WP_REST_Request $request Request object. - * @param WC_Order $order Order data. + * @param \WC_Order $order Order data. * @return bool */ protected function calculate_coupons( $request, $order ) { diff --git a/src/RestApi/Version4/Controllers/ProductVariations.php b/src/RestApi/Version4/Controllers/ProductVariations.php index 51236aa91ed..f65cf24369d 100644 --- a/src/RestApi/Version4/Controllers/ProductVariations.php +++ b/src/RestApi/Version4/Controllers/ProductVariations.php @@ -177,10 +177,11 @@ class ProductVariations extends Products { * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { - $data = array( + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = array( 'id' => $object->get_id(), 'name' => $object->get_name( $context ), - 'type' => $object->get_type(), + 'type' => $object->get_type(), 'parent_id' => $object->get_parent_id( $context ), 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), @@ -284,9 +285,10 @@ class ProductVariations extends Products { /** * Set variation image. * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product_Variation $variation Variation instance. - * @param array $image Image data. + * @throws \WC_REST_Exception REST API exceptions. + * + * @param \WC_Product_Variation $variation Variation instance. + * @param array $image Image data. * @return WC_Product_Variation */ protected function set_variation_image( $variation, $image ) { @@ -1197,7 +1199,7 @@ class ProductVariations extends Products { 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); - + $params['search'] = array( 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), 'type' => 'string', @@ -1214,13 +1216,13 @@ class ProductVariations extends Products { * @return \WP_Error\WP_REST_Response */ public function get_items( $request ) { - add_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10, 2 ); - add_filter( 'posts_join', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_join' ), 10, 2 ); - add_filter( 'posts_groupby', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_group_by' ), 10, 2 ); + add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); + add_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10, 2 ); + add_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10, 2 ); $response = parent::get_items( $request ); - remove_filter( 'posts_where', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_filter' ), 10 ); - remove_filter( 'posts_join', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_join' ), 10 ); - remove_filter( 'posts_groupby', array( 'WC_Admin_REST_Products_Controller', 'add_wp_query_group_by' ), 10 ); + remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10 ); + remove_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10 ); + remove_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10 ); return $response; } } diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/RestApi/Version4/Controllers/Products.php index 464a0b9c7b8..73477850733 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/RestApi/Version4/Controllers/Products.php @@ -1200,7 +1200,8 @@ class Products extends AbstractObjectsController { /** * Set product images. * - * @throws WC_REST_Exception REST API exceptions. + * @throws \WC_REST_Exception REST API exceptions. + * * @param WC_Product $product Product instance. * @param array $images Images data. * @return WC_Product diff --git a/src/RestApi/Version4/Controllers/Reports/CouponStats.php b/src/RestApi/Version4/Controllers/Reports/CouponStats.php index 279ba053350..5b5bfdb2365 100644 --- a/src/RestApi/Version4/Controllers/Reports/CouponStats.php +++ b/src/RestApi/Version4/Controllers/Reports/CouponStats.php @@ -57,7 +57,7 @@ class CouponStats extends Reports { $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 ) { + } catch ( \WC_Admin_Reports_Parameter_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } diff --git a/src/RestApi/Version4/Controllers/Reports/OrderStats.php b/src/RestApi/Version4/Controllers/Reports/OrderStats.php index 1b0224d2026..894bde56073 100644 --- a/src/RestApi/Version4/Controllers/Reports/OrderStats.php +++ b/src/RestApi/Version4/Controllers/Reports/OrderStats.php @@ -67,7 +67,7 @@ class OrderStats extends Reports { $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 ) { + } catch ( \WC_Admin_Reports_Parameter_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } diff --git a/src/RestApi/Version4/Controllers/Reports/ProductStats.php b/src/RestApi/Version4/Controllers/Reports/ProductStats.php index 2794e7e56d9..d68a760e485 100644 --- a/src/RestApi/Version4/Controllers/Reports/ProductStats.php +++ b/src/RestApi/Version4/Controllers/Reports/ProductStats.php @@ -72,7 +72,7 @@ class ProductStats extends Reports { $query = new \WC_Admin_Reports_Products_Stats_Query( $query_args ); try { $report_data = $query->get_data(); - } catch ( WC_Admin_Reports_Parameter_Exception $e ) { + } catch ( \WC_Admin_Reports_Parameter_Exception $e ) { return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } diff --git a/src/Utilities/SingletonTrait.php b/src/Utilities/SingletonTrait.php index 5190f079023..e39c1e35998 100644 --- a/src/Utilities/SingletonTrait.php +++ b/src/Utilities/SingletonTrait.php @@ -9,8 +9,6 @@ namespace WooCommerce\Utilities; -defined( 'ABSPATH' ) || exit; - /** * Singleton trait. */ diff --git a/unit-tests/AbstractReportsTest.php b/unit-tests/AbstractReportsTest.php index e74d971fd96..c5617c8b355 100644 --- a/unit-tests/AbstractReportsTest.php +++ b/unit-tests/AbstractReportsTest.php @@ -9,10 +9,6 @@ defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\Bootstrap; use \WC_REST_Unit_Test_Case; -use \WP_REST_Request; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Class AbstractReportsTest. diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index c1120e72a71..b8de3d6af58 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -6,34 +6,48 @@ */ namespace WooCommerce\RestApi\UnitTests; +require __DIR__ . '/../src/Utilities/SingletonTrait.php'; + +use WooCommerce\Utilities\SingletonTrait; + class Bootstrap { + use SingletonTrait; /** * Directory path to WP core tests. * * @var string */ - protected static $wp_tests_dir; + protected $wp_tests_dir; /** * Directory path to woocommerce core tests. * * @var string */ - protected static $wc_tests_dir; + protected $wc_tests_dir; /** * Init unit testing library. */ - public static function init() { - self::$wc_tests_dir = dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce/tests'; - self::$wp_tests_dir = getenv( 'WP_TESTS_DIR' ); + public function init() { + $this->wc_tests_dir = dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce/tests'; + $this->wp_tests_dir = getenv( 'WP_TESTS_DIR' ); - if ( ! self::$wp_tests_dir ) { - self::$wp_tests_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; + if ( ! $this->wp_tests_dir ) { + $this->wp_tests_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; } - self::setup_hooks(); - self::load_framework(); + $this->setup_hooks(); + $this->load_framework(); + } + + /** + * Get tests dir. + * + * @return string + */ + public function get_dir() { + return __DIR__; } /** @@ -41,22 +55,22 @@ class Bootstrap { * * @return boolean */ - protected static function wc_admin_exists() { + protected function wc_admin_exists() { return file_exists( dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php' ); } /** * Setup hooks. */ - protected static function setup_hooks() { + protected function setup_hooks() { // Give access to tests_add_filter() function. - require_once self::$wp_tests_dir . '/includes/functions.php'; + require_once $this->wp_tests_dir . '/includes/functions.php'; \tests_add_filter( 'muplugins_loaded', function() { require_once dirname( dirname( __DIR__ ) ) . '/woocommerce/woocommerce.php'; require_once dirname( __DIR__ ) . '/woocommerce-rest-api.php'; - if ( self::wc_admin_exists() ) { + if ( $this->wc_admin_exists() ) { require_once dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php'; } } ); @@ -70,7 +84,7 @@ class Bootstrap { \WC_Install::install(); - if ( self::wc_admin_exists() ) { + if ( $this->wc_admin_exists() ) { echo esc_html( 'Installing WooCommerce Admin...' . PHP_EOL ); require_once dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/includes/class-wc-admin-install.php'; \WC_Admin_Install::create_tables(); @@ -85,16 +99,16 @@ class Bootstrap { /** * Load the testing framework. */ - protected static function load_framework() { + protected function load_framework() { // Start up the WP testing environment. - require_once self::$wp_tests_dir . '/includes/bootstrap.php'; + require_once $this->wp_tests_dir . '/includes/bootstrap.php'; // WooCommerce Core Testing Framework. - require_once self::$wc_tests_dir . '/framework/class-wc-unit-test-factory.php'; - require_once self::$wc_tests_dir . '/framework/vendor/class-wp-test-spy-rest-server.php'; - require_once self::$wc_tests_dir . '/includes/wp-http-testcase.php'; - require_once self::$wc_tests_dir . '/framework/class-wc-unit-test-case.php'; - require_once self::$wc_tests_dir . '/framework/class-wc-rest-unit-test-case.php'; + require_once $this->wc_tests_dir . '/framework/class-wc-unit-test-factory.php'; + require_once $this->wc_tests_dir . '/framework/vendor/class-wp-test-spy-rest-server.php'; + require_once $this->wc_tests_dir . '/includes/wp-http-testcase.php'; + require_once $this->wc_tests_dir . '/framework/class-wc-unit-test-case.php'; + require_once $this->wc_tests_dir . '/framework/class-wc-rest-unit-test-case.php'; require_once __DIR__ . '/Helpers/AdminNotesHelper.php'; require_once __DIR__ . '/Helpers/CouponHelper.php'; @@ -109,4 +123,4 @@ class Bootstrap { } } -Bootstrap::init(); +Bootstrap::instance()->init(); diff --git a/unit-tests/Helpers/QueueHelper.php b/unit-tests/Helpers/QueueHelper.php index 3b233ab5db3..31225a8edc3 100644 --- a/unit-tests/Helpers/QueueHelper.php +++ b/unit-tests/Helpers/QueueHelper.php @@ -54,7 +54,7 @@ class QueueHelper { public static function process_pending() { $jobs = self::get_all_pending(); - $queue_runner = new ActionScheduler_QueueRunner(); + $queue_runner = new \ActionScheduler_QueueRunner(); foreach ( $jobs as $job_id => $job ) { $queue_runner->process_action( $job_id ); } diff --git a/unit-tests/Tests/Version3/functions.php b/unit-tests/Tests/Version3/functions.php index 6c079556341..19a523f5d5d 100644 --- a/unit-tests/Tests/Version3/functions.php +++ b/unit-tests/Tests/Version3/functions.php @@ -232,14 +232,14 @@ class WC_Tests_API_Functions extends WC_Unit_Test_Case { } elseif ( 'http://somedomain.com/invalid-image-2.png' === $url ) { // image with an unsupported mime type. // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( WC_Unit_Tests_Bootstrap::instance()->tests_dir . '/data/file.txt', $request['filename'] ); + copy( WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/file.txt', $request['filename'] ); $mocked_response = array( 'response' => array( 'code' => 200 ), ); } elseif ( 'http://somedomain.com/' . $this->file_name === $url ) { // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( WC_Unit_Tests_Bootstrap::instance()->tests_dir . '/data/Dr1Bczxq4q.png', $request['filename'] ); + copy( WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/Dr1Bczxq4q.png', $request['filename'] ); $mocked_response = array( 'response' => array( 'code' => 200 ), diff --git a/unit-tests/Tests/Version4/Orders.php b/unit-tests/Tests/Version4/Orders.php index 7bb2feb98d3..730245d278b 100644 --- a/unit-tests/Tests/Version4/Orders.php +++ b/unit-tests/Tests/Version4/Orders.php @@ -10,6 +10,9 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Abstract Rest API Test Class diff --git a/unit-tests/Tests/Version4/ProductReviews.php b/unit-tests/Tests/Version4/ProductReviews.php index f45203d5aad..ec9417704db 100644 --- a/unit-tests/Tests/Version4/ProductReviews.php +++ b/unit-tests/Tests/Version4/ProductReviews.php @@ -350,7 +350,6 @@ class ProductReviews extends AbstractRestApiTest { * @since 3.5.0 */ public function test_product_reviews_batch() { - wp_set_current_user( $this->user ); $product = ProductHelper::create_simple_product(); $review_1_id = ProductHelper::create_product_review( $product->get_id() ); diff --git a/unit-tests/Tests/Version4/ProductVariations.php b/unit-tests/Tests/Version4/ProductVariations.php index 92a732de21b..2b9fd04d279 100644 --- a/unit-tests/Tests/Version4/ProductVariations.php +++ b/unit-tests/Tests/Version4/ProductVariations.php @@ -252,7 +252,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { ) ); $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); + $this->assertEquals( 404, $response->get_status() ); } /** @@ -369,7 +369,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $data['create'][0]['sku'] ); $this->assertEquals( 'medium', $data['create'][0]['attributes'][0]['option'] ); - $this->assertEquals( $children[1], $data['delete'][0]['id'] ); + $this->assertEquals( $children[1], $data['delete'][0]['previous']['id'] ); $request = new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ); $response = $this->server->dispatch( $request ); @@ -390,7 +390,7 @@ class ProductVariations extends WC_REST_Unit_Test_Case { $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 37, count( $properties ) ); + $this->assertEquals( 40, count( $properties ) ); $this->assertArrayHasKey( 'id', $properties ); $this->assertArrayHasKey( 'date_created', $properties ); $this->assertArrayHasKey( 'date_modified', $properties ); diff --git a/unit-tests/Tests/Version4/Reports/Categories.php b/unit-tests/Tests/Version4/Reports/Categories.php index ce84c1e9deb..11f06d3c686 100644 --- a/unit-tests/Tests/Version4/Reports/Categories.php +++ b/unit-tests/Tests/Version4/Reports/Categories.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Class Categories @@ -42,7 +46,7 @@ class Categories extends AbstractReportsTest { */ public function test_get_reports() { // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); @@ -90,7 +94,7 @@ class Categories extends AbstractReportsTest { $order->save(); // Populate all of the data. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product 2' ); $product->set_regular_price( 100 ); $second_category_id = wp_create_category( 'Second Category' ); diff --git a/unit-tests/Tests/Version4/Reports/Coupons.php b/unit-tests/Tests/Version4/Reports/Coupons.php index 5aecfd0903f..e046ca63488 100644 --- a/unit-tests/Tests/Version4/Reports/Coupons.php +++ b/unit-tests/Tests/Version4/Reports/Coupons.php @@ -10,6 +10,11 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; /** * Class Coupons @@ -37,7 +42,7 @@ class Coupons extends AbstractReportsTest { */ public function test_get_reports() { // Simple product. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); @@ -98,7 +103,7 @@ class Coupons extends AbstractReportsTest { */ public function test_get_reports_coupons_param() { // Simple product. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); diff --git a/unit-tests/Tests/Version4/Reports/CouponsStats.php b/unit-tests/Tests/Version4/Reports/CouponsStats.php index f59a9d0ba2c..22bbfd0cf97 100644 --- a/unit-tests/Tests/Version4/Reports/CouponsStats.php +++ b/unit-tests/Tests/Version4/Reports/CouponsStats.php @@ -10,6 +10,11 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; /** * Class CouponsStats @@ -38,7 +43,7 @@ class CouponsStats extends AbstractReportsTest { public function test_get_reports() { // Populate all of the data. // Simple product. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); diff --git a/unit-tests/Tests/Version4/Reports/CustomerStats.php b/unit-tests/Tests/Version4/Reports/CustomerStats.php index db4e35a14f8..447e17380e7 100644 --- a/unit-tests/Tests/Version4/Reports/CustomerStats.php +++ b/unit-tests/Tests/Version4/Reports/CustomerStats.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Customers Stats REST API Test Class @@ -85,7 +89,7 @@ class CustomerStats extends AbstractReportsTest { $test_customers[2]->save(); // Create a test product for use in an order. - $product = new WC_Product_Simple(); + $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); $product->set_regular_price( 25 ); $product->save(); diff --git a/unit-tests/Tests/Version4/Reports/Customers.php b/unit-tests/Tests/Version4/Reports/Customers.php index af136a77e51..13fea32e14d 100644 --- a/unit-tests/Tests/Version4/Reports/Customers.php +++ b/unit-tests/Tests/Version4/Reports/Customers.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Customers REST API Test Class @@ -65,8 +69,6 @@ class Customers extends AbstractReportsTest { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -103,7 +105,6 @@ class Customers extends AbstractReportsTest { * @since 3.5.0 */ public function test_user_creation() { - wp_set_current_user( $this->user ); $admin_id = wp_insert_user( array( 'user_login' => 'testadmin', diff --git a/unit-tests/Tests/Version4/Reports/DownloadStats.php b/unit-tests/Tests/Version4/Reports/DownloadStats.php index 2940f3a20a8..92b7d433ba6 100644 --- a/unit-tests/Tests/Version4/Reports/DownloadStats.php +++ b/unit-tests/Tests/Version4/Reports/DownloadStats.php @@ -10,6 +10,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Customers Stats REST API Test Class diff --git a/unit-tests/Tests/Version4/Reports/Downloads.php b/unit-tests/Tests/Version4/Reports/Downloads.php index cf8e3d905e5..fbc4cecd4cc 100644 --- a/unit-tests/Tests/Version4/Reports/Downloads.php +++ b/unit-tests/Tests/Version4/Reports/Downloads.php @@ -10,6 +10,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Customers Stats REST API Test Class diff --git a/unit-tests/Tests/Version4/Reports/Import.php b/unit-tests/Tests/Version4/Reports/Import.php index 875c9bfcdf1..34ce6ba09b1 100644 --- a/unit-tests/Tests/Version4/Reports/Import.php +++ b/unit-tests/Tests/Version4/Reports/Import.php @@ -10,6 +10,9 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WP_REST_Request; /** * Reports Customers Stats REST API Test Class @@ -32,12 +35,6 @@ class Import extends AbstractReportsTest { public function setUp() { parent::setUp(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - $this->customer = $this->factory->user->create( array( 'first_name' => 'Steve', @@ -70,8 +67,6 @@ class Import extends AbstractReportsTest { * Test reports schema. */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -95,8 +90,6 @@ class Import extends AbstractReportsTest { */ public function test_import_params() { global $wpdb; - wp_set_current_user( $this->user ); - // Populate all of the data. $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); @@ -197,8 +190,6 @@ class Import extends AbstractReportsTest { * Test cancelling import actions. */ public function test_cancel_import() { - wp_set_current_user( $this->user ); - // Populate all of the data. $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); @@ -232,7 +223,6 @@ class Import extends AbstractReportsTest { */ public function test_delete_stats() { global $wpdb; - wp_set_current_user( $this->user ); // Populate all of the data. $product = new \WC_Product_Simple(); @@ -301,8 +291,6 @@ class Import extends AbstractReportsTest { // Delete any pending actions that weren't fully run. \WC_Admin_Reports_Sync::clear_queued_actions(); - wp_set_current_user( $this->user ); - // Populate all of the data. $product = new \WC_Product_Simple(); $product->set_name( 'Test Product' ); diff --git a/unit-tests/Tests/Version4/Reports/OrderStats.php b/unit-tests/Tests/Version4/Reports/OrderStats.php index 8152df41541..0e20efc5bb4 100644 --- a/unit-tests/Tests/Version4/Reports/OrderStats.php +++ b/unit-tests/Tests/Version4/Reports/OrderStats.php @@ -10,6 +10,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Class OrderStats diff --git a/unit-tests/Tests/Version4/Reports/Orders.php b/unit-tests/Tests/Version4/Reports/Orders.php index 2f283602d5e..05b5c1c7c49 100644 --- a/unit-tests/Tests/Version4/Reports/Orders.php +++ b/unit-tests/Tests/Version4/Reports/Orders.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Orders REST API Test Class diff --git a/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php b/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php index 024daa95f8a..cd84cb5c1ff 100644 --- a/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php +++ b/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php @@ -10,6 +10,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * PerformanceIndicators diff --git a/unit-tests/Tests/Version4/Reports/ProductStats.php b/unit-tests/Tests/Version4/Reports/ProductStats.php index f30b6e0a0de..40f84200765 100644 --- a/unit-tests/Tests/Version4/Reports/ProductStats.php +++ b/unit-tests/Tests/Version4/Reports/ProductStats.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Class ProductStats diff --git a/unit-tests/Tests/Version4/Reports/Products.php b/unit-tests/Tests/Version4/Reports/Products.php index abcdf5436bb..becee6c9073 100644 --- a/unit-tests/Tests/Version4/Reports/Products.php +++ b/unit-tests/Tests/Version4/Reports/Products.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Products REST API Test Class diff --git a/unit-tests/Tests/Version4/Reports/RevenueStats.php b/unit-tests/Tests/Version4/Reports/RevenueStats.php index 10e8c44eac2..c750938ef5a 100644 --- a/unit-tests/Tests/Version4/Reports/RevenueStats.php +++ b/unit-tests/Tests/Version4/Reports/RevenueStats.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Class RevenueStats @@ -48,8 +52,6 @@ class RevenueStats extends AbstractReportsTest { * @since 3.5.0 */ public function test_get_reports() { - wp_set_current_user( $this->user ); - // @todo update after report interface is done. $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); $data = $response->get_data(); @@ -76,8 +78,6 @@ class RevenueStats extends AbstractReportsTest { * @since 3.5.0 */ public function test_reports_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version4/Reports/Stock.php b/unit-tests/Tests/Version4/Reports/Stock.php index a435aea84a0..9fc688a173e 100644 --- a/unit-tests/Tests/Version4/Reports/Stock.php +++ b/unit-tests/Tests/Version4/Reports/Stock.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Customers Stats REST API Test Class diff --git a/unit-tests/Tests/Version4/Reports/StockStats.php b/unit-tests/Tests/Version4/Reports/StockStats.php index 55ed6736e2d..51248a4fb4d 100644 --- a/unit-tests/Tests/Version4/Reports/StockStats.php +++ b/unit-tests/Tests/Version4/Reports/StockStats.php @@ -10,6 +10,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Class StockStats diff --git a/unit-tests/Tests/Version4/Reports/TaxStats.php b/unit-tests/Tests/Version4/Reports/TaxStats.php index 607b3d17909..0c8eebd9f92 100644 --- a/unit-tests/Tests/Version4/Reports/TaxStats.php +++ b/unit-tests/Tests/Version4/Reports/TaxStats.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * TaxStats diff --git a/unit-tests/Tests/Version4/Reports/Taxes.php b/unit-tests/Tests/Version4/Reports/Taxes.php index 4f93d8b8ada..d5f134d59a3 100644 --- a/unit-tests/Tests/Version4/Reports/Taxes.php +++ b/unit-tests/Tests/Version4/Reports/Taxes.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Customers Stats REST API Test Class diff --git a/unit-tests/Tests/Version4/Reports/Variations.php b/unit-tests/Tests/Version4/Reports/Variations.php index 8997ffcf314..48312f0be30 100644 --- a/unit-tests/Tests/Version4/Reports/Variations.php +++ b/unit-tests/Tests/Version4/Reports/Variations.php @@ -11,6 +11,10 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4\Reports; defined( 'ABSPATH' ) || exit; use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; +use \WP_REST_Request; +use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\QueueHelper; +use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Reports Customers Stats REST API Test Class diff --git a/unit-tests/data/Dr1Bczxq4q.png b/unit-tests/data/Dr1Bczxq4q.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2bb205fe40d4d8c5125399ffc585bc65595323 GIT binary patch literal 10325 zcmZX31yEeg()Qx+A&{U!6Wm<_Z14a90t5*T!4_NGArKZPxRb@*-Q5Dq;!c17i@V#$ zd++_f?^gX&HK+SbcRzjlnVP9H=Rnj{yHJOz26`m=0)?lG9?&({uN$6o*d zE~%A_jGBUs46T}zy@i#nIRGFJNzlg7j2n8H*^x^~tV@fmE^Qxp&eGur)gf^@kEvC*y`z4Z>&s%79HOI@!>{BK*u+KrO*Vz5p=2)9syJ!=y zB|6}PjTQ(bP>lK>U(%3}3elsitZ4Dm)1Pu2plO6dsbgzg?xv|p?$0yxWDsJH1Y9y~ zcrkE0d-B9GOj#a-2OvgsWRV*j3%JGvG>V97#}EL1QSIVw{oM{bq3tb3mL~+zarEz~ zmvZzMsf#I?kWd`pRFMJ9Si%|QG2To4PW#fS^26~(FJ;*cB{j|Z>rnBzS8Vvb1hkp) zal8~JA9#B6i&py-p7efCog}kq-3ldc(GgYCs3xb4re67R3_K;K+rsB4Z!16XqDsNn z)7P4(%}4P`O<8&eZi0~WSuN!#ryF-Ql$#>pt?uu6!gV*RK>u$=c=?(1lp{Db zCN&JsUAmpEr@SUXx$Qc1+R5Ys{Q*4}XGu<-Li)bx5ftbpBh0#6dOy>s7;6UVooY~W z^7bOAUcBs$xN+U?L5?d&xnzhVC1y;s5fYSS(Hh2+lOjJx^YzC9R^|oH(~=yEpr>N| z;oOl27$G6aW9S>bn~d;ake9tara-~&$|7_Oa9D!L@eHG(sXdwNvp(ns@(q0p=%vRI z3lhSZ?G<+r6vOpxGpgy!a7^Ns%wL}?1^Pj0xI@X`^HFSfg_PD9lK@sa;KALQI5i~B zYtfs>?9^+oeuW=@cZeI8X~bFY(olGjGR^ii_7BFEG9kXFQ7zz$YY~^lQ!*Y1_lxKs ziAK@C1Wg;b`XoB*ms}+FOC(!cfVx%Q7m?0)^@);W%oYzm50HrUBB%yZkw`>?>x>TOu(+u!z8CydBu``4?Pka6UyGdA z5!AWT^LsP~CEEI)cw(J3IiK~Vb-B47iXm}|(`W7AshV=|Cd2Aedu!|J9Z}zV*DFOw zHQ)}VL~@mTPi|(Qcjmodne5onK?hKJp#yxb)5iYbv0c>x(h+9isA%dL*Fxy1?~%eB zw7&tUi~!2U67`)#jYyn-2&CULgrX@JG3lS+#-IqpkZ?NH)sTlfbt{Q91MG~L3sLU6 z-i+f$1@ZntZp0Sp`shG2^MS@43%!erT#E4f_i;iIXaIsvHWbYyT!@}JRFXIZNUtD| z{WI#Ah^QLyB_#gMraWmiN|BuJhp0D}F(dM1PGlYt=k)e5s&7NoKYiAu;Fo3287mZg z9o7%!9S8Ffumi*4)880%!w+TB#(5E+&zTm2+JQf~{D(|&l?iHk)42`Vh?V*$xRB~G zS^HQjbxVnCf}hS@N--!pCDwuIQM`^yI%!hwlwbw|9%rs$b#8|C5N@W*1kiJO9BC+!@na?ugrgJDTg0tC0&*r`bXIl3A)$&xjEdH{|U^)D+m74dY2F{JM1xxGOXv} z;o;*!c2jgJcEfm@aEh_XIV73*B>(wWs)kR|WD(u2^)B_U)vm#=-s?yU-MiXIiG=9^?J45X%{exy-~Rl_O?H7sr52+;ehyqcX6 zLxzo^NsR4>?!;O#N8>Bavy5hRKC#sA(@!`I5!B z@=`ogw^C+OSGed?h11Ma?6~*%WK&~w(S zx2rqA6HPVnUp8rZ*)n_i@>2heYJz;Z zumRU-YE^O7M9Z>m5>6D(s98|O_KL+y%F11<;f>B6rgzkB>y^ue0m5s6;0))S^ z`y~3T;?(a&HcbrmI3X7~f>22E7)M%*-6ht*N;wy-L;!OpF7}M=I2* zTatDgwe36jlS=uksm45}hY=&Z{FW9lF>WQtmo_tNFQgTvhgafZrSe+rHgEZb>X=+& z4n|gbeTPogZU3A*FE?#2ZCf2$ZCY_oEKklBTv@tXXqw?3dwYCtolTKSS>#!@{9th~ z^m208-7gS?O<;k}5Q6AS4a_RaZeBz7``f$v#^L{s%Lif*DE{jDJ8a@wS%i3&SkE4H*d1~Le6S=xOu(ztUU2^ny%-*LJdMk20Q1Px~ zMdXEN;X&ouT0gz4oORShbfUnUk7udqX}qakx<7TBqk<`IY+P)_Z_}pjy`uK0DkOfn znv5z853R@L6kx03WsHf7J1{*c+b@>Z-&vBtR)hpE^apOn&yqM$^@Y6Pck4w;he=U} zu5I4?VP^?jB~jXG3seiykB7&1aQuO&d>fTnT@eEjy_S4%#{T8Lg!A&zZ7@ZbVEIZ! z+LDK(;N9V#7uuEVA*aWCcePu!9pgUwGP$}ZuDgK%>VZs>=m+Ws zNr;D2N7C}$Y0>e{cKf|?YECGkJ@R$X%>HlvLV&Y z$X>-|S8rGQY~XB;y;j?_d&_plLreXy!e4Sd!aejyN|N8a3-1v3C+h{@Rbg^l-b_B_ z_a>Kl7dD7lj2z*doF+CTB`4BOBbmtwfO`!FK$o~x6pZ}-Q%rjsL!kU>I5FxYNn$&U z0ok6zs}&Hchy0$rHODr16w`!dzfb!}htq#yK2k6Rb8_D{ud47EP3D?Q~ zM9s;e*OQg&*bg*2LUs^Qz1vCtx|qe{lu? zUNZjEkrdP!jsXCq3@c3?u+B$i5mS3R4r4QW6LSuCJBMd)06@%Ld2OHD6+u4Gg zMcl>d{^cR^tp792Nk{uH7qE>uoz6!!S{ZvMb6S25J`OHA32a(gS}`Xx3lVjo?0>?a z@5Jf8fx!+UoSbfMZX9mB9QIC@oZP~~!kk<@oIE`2&mQc~9w4x>J3Gjk{@)<~4+m)O zZ0cm?0JgFR(f)&LY+~;M7N?{8C(-}5e?O+B^I0PQGd0gm{<**Xk9^i~!e8K)hCfSf z1)!9sJJPZCCwJ_U)vRqc9gRH*y0qQ+STS8;843$>)X3NmGrRf(c8$970cBi;NA9zHQRz zzU$1a_xj#Idj*at!oeeZLaJ}>U!}lgif&NL%;Ck;%>Ayvy)8C^hU*FKHYqih#_eJd?;$r*2s)<^(JW-AG=IBi;{h+AO-UEff!1r0Lwuk+dwW zSNZ>T%NIz2yL%`9Zoc?nc5ae^e{H6AHA~HwRX5`?mW+5iB<9zJ#Q?)acN*=zL#<7? zuh++wI!A9Vn?x1~`#`|A|HX1-wc%qKL)bH7A}Qd7DT|J^05%-0?zrk}z5F?+w>o4=@l9y68&Mk^;fHdRz==+ut5w1}w+ ziv~DJ`gKinvUiB<Qd1Q7Ey#EOKARlpW7D&q$jFW{xB=&MX%c_jF^g#KS$TF+8<6<=>z-w+^~(`?Xj z3I_(AO;Wh-*&@tyT)SB1E4i7=HT4p>z0*8Wi5eRIFgS`0=l7>R)v@+cW>d%#OG6xY z&FM`N{zF9mFYcCdnXBb zK~6ZLOs4&3`6*Vac#UZ8$2ZO2Ip;8U7(WR#En?M_UDiE*_B}K$>W#?E*0qRg*V6J# z({hbpd3h=lx*~Las?jv~jvKoWg^YtRvH1t0bmPP-@*>G8DrLa#B!2bOQjJWDwaz@v zO~!bXF5M=}Gq;r?wvbW0c5xuwnt0$9YGSW#^3tiLvS55O%=!FQIaOl5?U7kt$RbK^ zqe5GzpLdck&3|^CSwkoMVqL{{__AOI3(C72CE!nOCrp`75e*Zg2L4dU0iNh}$iA4fpqX>84wb zG|_(Zo!_gvaw^b=jwQD&@WYSfIZ*S`ex(!GI)|xb?L#YqYTAbv z=C^T^~z56lI3xziK!l(Xx8}-S3|XhC9^NWxj>y`DbUxLy@Tn;Cd9- zEWTw9*MTPpJ>N(5G48WQ-V>B*8#^r8n=R2Z_W$Tti)M)p1_7W_i`n5Zp+@iw!U z*GlZxJmRYEnRyeYM}3J#Xo2MKRSp~;UBZk{ekOVfFi7oBaZ$EA6 z^reX_g)9OKrd1)J`CT0;@P}>>w#B#=quM>A2b^|4A@*h{=v$;4|6o48C1x z&f7PvnNFIDd)%?&Yel!m(E^^EXY9qy?Lml$<{Udl+MZN4 zG5Ueuj&I=!l}-91X^96P#6KT>xAb!6bfpz8CoT*;plw3zHA#>OO6yVsx{Y%GjTK898;RO3PQ-b&D}B2$&KQ|(K+tiF2_PriQO?;gK7M)J)vWK~&ZFBX^hXdlP$9hU){st>L*S+dL=++^|35 z^||AR0W!L1!?t!!_m78jySNjt8xCIC5gCa2AMRu_)pH;Z@UDtu)qsUOU=cf*?QF`W zbFWI+|5G#j_}W5F5O8;rv}))mft{J6P0rVYYwhM_sloP{`K7o8+}nK(G7nkW095!a z2{F)cV0*KTAATn;h-^fKAG-OxGV<-CLo@B)2iV^toq9%ut!y;t@p!V$`C<;aa;Rzx zd5lxp8Q9WTBGw9&#b}oMt8fnj9{(JQhpwz&c6xjSYub4)lxu>^XCAnuz(pN_deN#r z@TA97L{lL1pSquEPjyO;gk@h)b)h|(tYAVPD!7YxZ{o=dg=cj-qfH*&o>>+oWSmZ( zc;&hgwz8M;Nj=WRE+nv^jE2+)uMN^Jtz`qlwDi|Ayqx)vHHc93r#B?uU0agtQskOj zs7GA(&EP;KA?(43vs^R1?>VeNgB>-{hGfKt)qJHY>&*iX!nO})+rrHKdOmVPrh1o6 zyrn&F<6It9Y44e zg6yBv$l}xk^h9~2^u)u*6ZH>-(Ls8q9^k2~*eEehUJz2v(bvTJLWDTqmv!VMTlQ0_ zJf_;IjFG&DNg>C6UmdVX%1r2IX2ryfNBj4E+;?l_jiVxzQF1>nqNnTYxp894I;46T&OkhEpWcj96j!V^ z|NaSJi2Gc11qW)#Js5C+?rX{ zw6_-6uJ2Ic%*I|X;pTI`Dfm!TrrsiIpc`_Ybq#Qv@vf9X%XTIzq9=8w4^RW~{hZ7|B$%S%gP(AU;+dHg&4AsutSUw92lSrAD3kBI3=sbd? zmAlup{H|I95r>+Pbust|pjrGKvE7Mlz8`UpuAIa_7;RsmG`60cID(;%Jl_mAghJa1 zW@&FFmR2nImCjvTx;rv_7a3N#90(uqvL$)`iorde%4m9owk5prwExVEy&in8MPIvR z?q|3Z@p|qHX=qjqd459URZj;Vm85kkCFTD2ZJg5cs&|i*)r+LgNu1gV?Z6Y)AuqUh z5CXk2y;AqXo~mA!HM{U+>gTJI%gyLheT?I7-jp;W`c*3w+~Wae2;xTWHXb2(ZwS%g zBsgsAq4kVbNSp)832K}7NGTr9%iE6DCgDh&vYQ8@98b|8$e=JHH*roM1{N$REAgl! zXLe-Tp=Od3*x_RD1pzxD^lT_H(*K+X^8ImQr zEXCmd)`Z`T`sFKONF!nS(eRg+rv%J#lEb;<&(k1k|rVa?_wZJqa_D&h;mF#l*m z-MO#gRzq~n*sX*Pq$djuZO@pAA51*V^0D|LYILYe*2oy=iW0Fc=F^WHa|x-O2Wa9A zPu==9_9Ty+x5AC05KU0#MRn_H*4f1;Bmm&)i2)M$007`u|MQA{V6fx4CxUNt`$!-< z(spLE1xD?z%pO&mU~nb&E0~u3#DED8i`&wFyvXYCYnRXt>V&D%B#vyJ_WgQne8E@+ zmU`(VIhn3mV-=rb>78JAkyVoJ81&>f(ean-w!MS%#JS1)hYTXkoaWE^rp&p-@QBo4 z?*UBqs4vv!RO%dZFlmvEpG5O~_#T91^@45~c?x){?q$w%FklBZg8s2{XaypNfD3bl zjPyb@{3*}_6$M7e-?CkCL#jCO+X2>!Xm6fd5!r3LCXUMKS=XY4$A9paK8c)MM>^Pf-G z-l1P*efiaMI^B=6f%85L9nIq?sF~(zrWbE1KuotN>yERGm&oEjul{)WF!*T~fHd1@ zx7r>L6FT4-$&Z)7BO00h@hA{Lq}YKeic_rn{yukmn7KufCMimAlN%2NnrEPaWS8ol*8sNc+IV(P4h}HcIdOZi(?G^~;ZbLgvn6YH@|hIn2@w4)Vk#$=EAcNtYzB^pR(ly3qTr2XpN;9XH_mDX;!x}PF5ajO&UX3hqZ zpVtG&+1LdyiTHZ|pVNp;lp^sMuQBzs`*&aaX6vsoGXz~zOmiz{0_r=cSs;G|zwVs1 zXV#luB|I*JY`EA0So0qk+BkK z_u4xs-A=B|1|2+T`aU7)bkXYYU`7HcsIwa}Qc8f-In{EE{!#!#5EHqO7RouW#?RwP z5MXl~Y7_Zx;XadWmu+BAI2KOQ`7p&-9VW6}z(HSCbB+_A+6d|}YpqB;8fp}ij}%V5 zdefX!qqV)|_HHe-J)MgQ^5>g^?+8P=MV+rMbQS=~Ufl_Iiiw0XIpA~fa%@+x_%8}G0CmAN2rvjzCUj?<|p5#N5&kb zA-sPL8jU;-}UiDm-NvGGBH* zp{&Oz2?2&lYI7FVUL-#Df0i@Zofk)&qU>%KdbHM!EC2uf% zX`IG8OP=ORe)(-pE8mPj;Zvehh01{0NORf!sl^J^`Ah$Wq`hf+BI1E9hnY@f>@V9v z7h#IS{gB@TgjW75qXh&}lvrGYDSLna7iUQmwr8iYQO^Ox9FiP@F@$`+wumH&J*zu0 z(EF{>A^ii-Oq{Ys-eYi_?1w`0r(1mukEC4)L}i_*TtXnFakG(R%DnaKSaM*phLMm;OQ_qzTDW0ZbCj;=lygNHM!rzbIW? z;FJLaFbb)bh#U<<{PMDbM&}4UcW}ky9_9B)w#v8bxx_478!H14;!D8wapNuYF6L^* zEg3M%H=6`A6ZAq9TJ@hX<2uAt2V(i6fWJ=oj!-2-YB_}O#7TZuz@Zd)0YK4UaJae< zLHlmZy5_EQ$|lNXhHo~krhDqmE5>M7w!I&v(MqdFNu058AC#%T^o6LBB*G|Ph^ew! z-^aY^l3~)!HS7=bEGxaZUHF=Dc$fG&oO3seX(6a*K;6R@A=zB)qo{~GXXSu#>op*)G}J76)5&2u;&GFo(unKYdiy9P=KUUBCcYUo=N&b1iNz>B?$e z`R<4s-p~PIUB?l1vf%G~e&)3>vM#)rta~Vo@THMDBQo zAK*D9XG}6scD03wN`F+xY-SpDlxJ>1Ea-0Ws6rlGiJT=Jd0P5v8D;0IecjB*HW>6S)CQ2AB`Rq-#Uch1LDi z_^hgQUUBn&c|j8dB-%X^k*04s8U^_6Pquyni{m_ zekDNzNrr~_Rd*6El|j3J7`DFW?gY-{4P@o4SiCu2eG=X$5+3YhKuyCcXdl4*1u`#!vS4B<73cAW`$5s}&$^9Fv$I(6#*+Ib}o(X9#Az}hDi zxDUPl)OJF4@d;AllC!|9`a`=%Fye9nJ@6+2^&131dxW?p%owZ{sts*Y7QNjeLUv=k zZN+?5Ve#p<{}{=RSke~}LEYt(mJ^=i)X}`LU(z}(d+P!v$@MM=dSR9RL=2ybIEQ$g zIU*iHzp9N!0(U!$v`{^MF z6=jqq2ldUnT9+WgS%`4*bX~ch=g5hZs=WhV&5Zu&C8%6+~q* z7S<(7;zQ#SuQOvQ{K#Q2&^<7w+mV8}*J110bju~g?qHwkg!IPfFEfZjzWOP;;?v&{rao0Wn$Ie-;Ip|sROylv<5A|k~{z87b{E*c;t zr4%eyeqBa#p}qnOr{=OgZ7TP2j`5x-nIZ{+UK8UJwTBudt|Cj7k+6WRmRr*%24g41 zhM3Mqc!WvP>X~jQ(%<>ShpFQ@Q~t06MkAD)6;CZGXmbdE9}Dhvn8@`Lu3!ZbZ<8y? z@IUGu7ec$w!jj~YRFI5~2RB6ev4 zrqv{>e<|ZmIhZBiIo=EyrXT=45T*BrGUvFiGX!M2f7(dk0Sexq{Lqr>v3z!C&MM#jm%MB%eC!=C+LbBg9`#0w={e%}aFoIh$?fqTPKYP8e z#mpmCx0X{YQ1_)T+BZH%>SJseQ5JKt6zig|NHW85aFCdxfgw!i8TK#@E2s Tmze$k{5ewipaLwHHVXV7`I0Rd literal 0 HcmV?d00001 diff --git a/unit-tests/data/file.txt b/unit-tests/data/file.txt new file mode 100644 index 00000000000..078595600bd --- /dev/null +++ b/unit-tests/data/file.txt @@ -0,0 +1 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi porta purus dolor, malesuada consequat sem blandit eu. Pellentesque tempor elementum maximus. Phasellus efficitur turpis ante, ac egestas nisl efficitur sit amet. Vestibulum tortor erat, efficitur id nulla eget, malesuada lobortis augue. Ut eleifend ante at pharetra gravida. Quisque suscipit efficitur mauris, quis bibendum massa efficitur id. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vel luctus nisl, ac bibendum nulla. Sed faucibus nibh consectetur urna hendrerit sagittis. Sed bibendum felis in tortor elementum, a porttitor lacus volutpat. Etiam facilisis congue lacinia. Quisque vitae ultricies mauris, non ornare orci. From 4151623b9cca32e26e78b749dee3bf9d15c827e8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 17:09:42 +0100 Subject: [PATCH 065/440] Travis setup --- .travis.yml | 28 +++++ unit-tests/bin/install.sh | 210 ++++++++++++++++++++++++++++++++++++++ unit-tests/bin/phpcs.sh | 11 ++ unit-tests/bin/phpunit.sh | 8 ++ unit-tests/bin/travis.sh | 12 +++ 5 files changed, 269 insertions(+) create mode 100644 .travis.yml create mode 100755 unit-tests/bin/install.sh create mode 100755 unit-tests/bin/phpcs.sh create mode 100755 unit-tests/bin/phpunit.sh create mode 100755 unit-tests/bin/travis.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..96d37559994 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +language: php + +sudo: false + +matrix: + include: + - name: "PHP 7.2 unit tests, PHP Coding standards check and JS tests" + php: 7.2 + env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress RUN_PHPCS=1 + - name: "PHP 7.1 unit tests" + php: 7.1 + env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress + - name: "PHP 7.0 unit tests" + php: 7.0 + env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress + - name: "PHP 5.6 unit tests" + php: 5.6 + env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress + +before_script: + - phpenv config-rm xdebug.ini + - export PATH="$HOME/.composer/vendor/bin:$PATH" + - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION + - bash bin/travis.sh before + +script: + - bash unit-tests/bin/phpunit.sh + - bash unit-tests/tests/bin/phpcs.sh \ No newline at end of file diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh new file mode 100755 index 00000000000..fb72cc86ab5 --- /dev/null +++ b/unit-tests/bin/install.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env bash + +if [ $# -lt 3 ]; then + echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" + exit 1 +fi + +DB_NAME=$1 +DB_USER=$2 +DB_PASS=$3 +DB_HOST=${4-localhost} +WP_VERSION=${5-latest} +SKIP_DB_CREATE=${6-false} + +TMPDIR=${TMPDIR-/tmp} +TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//") +WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib} +WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress/} + +# Error if WP < 5 +if [[ $WP_VERSION =~ ^([0-9]+)[0-9\.]+\-? ]]; then + if [ "5" -gt "${BASH_REMATCH[1]}" ]; then + echo "You must use WordPress 5.0 or greater." + exit 1 + fi +fi + +download() { + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + fi +} + +if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then + WP_TESTS_TAG="branches/$WP_VERSION" +elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then + if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then + # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x + WP_TESTS_TAG="tags/${WP_VERSION%??}" + else + WP_TESTS_TAG="tags/$WP_VERSION" + fi +elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + WP_TESTS_TAG="trunk" +else + # http serves a single offer, whereas https serves multiple. we only want one + download http://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json + grep '[0-9]+\.[0-9]+(\.[0-9]+)?' $TMPDIR/wp-latest.json + LATEST_VERSION=$(grep -o '"version":"[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//') + if [[ -z "$LATEST_VERSION" ]]; then + echo "Latest WordPress version could not be found" + exit 1 + fi + WP_TESTS_TAG="tags/$LATEST_VERSION" +fi + +set -ex + +install_wp() { + + if [ -d $WP_CORE_DIR ]; then + return; + fi + + mkdir -p $WP_CORE_DIR + + if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + mkdir -p $TMPDIR/wordpress-nightly + download https://wordpress.org/nightly-builds/wordpress-latest.zip $TMPDIR/wordpress-nightly/wordpress-nightly.zip + unzip -q $TMPDIR/wordpress-nightly/wordpress-nightly.zip -d $TMPDIR/wordpress-nightly/ + mv $TMPDIR/wordpress-nightly/wordpress/* $WP_CORE_DIR + else + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then + # https serves multiple offers, whereas http serves single. + download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json + if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then + # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x + LATEST_VERSION=${WP_VERSION%??} + else + # otherwise, scan the releases and get the most up to date minor version of the major release + local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'` + LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1) + fi + if [[ -z "$LATEST_VERSION" ]]; then + local ARCHIVE_NAME="wordpress-$WP_VERSION" + else + local ARCHIVE_NAME="wordpress-$LATEST_VERSION" + fi + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz + tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR + fi + + download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php +} + +install_test_suite() { + # portable in-place argument for both GNU sed and Mac OSX sed + if [[ $(uname -s) == 'Darwin' ]]; then + local ioption='-i .bak' + else + local ioption='-i' + fi + + # set up testing suite if it doesn't yet exist + if [ ! -d $WP_TESTS_DIR ]; then + # set up testing suite + mkdir -p $WP_TESTS_DIR + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data + fi + + if [ ! -f wp-tests-config.php ]; then + download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php + # remove all forward slashes in the end + WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php + fi + +} + +install_db() { + + if [ ${SKIP_DB_CREATE} = "true" ]; then + return 0 + fi + + # parse DB_HOST for port or socket references + local PARTS=(${DB_HOST//\:/ }) + local DB_HOSTNAME=${PARTS[0]}; + local DB_SOCK_OR_PORT=${PARTS[1]}; + local EXTRA="" + + if ! [ -z $DB_HOSTNAME ] ; then + if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then + EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" + elif ! [ -z $DB_SOCK_OR_PORT ] ; then + EXTRA=" --socket=$DB_SOCK_OR_PORT" + elif ! [ -z $DB_HOSTNAME ] ; then + EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" + fi + fi + + # create database + mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +} + +install_deps() { + + # Script Variables + WP_SITE_URL="http://local.wordpress.test" + BRANCH=$TRAVIS_BRANCH + REPO=$TRAVIS_REPO_SLUG + WORKING_DIR="$PWD" + + if [ "$TRAVIS_PULL_REQUEST_BRANCH" != "" ]; then + BRANCH=$TRAVIS_PULL_REQUEST_BRANCH + REPO=$TRAVIS_PULL_REQUEST_SLUG + fi + + # Set up WordPress using wp-cli + mkdir -p "$WP_CORE_DIR" + cd "$WP_CORE_DIR" + + curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar + php wp-cli.phar core config --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS --dbhost=$DB_HOST --dbprefix=wptests_ + php wp-cli.phar core install --url="$WP_SITE_URL" --title="Example" --admin_user=admin --admin_password=password --admin_email=info@example.com --path=$WP_CORE_DIR --skip-email + + # Install WooCommerce + cd "wp-content/plugins/" + # As zip file does not include tests, we have to get it from git repo. + git clone --depth 1 https://github.com/woocommerce/woocommerce.git + cd "$WP_CORE_DIR" + php wp-cli.phar plugin activate woocommerce + + if [ "$TRAVIS_PULL_REQUEST_BRANCH" != "" ]; then + BRANCH="$(sed 's/#/%23/' <<<$BRANCH)" + # Install woocommerce-admin, the correct branch, if running from Travis CI. + php wp-cli.phar plugin install https://github.com/$REPO/archive/$BRANCH.zip --activate + fi + + # Install WooCommerce-Admin + git clone --depth 1 https://github.com/woocommerce/woocommerce-admin.git + cd "$WP_CORE_DIR" + php wp-cli.phar plugin activate woocommerce-admin + + if [ "$TRAVIS_PULL_REQUEST_BRANCH" != "" ]; then + BRANCH="$(sed 's/#/%23/' <<<$BRANCH)" + # Install woocommerce-admin, the correct branch, if running from Travis CI. + php wp-cli.phar plugin install https://github.com/$REPO/archive/$BRANCH.zip --activate + fi + + # Back to original dir + cd "$WORKING_DIR" +} + +install_wp +install_test_suite +install_db +install_deps \ No newline at end of file diff --git a/unit-tests/bin/phpcs.sh b/unit-tests/bin/phpcs.sh new file mode 100755 index 00000000000..5a2c8b48a05 --- /dev/null +++ b/unit-tests/bin/phpcs.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +if [[ ${RUN_PHPCS} == 1 ]]; then + CHANGED_FILES=`git diff --name-only --diff-filter=ACMR $TRAVIS_COMMIT_RANGE | grep \\\\.php | awk '{print}' ORS=' '` + IGNORE="" + + if [ "$CHANGED_FILES" != "" ]; then + echo "Running Code Sniffer." + ./vendor/bin/phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES + fi +fi diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh new file mode 100755 index 00000000000..ae5e4ef3f8a --- /dev/null +++ b/unit-tests/bin/phpunit.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +WORKING_DIR="$PWD" +cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" +phpunit --version +phpunit -c phpunit.xml.dist +TEST_RESULT=$? +cd "$WORKING_DIR" +exit $TEST_RESULT diff --git a/unit-tests/bin/travis.sh b/unit-tests/bin/travis.sh new file mode 100755 index 00000000000..e7b020cc9ac --- /dev/null +++ b/unit-tests/bin/travis.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# usage: travis.sh before|after + +if [ $1 == 'before' ]; then + + if [[ ${RUN_PHPCS} == 1 ]]; then + cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" + # This can (currently) only run for PHP 7.1+ + composer install + fi + +fi From 4fbac5f27c99070dde7e116a786c90b4e46c0d54 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 17:19:33 +0100 Subject: [PATCH 066/440] Badges --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ac2c5d64e71..ad07e1d85b6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ WooCommerce REST API === +license +Latest Stable Version +Build Status +Scrutinizer Code Quality + This repository is home to the WooCommerce REST API package. The stable version of this package is bundled with [WooCommerce core](https://github.com/woocommerce/woocommerce) releases, but it can also be used as a standalone plugin so bleeding-edge API features can be tested or used by other feature plugins. From f070efea19b0a325c6a0892eb49148e8b290a9e1 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 17:20:37 +0100 Subject: [PATCH 067/440] Fix badge url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad07e1d85b6..5fa541fa285 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ WooCommerce REST API license Latest Stable Version -Build Status +Build Status Scrutinizer Code Quality This repository is home to the WooCommerce REST API package. From adb8dc5ede0f9b90a6cd8805c0fc0fb964fda130 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 17:22:33 +0100 Subject: [PATCH 068/440] test paths --- .gitignore | 9 +-------- .travis.yml | 6 +++--- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 33f6bb1d8a7..b19a8d1f0ae 100644 --- a/.gitignore +++ b/.gitignore @@ -24,16 +24,9 @@ none # Windows junk Thumbs.db -# Behat/CLI Tests -tests/cli/installer -tests/cli/composer.phar -tests/cli/composer.lock -tests/cli/composer.json -tests/cli/vendor - # Unit tests /tmp -/tests/bin/tmp +/unit-tests/bin/tmp # Logs /logs diff --git a/.travis.yml b/.travis.yml index 96d37559994..ff3c101a399 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,9 +20,9 @@ matrix: before_script: - phpenv config-rm xdebug.ini - export PATH="$HOME/.composer/vendor/bin:$PATH" - - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION - - bash bin/travis.sh before + - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION + - bash unit-tests/bin/travis.sh before script: - bash unit-tests/bin/phpunit.sh - - bash unit-tests/tests/bin/phpcs.sh \ No newline at end of file + - bash unit-tests/bin/phpcs.sh \ No newline at end of file From aa16047538f88936bf787c492236d0b8e91a31bb Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 17:23:46 +0100 Subject: [PATCH 069/440] Update test description --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ff3c101a399..7f85dcd410c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ sudo: false matrix: include: - - name: "PHP 7.2 unit tests, PHP Coding standards check and JS tests" + - name: "PHP 7.2 unit tests, PHP Coding standards check" php: 7.2 env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress RUN_PHPCS=1 - name: "PHP 7.1 unit tests" From 103e24ade249f8bd0089827b3854c86cf323a0e1 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 17:28:55 +0100 Subject: [PATCH 070/440] Updated travis installer --- unit-tests/bin/install.sh | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh index fb72cc86ab5..d5579b4a5f5 100755 --- a/unit-tests/bin/install.sh +++ b/unit-tests/bin/install.sh @@ -176,30 +176,16 @@ install_deps() { php wp-cli.phar core config --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS --dbhost=$DB_HOST --dbprefix=wptests_ php wp-cli.phar core install --url="$WP_SITE_URL" --title="Example" --admin_user=admin --admin_password=password --admin_email=info@example.com --path=$WP_CORE_DIR --skip-email - # Install WooCommerce + # Install WooCommerce and WooCommerce Admin cd "wp-content/plugins/" - # As zip file does not include tests, we have to get it from git repo. + git clone --depth 1 https://github.com/woocommerce/woocommerce.git + git clone --depth 1 https://github.com/woocommerce/woocommerce-admin.git + cd "$WP_CORE_DIR" php wp-cli.phar plugin activate woocommerce - - if [ "$TRAVIS_PULL_REQUEST_BRANCH" != "" ]; then - BRANCH="$(sed 's/#/%23/' <<<$BRANCH)" - # Install woocommerce-admin, the correct branch, if running from Travis CI. - php wp-cli.phar plugin install https://github.com/$REPO/archive/$BRANCH.zip --activate - fi - - # Install WooCommerce-Admin - git clone --depth 1 https://github.com/woocommerce/woocommerce-admin.git - cd "$WP_CORE_DIR" php wp-cli.phar plugin activate woocommerce-admin - if [ "$TRAVIS_PULL_REQUEST_BRANCH" != "" ]; then - BRANCH="$(sed 's/#/%23/' <<<$BRANCH)" - # Install woocommerce-admin, the correct branch, if running from Travis CI. - php wp-cli.phar plugin install https://github.com/$REPO/archive/$BRANCH.zip --activate - fi - # Back to original dir cd "$WORKING_DIR" } From a962e5e361e3967cc3ae932720faa1c1f545049d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 17:37:17 +0100 Subject: [PATCH 071/440] update phpunit code --- unit-tests/bin/phpunit.sh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index ae5e4ef3f8a..87174dc3391 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,8 +1,3 @@ #!/usr/bin/env bash -WORKING_DIR="$PWD" -cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" -phpunit --version -phpunit -c phpunit.xml.dist -TEST_RESULT=$? -cd "$WORKING_DIR" -exit $TEST_RESULT + +$HOME/.composer/vendor/bin/phpunit -c phpunit.xml.dist $@ From 44764de97656f1e1b4f40a40ae9fe0a2757c0d07 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 10 Jun 2019 17:51:31 +0100 Subject: [PATCH 072/440] Update config --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7f85dcd410c..c5344bbe4f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: php -sudo: false +sudo: required matrix: include: @@ -19,9 +19,10 @@ matrix: before_script: - phpenv config-rm xdebug.ini - - export PATH="$HOME/.composer/vendor/bin:$PATH" + - export PATH="$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/vendor/bin:$PATH" - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION - bash unit-tests/bin/travis.sh before + - timedatectl script: - bash unit-tests/bin/phpunit.sh From 6dc3999ff9263d4d5bd85361a18bce29f4c0a0c8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 10:17:12 +0100 Subject: [PATCH 073/440] phpunit.sh --- unit-tests/bin/phpunit.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index 87174dc3391..ae5e4ef3f8a 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,3 +1,8 @@ #!/usr/bin/env bash - -$HOME/.composer/vendor/bin/phpunit -c phpunit.xml.dist $@ +WORKING_DIR="$PWD" +cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" +phpunit --version +phpunit -c phpunit.xml.dist +TEST_RESULT=$? +cd "$WORKING_DIR" +exit $TEST_RESULT From c2e4d5a28ed353a7698046b0c76b7e40759623e3 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 10:31:50 +0100 Subject: [PATCH 074/440] Tweak travis scripts --- .scrutinizer.yml | 29 +++++++++++++++++++++++++++++ .travis.yml | 11 ++--------- unit-tests/bin/install.sh | 5 +++++ unit-tests/bin/travis.sh | 12 ------------ 4 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 .scrutinizer.yml delete mode 100755 unit-tests/bin/travis.sh diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 00000000000..261f5dcc6d9 --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,29 @@ +tools: + php_code_sniffer: + config: + standard: WordPress + sensiolabs_security_checker: true + external_code_coverage: + timeout: 2500 +checks: + php: + avoid_closing_tag: false + avoid_superglobals: false + coding_standard: + name: WordPress + no_exit: false + no_global_keyword: false + one_class_per_file: false + psr2_class_declaration: false + psr2_control_structure_declaration: false + psr2_switch_declaration: false + variable_existence: false + verify_access_scope_valid: false + verify_argument_usable_as_reference: false + verify_property_names: false +filter: + excluded_paths: + - src/RestApi/Version1/ + - src/RestApi/Version2/ + - src/RestApi/Version3/ + - unit-tests/ diff --git a/.travis.yml b/.travis.yml index c5344bbe4f8..2b445c3ded6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: php - +dist: trusty sudo: required matrix: @@ -10,20 +10,13 @@ matrix: - name: "PHP 7.1 unit tests" php: 7.1 env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress - - name: "PHP 7.0 unit tests" - php: 7.0 - env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress - - name: "PHP 5.6 unit tests" - php: 5.6 - env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress before_script: - phpenv config-rm xdebug.ini - export PATH="$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/vendor/bin:$PATH" - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION - - bash unit-tests/bin/travis.sh before - - timedatectl script: + - composer install - bash unit-tests/bin/phpunit.sh - bash unit-tests/bin/phpcs.sh \ No newline at end of file diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh index d5579b4a5f5..d730a3d1b73 100755 --- a/unit-tests/bin/install.sh +++ b/unit-tests/bin/install.sh @@ -186,6 +186,11 @@ install_deps() { php wp-cli.phar plugin activate woocommerce php wp-cli.phar plugin activate woocommerce-admin + if [ "$BRANCH" != "" ]; then + # Install the correct branch of the plugin, if running from Travis CI. + php wp-cli.phar plugin install https://github.com/$REPO/archive/$BRANCH.zip --activate + fi + # Back to original dir cd "$WORKING_DIR" } diff --git a/unit-tests/bin/travis.sh b/unit-tests/bin/travis.sh deleted file mode 100755 index e7b020cc9ac..00000000000 --- a/unit-tests/bin/travis.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -# usage: travis.sh before|after - -if [ $1 == 'before' ]; then - - if [[ ${RUN_PHPCS} == 1 ]]; then - cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" - # This can (currently) only run for PHP 7.1+ - composer install - fi - -fi From 99a09c58102af4efd45ed91259815e7d6f8ac31a Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 10:36:46 +0100 Subject: [PATCH 075/440] Remove woo admin from installer --- unit-tests/bin/install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh index d730a3d1b73..269e4ed91a3 100755 --- a/unit-tests/bin/install.sh +++ b/unit-tests/bin/install.sh @@ -180,11 +180,9 @@ install_deps() { cd "wp-content/plugins/" git clone --depth 1 https://github.com/woocommerce/woocommerce.git - git clone --depth 1 https://github.com/woocommerce/woocommerce-admin.git cd "$WP_CORE_DIR" php wp-cli.phar plugin activate woocommerce - php wp-cli.phar plugin activate woocommerce-admin if [ "$BRANCH" != "" ]; then # Install the correct branch of the plugin, if running from Travis CI. From a344d1fad51cf0769a59eac42de04258f402ee0c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 10:40:24 +0100 Subject: [PATCH 076/440] phpunit --- phpunit.xml.dist => phpunit.xml | 0 unit-tests/bin/phpunit.sh | 8 ++------ 2 files changed, 2 insertions(+), 6 deletions(-) rename phpunit.xml.dist => phpunit.xml (100%) diff --git a/phpunit.xml.dist b/phpunit.xml similarity index 100% rename from phpunit.xml.dist rename to phpunit.xml diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index ae5e4ef3f8a..0ed651b96c7 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,8 +1,4 @@ #!/usr/bin/env bash -WORKING_DIR="$PWD" -cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" + phpunit --version -phpunit -c phpunit.xml.dist -TEST_RESULT=$? -cd "$WORKING_DIR" -exit $TEST_RESULT +phpunit -c phpunit.xml $@ From ceae3979a8aceef495511f03674567072b35cdf9 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 10:44:54 +0100 Subject: [PATCH 077/440] Update dirs --- unit-tests/Bootstrap.php | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index b8de3d6af58..b8a1a83c95d 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -47,7 +47,7 @@ class Bootstrap { * @return string */ public function get_dir() { - return __DIR__; + return dirname( __FILE__ ); } /** @@ -56,7 +56,7 @@ class Bootstrap { * @return boolean */ protected function wc_admin_exists() { - return file_exists( dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php' ); + return file_exists( dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce-admin/woocommerce-admin.php' ); } /** @@ -67,11 +67,11 @@ class Bootstrap { require_once $this->wp_tests_dir . '/includes/functions.php'; \tests_add_filter( 'muplugins_loaded', function() { - require_once dirname( dirname( __DIR__ ) ) . '/woocommerce/woocommerce.php'; - require_once dirname( __DIR__ ) . '/woocommerce-rest-api.php'; + require_once dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce/woocommerce.php'; + require_once dirname( dirname( __FILE__ ) ) . '/woocommerce-rest-api.php'; if ( $this->wc_admin_exists() ) { - require_once dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/woocommerce-admin.php'; + require_once dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce-admin/woocommerce-admin.php'; } } ); @@ -80,13 +80,13 @@ class Bootstrap { define( 'WP_UNINSTALL_PLUGIN', true ); define( 'WC_REMOVE_ALL_DATA', true ); - include dirname( dirname( __DIR__ ) ) . '/woocommerce/uninstall.php'; + include dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce/uninstall.php'; \WC_Install::install(); if ( $this->wc_admin_exists() ) { echo esc_html( 'Installing WooCommerce Admin...' . PHP_EOL ); - require_once dirname( dirname( __DIR__ ) ) . '/woocommerce-admin/includes/class-wc-admin-install.php'; + require_once dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce-admin/includes/class-wc-admin-install.php'; \WC_Admin_Install::create_tables(); \WC_Admin_Install::create_events(); } @@ -110,16 +110,16 @@ class Bootstrap { require_once $this->wc_tests_dir . '/framework/class-wc-unit-test-case.php'; require_once $this->wc_tests_dir . '/framework/class-wc-rest-unit-test-case.php'; - require_once __DIR__ . '/Helpers/AdminNotesHelper.php'; - require_once __DIR__ . '/Helpers/CouponHelper.php'; - require_once __DIR__ . '/Helpers/CustomerHelper.php'; - require_once __DIR__ . '/Helpers/OrderHelper.php'; - require_once __DIR__ . '/Helpers/ProductHelper.php'; - require_once __DIR__ . '/Helpers/ShippingHelper.php'; - require_once __DIR__ . '/Helpers/SettingsHelper.php'; - require_once __DIR__ . '/Helpers/QueueHelper.php'; - require_once __DIR__ . '/AbstractRestApiTest.php'; - require_once __DIR__ . '/AbstractReportsTest.php'; + require_once dirname( __FILE__ ) . '/Helpers/AdminNotesHelper.php'; + require_once dirname( __FILE__ ) . '/Helpers/CouponHelper.php'; + require_once dirname( __FILE__ ) . '/Helpers/CustomerHelper.php'; + require_once dirname( __FILE__ ) . '/Helpers/OrderHelper.php'; + require_once dirname( __FILE__ ) . '/Helpers/ProductHelper.php'; + require_once dirname( __FILE__ ) . '/Helpers/ShippingHelper.php'; + require_once dirname( __FILE__ ) . '/Helpers/SettingsHelper.php'; + require_once dirname( __FILE__ ) . '/Helpers/QueueHelper.php'; + require_once dirname( __FILE__ ) . '/AbstractRestApiTest.php'; + require_once dirname( __FILE__ ) . '/AbstractReportsTest.php'; } } From 0753e3f6a8184dd3afb14aacaa967fb04c73d5f8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 10:50:13 +0100 Subject: [PATCH 078/440] More config changes --- unit-tests/bin/phpcs.sh | 1 + unit-tests/bin/phpunit.sh | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/unit-tests/bin/phpcs.sh b/unit-tests/bin/phpcs.sh index 5a2c8b48a05..dc51767a2c6 100755 --- a/unit-tests/bin/phpcs.sh +++ b/unit-tests/bin/phpcs.sh @@ -6,6 +6,7 @@ if [[ ${RUN_PHPCS} == 1 ]]; then if [ "$CHANGED_FILES" != "" ]; then echo "Running Code Sniffer." + cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" ./vendor/bin/phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES fi fi diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index 0ed651b96c7..e336038ff4a 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,4 +1,8 @@ #!/usr/bin/env bash - +WORKING_DIR="$PWD" +cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" phpunit --version -phpunit -c phpunit.xml $@ +phpunit -c phpunit.xml +TEST_RESULT=$? +cd "$WORKING_DIR" +exit $TEST_RESULT \ No newline at end of file From fa8ebdc47fcbe8bcf44432730d3195911034be6f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 10:53:58 +0100 Subject: [PATCH 079/440] Update phpunit dir --- unit-tests/bin/phpunit.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index e336038ff4a..2c3341c1005 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash WORKING_DIR="$PWD" cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" -phpunit --version -phpunit -c phpunit.xml +./vendor/bin/phpunit --version +./vendor/bin/phpunit -c phpunit.xml TEST_RESULT=$? cd "$WORKING_DIR" exit $TEST_RESULT \ No newline at end of file From 73e5c5d95162dd7cd31d759c6ab3db1a09228f19 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 10:58:00 +0100 Subject: [PATCH 080/440] pwd --- unit-tests/bin/phpunit.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index 2c3341c1005..771a67e7287 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash WORKING_DIR="$PWD" cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" +pwd ./vendor/bin/phpunit --version ./vendor/bin/phpunit -c phpunit.xml TEST_RESULT=$? From 759feffbee282995a4d6b4da3aa955ce73fcf477 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:05:53 +0100 Subject: [PATCH 081/440] which phpunit --- .travis.yml | 2 +- unit-tests/bin/phpcs.sh | 3 +-- unit-tests/bin/phpunit.sh | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2b445c3ded6..6730b3d7db6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,10 +13,10 @@ matrix: before_script: - phpenv config-rm xdebug.ini - - export PATH="$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/vendor/bin:$PATH" - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION script: - composer install + - export PATH="$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/vendor/bin:$PATH" - bash unit-tests/bin/phpunit.sh - bash unit-tests/bin/phpcs.sh \ No newline at end of file diff --git a/unit-tests/bin/phpcs.sh b/unit-tests/bin/phpcs.sh index dc51767a2c6..b66495f557e 100755 --- a/unit-tests/bin/phpcs.sh +++ b/unit-tests/bin/phpcs.sh @@ -6,7 +6,6 @@ if [[ ${RUN_PHPCS} == 1 ]]; then if [ "$CHANGED_FILES" != "" ]; then echo "Running Code Sniffer." - cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" - ./vendor/bin/phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES + phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES fi fi diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index 771a67e7287..be8fe8761b5 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash WORKING_DIR="$PWD" cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" -pwd -./vendor/bin/phpunit --version -./vendor/bin/phpunit -c phpunit.xml +which phpunit +phpunit --version +phpunit -c phpunit.xml TEST_RESULT=$? cd "$WORKING_DIR" exit $TEST_RESULT \ No newline at end of file From 561e44432ad5f83bc33aad8f86aa700249523d20 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:10:55 +0100 Subject: [PATCH 082/440] Add caching --- .travis.yml | 6 ++++-- unit-tests/bin/phpunit.sh | 7 +++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6730b3d7db6..809086ff8f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,10 @@ language: php dist: trusty sudo: required - +cache: + directories: + - vendor + - $HOME/.composer/cache matrix: include: - name: "PHP 7.2 unit tests, PHP Coding standards check" @@ -17,6 +20,5 @@ before_script: script: - composer install - - export PATH="$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/vendor/bin:$PATH" - bash unit-tests/bin/phpunit.sh - bash unit-tests/bin/phpcs.sh \ No newline at end of file diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index be8fe8761b5..5e3d054f19c 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,9 +1,8 @@ #!/usr/bin/env bash WORKING_DIR="$PWD" -cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api/" -which phpunit -phpunit --version -phpunit -c phpunit.xml +cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api" +./vendor/bin/phpunit --version +./vendor/bin/phpunit -c phpunit.xml TEST_RESULT=$? cd "$WORKING_DIR" exit $TEST_RESULT \ No newline at end of file From 129ea30305302a71c07a80703e8b8b656c37ca72 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:16:23 +0100 Subject: [PATCH 083/440] Move composer install --- .travis.yml | 1 - unit-tests/bin/phpunit.sh | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 809086ff8f2..a332008106b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,5 @@ before_script: - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION script: - - composer install - bash unit-tests/bin/phpunit.sh - bash unit-tests/bin/phpcs.sh \ No newline at end of file diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index 5e3d054f19c..c21ff9e0740 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash WORKING_DIR="$PWD" cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api" +composer install ./vendor/bin/phpunit --version ./vendor/bin/phpunit -c phpunit.xml TEST_RESULT=$? From 6d211e17bfa92a6392d0b8d979afab08553aebc8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:18:59 +0100 Subject: [PATCH 084/440] ls --- unit-tests/bin/phpunit.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index c21ff9e0740..bbcf6b6d7f8 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash WORKING_DIR="$PWD" cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api" +ls composer install ./vendor/bin/phpunit --version ./vendor/bin/phpunit -c phpunit.xml From 52dc671ea81109e874cfead2884ac818a829ce5e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:24:52 +0100 Subject: [PATCH 085/440] try travis build dir --- .travis.yml | 1 + unit-tests/bin/phpunit.sh | 11 ++--------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index a332008106b..809086ff8f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,5 +19,6 @@ before_script: - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION script: + - composer install - bash unit-tests/bin/phpunit.sh - bash unit-tests/bin/phpcs.sh \ No newline at end of file diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index bbcf6b6d7f8..773d188c61a 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,10 +1,3 @@ #!/usr/bin/env bash -WORKING_DIR="$PWD" -cd "$WP_CORE_DIR/wp-content/plugins/woocommerce-rest-api" -ls -composer install -./vendor/bin/phpunit --version -./vendor/bin/phpunit -c phpunit.xml -TEST_RESULT=$? -cd "$WORKING_DIR" -exit $TEST_RESULT \ No newline at end of file +"$TRAVIS_BUILD_DIR"/vendor/bin/phpunit --version +"$TRAVIS_BUILD_DIR"/vendor/bin/phpunit -c phpunit.xml $@ \ No newline at end of file From 652e622aa84c312d439783b4085835b9ba44c0a6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:37:09 +0100 Subject: [PATCH 086/440] Config --- .travis.yml | 3 ++- composer.json | 3 ++- unit-tests/bin/phpcs.sh | 2 +- unit-tests/bin/phpunit.sh | 3 +-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 809086ff8f2..04246378dee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,10 @@ matrix: before_script: - phpenv config-rm xdebug.ini + - composer install + - export PATH="$HOME/.composer/vendor/bin:$PATH" - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION script: - - composer install - bash unit-tests/bin/phpunit.sh - bash unit-tests/bin/phpcs.sh \ No newline at end of file diff --git a/composer.json b/composer.json index 8eef292cb10..3185cd520c3 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "composer/installers" : "~1.0" }, "require-dev": { - "phpunit/phpunit": "6.5.14" + "phpunit/phpunit": "6.5.14", + "woocommerce/woocommerce-sniffs": "0.0.6" }, "autoload": { "classmap": ["src"] diff --git a/unit-tests/bin/phpcs.sh b/unit-tests/bin/phpcs.sh index b66495f557e..5a2c8b48a05 100755 --- a/unit-tests/bin/phpcs.sh +++ b/unit-tests/bin/phpcs.sh @@ -6,6 +6,6 @@ if [[ ${RUN_PHPCS} == 1 ]]; then if [ "$CHANGED_FILES" != "" ]; then echo "Running Code Sniffer." - phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES + ./vendor/bin/phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES fi fi diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh index 773d188c61a..12e95676881 100755 --- a/unit-tests/bin/phpunit.sh +++ b/unit-tests/bin/phpunit.sh @@ -1,3 +1,2 @@ #!/usr/bin/env bash -"$TRAVIS_BUILD_DIR"/vendor/bin/phpunit --version -"$TRAVIS_BUILD_DIR"/vendor/bin/phpunit -c phpunit.xml $@ \ No newline at end of file +$HOME/.composer/vendor/bin/phpunit -c phpunit.xml $@ \ No newline at end of file From a50dad20fa0381696bc5fbf58584fd82e563f58c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:41:21 +0100 Subject: [PATCH 087/440] config --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 04246378dee..ecc05440f0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,11 @@ matrix: env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress before_script: + - export PATH="$HOME/.composer/vendor/bin:$PATH" - phpenv config-rm xdebug.ini - composer install - - export PATH="$HOME/.composer/vendor/bin:$PATH" + - composer global require "phpunit/phpunit=4.8.*|6.5.*" + - composer require woocommerce/woocommerce-sniffs - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION script: From 584d46989ff67ef83123a7fdb9c20299d4ece8fc Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:57:20 +0100 Subject: [PATCH 088/440] Tweak bootstrap paths --- unit-tests/Bootstrap.php | 65 ++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index b8a1a83c95d..a533f69b181 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -21,22 +21,43 @@ class Bootstrap { protected $wp_tests_dir; /** - * Directory path to woocommerce core tests. + * unit-tests directory. + * + * @var string + */ + protected $tests_dir; + + /** + * WC Core unit-tests directory. * * @var string */ protected $wc_tests_dir; + + /** + * This plugin directory. + * + * @var string + */ + protected $plugin_dir; + + /** + * Plugins directory. + * + * @var string + */ + protected $plugins_dir; + /** * Init unit testing library. */ public function init() { - $this->wc_tests_dir = dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce/tests'; + $this->tests_dir = dirname( __FILE__ ); + $this->plugin_dir = dirname( $this->tests_dir ); + $this->plugins_dir = dirname( $this->plugin_dir ); + $this->wc_tests_dir = $this->plugins_dir . '/woocommerce/tests'; $this->wp_tests_dir = getenv( 'WP_TESTS_DIR' ); - if ( ! $this->wp_tests_dir ) { - $this->wp_tests_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; - } - $this->setup_hooks(); $this->load_framework(); } @@ -56,7 +77,7 @@ class Bootstrap { * @return boolean */ protected function wc_admin_exists() { - return file_exists( dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce-admin/woocommerce-admin.php' ); + return file_exists( $this->plugins_dir . '/woocommerce-admin/woocommerce-admin.php' ); } /** @@ -67,11 +88,11 @@ class Bootstrap { require_once $this->wp_tests_dir . '/includes/functions.php'; \tests_add_filter( 'muplugins_loaded', function() { - require_once dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce/woocommerce.php'; - require_once dirname( dirname( __FILE__ ) ) . '/woocommerce-rest-api.php'; + require_once $this->plugins_dir . '/woocommerce/woocommerce.php'; + require_once $this->plugin_dir . '/woocommerce-rest-api.php'; if ( $this->wc_admin_exists() ) { - require_once dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce-admin/woocommerce-admin.php'; + require_once $this->plugins_dir . '/woocommerce-admin/woocommerce-admin.php'; } } ); @@ -80,13 +101,13 @@ class Bootstrap { define( 'WP_UNINSTALL_PLUGIN', true ); define( 'WC_REMOVE_ALL_DATA', true ); - include dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce/uninstall.php'; + include $this->plugins_dir . '/woocommerce/uninstall.php'; \WC_Install::install(); if ( $this->wc_admin_exists() ) { echo esc_html( 'Installing WooCommerce Admin...' . PHP_EOL ); - require_once dirname( dirname( dirname( __FILE__ ) ) ) . '/woocommerce-admin/includes/class-wc-admin-install.php'; + require_once $this->plugins_dir . '/woocommerce-admin/includes/class-wc-admin-install.php'; \WC_Admin_Install::create_tables(); \WC_Admin_Install::create_events(); } @@ -110,16 +131,16 @@ class Bootstrap { require_once $this->wc_tests_dir . '/framework/class-wc-unit-test-case.php'; require_once $this->wc_tests_dir . '/framework/class-wc-rest-unit-test-case.php'; - require_once dirname( __FILE__ ) . '/Helpers/AdminNotesHelper.php'; - require_once dirname( __FILE__ ) . '/Helpers/CouponHelper.php'; - require_once dirname( __FILE__ ) . '/Helpers/CustomerHelper.php'; - require_once dirname( __FILE__ ) . '/Helpers/OrderHelper.php'; - require_once dirname( __FILE__ ) . '/Helpers/ProductHelper.php'; - require_once dirname( __FILE__ ) . '/Helpers/ShippingHelper.php'; - require_once dirname( __FILE__ ) . '/Helpers/SettingsHelper.php'; - require_once dirname( __FILE__ ) . '/Helpers/QueueHelper.php'; - require_once dirname( __FILE__ ) . '/AbstractRestApiTest.php'; - require_once dirname( __FILE__ ) . '/AbstractReportsTest.php'; + require_once $this->tests_dir . '/Helpers/AdminNotesHelper.php'; + require_once $this->tests_dir . '/Helpers/CouponHelper.php'; + require_once $this->tests_dir . '/Helpers/CustomerHelper.php'; + require_once $this->tests_dir . '/Helpers/OrderHelper.php'; + require_once $this->tests_dir . '/Helpers/ProductHelper.php'; + require_once $this->tests_dir . '/Helpers/ShippingHelper.php'; + require_once $this->tests_dir . '/Helpers/SettingsHelper.php'; + require_once $this->tests_dir . '/Helpers/QueueHelper.php'; + require_once $this->tests_dir . '/AbstractRestApiTest.php'; + require_once $this->tests_dir . '/AbstractReportsTest.php'; } } From e939c870ce17eade0058ce6b63cc41d7a2071fd1 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 11:59:49 +0100 Subject: [PATCH 089/440] WP_TESTS_DIR --- unit-tests/Bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index a533f69b181..e5ce59a1ba3 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -56,7 +56,7 @@ class Bootstrap { $this->plugin_dir = dirname( $this->tests_dir ); $this->plugins_dir = dirname( $this->plugin_dir ); $this->wc_tests_dir = $this->plugins_dir . '/woocommerce/tests'; - $this->wp_tests_dir = getenv( 'WP_TESTS_DIR' ); + $this->wp_tests_dir = getenv( 'WP_TESTS_DIR' ) ? getenv( 'WP_TESTS_DIR' ) : rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; $this->setup_hooks(); $this->load_framework(); From d50e2426df73f414db5025bc2638ac5fc9f8d36b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 12:08:56 +0100 Subject: [PATCH 090/440] plugins_dir --- unit-tests/Bootstrap.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index e5ce59a1ba3..b8a4db86af9 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -52,11 +52,19 @@ class Bootstrap { * Init unit testing library. */ public function init() { + $this->wp_tests_dir = getenv( 'WP_TESTS_DIR' ) ? getenv( 'WP_TESTS_DIR' ) : rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; $this->tests_dir = dirname( __FILE__ ); $this->plugin_dir = dirname( $this->tests_dir ); - $this->plugins_dir = dirname( $this->plugin_dir ); + + if ( file_exists( dirname( $this->plugin_dir ) . '/woocommerce/woocommerce.php' ) ) { + // From plugin directory. + $this->plugins_dir = dirname( $this->plugin_dir ); + } else { + // Travis. + $this->plugins_dir = getenv( 'WP_CORE_DIR' ) . 'wp-content/plugins'; + } + $this->wc_tests_dir = $this->plugins_dir . '/woocommerce/tests'; - $this->wp_tests_dir = getenv( 'WP_TESTS_DIR' ) ? getenv( 'WP_TESTS_DIR' ) : rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; $this->setup_hooks(); $this->load_framework(); From 411054fb5f09508fafc79c5d4a1b2d60d91ac903 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 12:10:53 +0100 Subject: [PATCH 091/440] Missing slash --- unit-tests/Bootstrap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index b8a4db86af9..bab9057189e 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -55,13 +55,13 @@ class Bootstrap { $this->wp_tests_dir = getenv( 'WP_TESTS_DIR' ) ? getenv( 'WP_TESTS_DIR' ) : rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; $this->tests_dir = dirname( __FILE__ ); $this->plugin_dir = dirname( $this->tests_dir ); - + if ( file_exists( dirname( $this->plugin_dir ) . '/woocommerce/woocommerce.php' ) ) { // From plugin directory. $this->plugins_dir = dirname( $this->plugin_dir ); } else { // Travis. - $this->plugins_dir = getenv( 'WP_CORE_DIR' ) . 'wp-content/plugins'; + $this->plugins_dir = getenv( 'WP_CORE_DIR' ) . '/wp-content/plugins'; } $this->wc_tests_dir = $this->plugins_dir . '/woocommerce/tests'; From 013934d8b797d558ae74ca2440ba2b8dab2efc10 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 16:15:02 +0100 Subject: [PATCH 092/440] Remove all blocks APIs --- .../class-wc-rest-blocks-controllers.php | 27 -- ...cks-product-attribute-terms-controller.php | 185 --------- ...t-blocks-product-attributes-controller.php | 188 --------- ...t-blocks-product-categories-controller.php | 151 ------- ...ass-wc-rest-blocks-products-controller.php | 390 ------------------ .../Tests/Blocks/ProductAttributeTerms.php | 113 ----- unit-tests/Tests/Blocks/ProductAttributes.php | 113 ----- unit-tests/Tests/Blocks/ProductCategories.php | 129 ------ unit-tests/Tests/Blocks/products.php | 313 -------------- 9 files changed, 1609 deletions(-) delete mode 100644 src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php delete mode 100644 src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php delete mode 100644 src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php delete mode 100644 src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php delete mode 100644 src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php delete mode 100644 unit-tests/Tests/Blocks/ProductAttributeTerms.php delete mode 100644 unit-tests/Tests/Blocks/ProductAttributes.php delete mode 100644 unit-tests/Tests/Blocks/ProductCategories.php delete mode 100644 unit-tests/Tests/Blocks/products.php diff --git a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php deleted file mode 100644 index 3d59789c143..00000000000 --- a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-controllers.php +++ /dev/null @@ -1,27 +0,0 @@ - 'WC_REST_Blocks_Product_Attributes_Controller', - 'product-attribute-terms' => 'WC_REST_Blocks_Product_Attribute_Terms_Controller', - 'product-categories' => 'WC_REST_Blocks_Product_Categories_Controller', - 'products' => 'WC_REST_Blocks_Products_Controller', - ]; - } -} diff --git a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php deleted file mode 100644 index bd42104463f..00000000000 --- a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attribute-terms-controller.php +++ /dev/null @@ -1,185 +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 identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check permissions. - * - * @param WP_REST_Request $request Full details about the request. - * @param string $context Request context. - * @return bool|WP_Error - */ - protected function check_permissions( $request, $context = 'read' ) { - // Get taxonomy. - $taxonomy = $this->get_taxonomy( $request ); - if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - // Check permissions for a single term. - $id = intval( $request['id'] ); - if ( $id ) { - $term = get_term( $id, $taxonomy ); - - if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { - return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - } - - return current_user_can( 'edit_posts' ); - } - - /** - * Prepare a single product category output for response. - * - * @param WP_Term $item Term object. - * @param WP_REST_Request $request Request instance. - * @return WP_REST_Response - */ - public function prepare_item_for_response( $item, $request ) { - // Get the attribute slug. - $attribute_id = absint( $request->get_param( 'attribute_id' ) ); - $attribute = wc_get_attribute( $attribute_id ); - - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'count' => (int) $item->count, - 'attribute' => array( - 'id' => $attribute->id, - 'name' => $attribute->name, - 'slug' => $attribute->slug, - ), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - return $response; - } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $raw_schema = parent::get_item_schema(); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_attribute_term', - 'type' => 'object', - 'properties' => array(), - ); - - $schema['properties']['id'] = $raw_schema['properties']['id']; - $schema['properties']['name'] = $raw_schema['properties']['name']; - $schema['properties']['slug'] = $raw_schema['properties']['slug']; - $schema['properties']['count'] = $raw_schema['properties']['count']; - $schema['properties']['attribute'] = array( - 'description' => __( 'Attribute.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Attribute slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php deleted file mode 100644 index 93e2dbdd864..00000000000 --- a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-attributes-controller.php +++ /dev/null @@ -1,188 +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 identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check if a given request has access to read the attributes. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! current_user_can( 'edit_posts' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** - * Check if a given request has access to read a attribute. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - - if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - if ( ! current_user_can( 'edit_posts' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check permissions. - * - * @param WP_REST_Request $request Full details about the request. - * @param string $context Request context. - * @return bool|WP_Error - */ - protected function check_permissions( $request, $context = 'read' ) { - // Get taxonomy. - $taxonomy = $this->get_taxonomy( $request ); - if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - // Check permissions for a single term. - $id = intval( $request['id'] ); - if ( $id ) { - $term = get_term( $id, $taxonomy ); - - if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { - return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - } - - return current_user_can( 'edit_posts' ); - } - - /** - * Prepare a single product category output for response. - * - * @param WP_Term $item Term object. - * @param WP_REST_Request $request Request instance. - * @return WP_REST_Response - */ - public function prepare_item_for_response( $item, $request ) { - $taxonomy = wc_attribute_taxonomy_name( $item->attribute_name ); - $data = array( - 'id' => (int) $item->attribute_id, - 'name' => $item->attribute_label, - 'slug' => $taxonomy, - 'count' => wp_count_terms( $taxonomy ), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); - $response->add_links( $this->prepare_links( $item ) ); - - return $response; - } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $raw_schema = parent::get_item_schema(); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_block_attribute', - 'type' => 'object', - 'properties' => array(), - ); - - $schema['properties']['id'] = $raw_schema['properties']['id']; - $schema['properties']['name'] = $raw_schema['properties']['name']; - $schema['properties']['slug'] = $raw_schema['properties']['slug']; - $schema['properties']['count'] = array( - 'description' => __( 'Number of terms in the attribute taxonomy.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php deleted file mode 100644 index 512af96a560..00000000000 --- a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-product-categories-controller.php +++ /dev/null @@ -1,151 +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 identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check permissions. - * - * @param WP_REST_Request $request Full details about the request. - * @param string $context Request context. - * @return bool|WP_Error - */ - protected function check_permissions( $request, $context = 'read' ) { - // Get taxonomy. - $taxonomy = $this->get_taxonomy( $request ); - if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - // Check permissions for a single term. - $id = intval( $request['id'] ); - if ( $id ) { - $term = get_term( $id, $taxonomy ); - - if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { - return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - } - - return current_user_can( 'edit_posts' ); - } - - /** - * Prepare a single product category output for response. - * - * @param WP_Term $item Term object. - * @param WP_REST_Request $request Request instance. - * @return WP_REST_Response - */ - public function prepare_item_for_response( $item, $request ) { - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'parent' => (int) $item->parent, - 'count' => (int) $item->count, - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); - $response->add_links( $this->prepare_links( $item, $request ) ); - - return $response; - } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $raw_schema = parent::get_item_schema(); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_block_category', - 'type' => 'object', - 'properties' => array(), - ); - - $schema['properties']['id'] = $raw_schema['properties']['id']; - $schema['properties']['name'] = $raw_schema['properties']['name']; - $schema['properties']['slug'] = $raw_schema['properties']['slug']; - $schema['properties']['parent'] = $raw_schema['properties']['parent']; - $schema['properties']['count'] = $raw_schema['properties']['count']; - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php b/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php deleted file mode 100644 index 9cb951cd9fa..00000000000 --- a/src/RestApi/Blocks/Version1/class-wc-rest-blocks-products-controller.php +++ /dev/null @@ -1,390 +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 identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check if a given request has access to read items. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! current_user_can( 'edit_posts' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - if ( ! current_user_can( 'edit_posts' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get a collection of posts. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $query_args = $this->prepare_objects_query( $request ); - $query_results = $this->get_objects( $query_args ); - - $objects = array(); - foreach ( $query_results['objects'] as $object ) { - $data = $this->prepare_object_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 ); - $response->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); - - $base = $this->rest_base; - $attrib_prefix = '(?P<'; - if ( strpos( $base, $attrib_prefix ) !== false ) { - $attrib_names = array(); - preg_match( '/\(\?P<[^>]+>.*\)/', $base, $attrib_names, PREG_OFFSET_CAPTURE ); - foreach ( $attrib_names as $attrib_name_match ) { - $beginning_offset = strlen( $attrib_prefix ); - $attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] ); - $attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset ); - if ( isset( $request[ $attrib_name ] ) ) { - $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); - } - } - } - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $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; - } - - /** - * Get the images for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * @return array - */ - protected function get_images( $product ) { - $images = array(); - $attachment_ids = array(); - - // Add featured image. - if ( has_post_thumbnail( $product->get_id() ) ) { - $attachment_ids[] = $product->get_image_id(); - } - - // Add gallery images. - $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); - - // Build image data. - foreach ( $attachment_ids as $attachment_id ) { - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - continue; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - continue; - } - - $images[] = array( - 'id' => (int) $attachment_id, - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - - return $images; - } - - /** - * Prepare a single product output for response. - * - * @deprecated 3.0.0 - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_item_for_response( $post, $request ) { - $product = wc_get_product( $post ); - $data = $this->get_product_data( $product ); - - $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->header( 'X-Woo-Notice', __( 'Private REST API for use by block editor only.', 'woocommerce' ) ); - $response->add_links( $this->prepare_links( $product, $request ) ); - - return $response; - } - - /** - * Make extra product orderby features supported by WooCommerce available to the WC API. - * This includes 'price', 'popularity', and 'rating'. - * - * @param WP_REST_Request $request Request data. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - $operator_mapping = array( - 'in' => 'IN', - 'not_in' => 'NOT IN', - 'and' => 'AND', - ); - - $orderby = $request->get_param( 'orderby' ); - $order = $request->get_param( 'order' ); - $category_operator = $operator_mapping[ $request->get_param( 'category_operator' ) ]; - $attribute_operator = $operator_mapping[ $request->get_param( 'attribute_operator' ) ]; - $catalog_visibility = $request->get_param( 'catalog_visibility' ); - - $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); - $args['orderby'] = $ordering_args['orderby']; - $args['order'] = $ordering_args['order']; - if ( $ordering_args['meta_key'] ) { - $args['meta_key'] = $ordering_args['meta_key']; // WPCS: slow query ok. - } - - if ( $category_operator && isset( $args['tax_query'] ) ) { - foreach ( $args['tax_query'] as $i => $tax_query ) { - if ( 'product_cat' === $tax_query['taxonomy'] ) { - $args['tax_query'][ $i ]['operator'] = $category_operator; - $args['tax_query'][ $i ]['include_children'] = 'AND' === $category_operator ? false : true; - } - } - } - - if ( $attribute_operator && isset( $args['tax_query'] ) ) { - foreach ( $args['tax_query'] as $i => $tax_query ) { - if ( in_array( $tax_query['taxonomy'], wc_get_attribute_taxonomy_names(), true ) ) { - $args['tax_query'][ $i ]['operator'] = $attribute_operator; - } - } - } - - if ( in_array( $catalog_visibility, array_keys( wc_get_product_visibility_options() ), true ) ) { - $exclude_from_catalog = 'search' === $catalog_visibility ? '' : 'exclude-from-catalog'; - $exclude_from_search = 'catalog' === $catalog_visibility ? '' : 'exclude-from-search'; - - $args['tax_query'][] = array( - 'taxonomy' => 'product_visibility', - 'field' => 'name', - 'terms' => array( $exclude_from_catalog, $exclude_from_search ), - 'operator' => 'hidden' === $catalog_visibility ? 'AND' : 'NOT IN', - ); - } - - return $args; - } - - /** - * Get product data. - * - * @param WC_Product $product Product instance. - * @param string $context Request context. - * Options: 'view' and 'edit'. - * @return array - */ - protected function get_product_data( $product, $context = 'view' ) { - $raw_data = parent::get_product_data( $product, $context ); - $data = array(); - - $data['id'] = $raw_data['id']; - $data['name'] = $raw_data['name']; - $data['permalink'] = $raw_data['permalink']; - $data['sku'] = $raw_data['sku']; - $data['description'] = $raw_data['description']; - $data['short_description'] = $raw_data['short_description']; - $data['price'] = $raw_data['price']; - $data['price_html'] = $raw_data['price_html']; - $data['images'] = $raw_data['images']; - $data['average_rating'] = $raw_data['average_rating']; - - return $data; - } - - /** - * Update the collection params. - * - * Adds new options for 'orderby', and new parameters 'category_operator', 'attribute_operator'. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating', 'menu_order' ) ); - $params['category_operator'] = array( - 'description' => __( 'Operator to compare product category terms.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( 'in', 'not_in', 'and' ), - 'default' => 'in', - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['attribute_operator'] = array( - 'description' => __( 'Operator to compare product attribute terms.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( 'in', 'not_in', 'and' ), - 'default' => 'in', - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['catalog_visibility'] = array( - 'description' => __( 'Determines if hidden or visible catalog products are shown.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $raw_schema = parent::get_item_schema(); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_block_product', - 'type' => 'object', - 'properties' => array(), - ); - - $schema['properties']['id'] = $raw_schema['properties']['id']; - $schema['properties']['name'] = $raw_schema['properties']['name']; - $schema['properties']['permalink'] = $raw_schema['properties']['permalink']; - $schema['properties']['sku'] = $raw_schema['properties']['sku']; - $schema['properties']['description'] = $raw_schema['properties']['description']; - $schema['properties']['short_description'] = $raw_schema['properties']['short_description']; - $schema['properties']['price'] = $raw_schema['properties']['price']; - $schema['properties']['price_html'] = $raw_schema['properties']['price_html']; - $schema['properties']['average_rating'] = $raw_schema['properties']['average_rating']; - $schema['properties']['images'] = array( - 'description' => $raw_schema['properties']['images']['description'], - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array(), - ), - ); - - $images_schema = $raw_schema['properties']['images']['items']['properties']; - - $schema['properties']['images']['items']['properties']['id'] = $images_schema['id']; - $schema['properties']['images']['items']['properties']['src'] = $images_schema['src']; - $schema['properties']['images']['items']['properties']['name'] = $images_schema['name']; - $schema['properties']['images']['items']['properties']['alt'] = $images_schema['alt']; - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/unit-tests/Tests/Blocks/ProductAttributeTerms.php b/unit-tests/Tests/Blocks/ProductAttributeTerms.php deleted file mode 100644 index 4febcaf1a72..00000000000 --- a/unit-tests/Tests/Blocks/ProductAttributeTerms.php +++ /dev/null @@ -1,113 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - - $this->contributor = $this->factory->user->create( - array( - 'role' => 'contributor', - ) - ); - - // Create 2 product attributes with terms. - $this->attr_color = ProductHelper::create_attribute( 'color', array( 'red', 'yellow', 'blue' ) ); - $this->attr_size = ProductHelper::create_attribute( 'size', array( 'small', 'medium', 'large', 'xlarge' ) ); - } - - /** - * Test getting attribute terms. - * - * @since 3.6.0 - */ - public function test_get_terms() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_color['attribute_id'] . '/terms' ); - - $response = $this->server->dispatch( $request ); - $response_terms = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 3, count( $response_terms ) ); - $term = $response_terms[0]; - $this->assertArrayHasKey( 'attribute', $term ); - $attribute = $term['attribute']; - $this->assertArrayHasKey( 'id', $attribute ); - $this->assertArrayHasKey( 'name', $attribute ); - $this->assertArrayHasKey( 'slug', $attribute ); - } - - /** - * Test getting invalid attribute terms. - * - * @since 3.6.0 - */ - public function test_get_invalid_attribute_terms() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/99999/terms' ); - - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test un-authorized getting attribute terms. - * - * @since 3.6.0 - */ - public function test_get_unauthed_attribute_terms() { - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_size['attribute_id'] . '/terms' ); - - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting attribute terms as contributor. - * - * @since 3.6.0 - */ - public function test_get_attribute_terms_contributor() { - wp_set_current_user( $this->contributor ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_size['attribute_id'] . '/terms' ); - - $response = $this->server->dispatch( $request ); - $response_terms = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 4, count( $response_terms ) ); - } -} diff --git a/unit-tests/Tests/Blocks/ProductAttributes.php b/unit-tests/Tests/Blocks/ProductAttributes.php deleted file mode 100644 index 6389a097f96..00000000000 --- a/unit-tests/Tests/Blocks/ProductAttributes.php +++ /dev/null @@ -1,113 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - - $this->contributor = $this->factory->user->create( - array( - 'role' => 'contributor', - ) - ); - - // Create 2 product attributes with terms. - $this->attr_color = ProductHelper::create_attribute( 'color', array( 'red', 'yellow', 'blue' ) ); - $this->attr_size = ProductHelper::create_attribute( 'size', array( 'small', 'medium', 'large', 'xlarge' ) ); - } - - /** - * Test getting attributes. - * - * @since 3.6.0 - */ - public function test_get_attributes() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes' ); - - $response = $this->server->dispatch( $request ); - $response_attributes = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $response_attributes ) ); - $attribute = $response_attributes[0]; - $this->assertArrayHasKey( 'id', $attribute ); - $this->assertArrayHasKey( 'name', $attribute ); - $this->assertArrayHasKey( 'slug', $attribute ); - $this->assertArrayHasKey( 'count', $attribute ); - } - - /** - * Test getting invalid attribute. - * - * @since 3.6.0 - */ - public function test_get_invalid_attribute() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/11111' ); - - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test un-authorized getting attribute. - * - * @since 3.6.0 - */ - public function test_get_unauthed_attribute() { - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_size['attribute_id'] ); - - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting attribute as contributor. - * - * @since 3.6.0 - */ - public function test_get_attribute_contributor() { - wp_set_current_user( $this->contributor ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/attributes/' . $this->attr_size['attribute_id'] ); - - $response = $this->server->dispatch( $request ); - $attribute = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $this->attr_size['attribute_id'], $attribute['id'] ); - $this->assertEquals( $this->attr_size['attribute_name'], $attribute['name'] ); - } -} diff --git a/unit-tests/Tests/Blocks/ProductCategories.php b/unit-tests/Tests/Blocks/ProductCategories.php deleted file mode 100644 index c143942e196..00000000000 --- a/unit-tests/Tests/Blocks/ProductCategories.php +++ /dev/null @@ -1,129 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - - $this->contributor = $this->factory->user->create( - array( - 'role' => 'contributor', - ) - ); - - // Create 3 product categories. - $parent = wp_insert_term( 'Parent Category', 'product_cat' ); - $child = wp_insert_term( - 'Child Category', - 'product_cat', - array( 'parent' => $parent['term_id'] ) - ); - $single = wp_insert_term( 'Standalone Category', 'product_cat' ); - $this->categories = array( - 'parent' => $parent, - 'child' => $child, - 'single' => $single, - ); - - // Create two products for the parent category. - $this->products = array(); - $this->products[0] = ProductHelper::create_simple_product( false ); - $this->products[0]->set_category_ids( array( $parent['term_id'] ) ); - $this->products[0]->save(); - - $this->products[3] = ProductHelper::create_simple_product( false ); - $this->products[3]->set_category_ids( array( $parent['term_id'], $single['term_id'] ) ); - $this->products[3]->save(); - } - - /** - * Test getting product categories. - * - * @since 3.6.0 - */ - public function test_get_product_categories() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/categories' ); - - $response = $this->server->dispatch( $request ); - $categories = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 4, count( $categories ) ); // Three created and `uncategorized`. - } - - /** - * Test getting invalid product category. - * - * @since 3.6.0 - */ - public function test_get_invalid_product_category() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/categories/007' ); - - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test un-authorized getting product category. - * - * @since 3.6.0 - */ - public function test_get_unauthed_product_category() { - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/categories/' . $this->categories['parent']['term_id'] ); - - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting category as contributor. - * - * @since 3.6.0 - */ - public function test_get_attribute_terms_contributor() { - wp_set_current_user( $this->contributor ); - $request = new WP_REST_Request( 'GET', $this->endpoint . '/products/categories/' . $this->categories['parent']['term_id'] ); - - $response = $this->server->dispatch( $request ); - $category = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $category['name'], 'Parent Category' ); - $this->assertEquals( $category['parent'], 0 ); - $this->assertEquals( $category['count'], 2 ); - } -} diff --git a/unit-tests/Tests/Blocks/products.php b/unit-tests/Tests/Blocks/products.php deleted file mode 100644 index 2da60b143cc..00000000000 --- a/unit-tests/Tests/Blocks/products.php +++ /dev/null @@ -1,313 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'author', - ) - ); - $this->contributor = $this->factory->user->create( - array( - 'role' => 'contributor', - ) - ); - $this->subscriber = $this->factory->user->create( - array( - 'role' => 'subscriber', - ) - ); - - // Create 3 product categories. - $parent = wp_insert_term( 'Parent Category', 'product_cat' ); - $child = wp_insert_term( - 'Child Category', - 'product_cat', - array( 'parent' => $parent['term_id'] ) - ); - $single = wp_insert_term( 'Standalone Category', 'product_cat' ); - $this->categories = array( - 'parent' => $parent, - 'child' => $child, - 'single' => $single, - ); - - // Create two products, one with 'parent', and one with 'single'. - $this->products = array(); - $this->products[0] = ProductHelper::create_simple_product( false ); - $this->products[0]->set_category_ids( array( $parent['term_id'] ) ); - $this->products[0]->save(); - - $this->products[1] = ProductHelper::create_simple_product( false ); - $this->products[1]->set_category_ids( array( $single['term_id'] ) ); - $this->products[1]->save(); - - $this->products[2] = ProductHelper::create_simple_product( false ); - $this->products[2]->set_category_ids( array( $child['term_id'], $single['term_id'] ) ); - $this->products[2]->save(); - - $this->products[3] = ProductHelper::create_simple_product( false ); - $this->products[3]->set_category_ids( array( $parent['term_id'], $single['term_id'] ) ); - $this->products[3]->save(); - } - - /** - * Test route registration. - * - * @since 3.6.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - - $this->assertArrayHasKey( '/wc-blocks/v1/products', $routes ); - $this->assertArrayHasKey( '/wc-blocks/v1/products/(?P[\d]+)', $routes ); - } - - /** - * Test getting products. - * - * @since 3.6.0 - */ - public function test_get_products() { - wp_set_current_user( $this->user ); - ProductHelper::create_external_product(); - sleep( 1 ); // So both products have different timestamps. - $product = ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 6, count( $products ) ); - } - - /** - * Test getting products as an contributor. - * - * @since 3.6.0 - */ - public function test_get_products_as_contributor() { - wp_set_current_user( $this->contributor ); - ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test getting products as an subscriber. - * - * @since 3.6.0 - */ - public function test_get_products_as_subscriber() { - wp_set_current_user( $this->subscriber ); - ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ) ); - $this->assertEquals( 403, $response->get_status() ); - } - - /** - * Test getting products with custom ordering. - * - * @since 3.6.0 - */ - public function test_get_products_order_by_price() { - wp_set_current_user( $this->user ); - ProductHelper::create_external_product(); - sleep( 1 ); // So both products have different timestamps. - $product = ProductHelper::create_simple_product( false ); // Prevent saving, since we save here. - // Customize the price, otherwise both are 10. - $product->set_props( - array( - 'regular_price' => 15, - 'price' => 15, - ) - ); - $product->save(); - - $request = new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ); - $request->set_param( 'orderby', 'price' ); - $request->set_param( 'order', 'asc' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 6, count( $products ) ); - - $this->assertEquals( 'Dummy Product', $products[1]['name'] ); - $this->assertEquals( '10', $products[1]['price'] ); - } - - /** - * Test product_visibility queries. - * - * @since 3.6.0 - */ - public function test_product_visibility() { - wp_set_current_user( $this->user ); - $visible_product = ProductHelper::create_simple_product(); - $visible_product->set_name( 'Visible Product' ); - $visible_product->set_catalog_visibility( 'visible' ); - $visible_product->save(); - - $catalog_product = ProductHelper::create_simple_product(); - $catalog_product->set_name( 'Catalog Product' ); - $catalog_product->set_catalog_visibility( 'catalog' ); - $catalog_product->save(); - - $search_product = ProductHelper::create_simple_product(); - $search_product->set_name( 'Search Product' ); - $search_product->set_catalog_visibility( 'search' ); - $search_product->save(); - - $hidden_product = ProductHelper::create_simple_product(); - $hidden_product->set_name( 'Hidden Product' ); - $hidden_product->set_catalog_visibility( 'hidden' ); - $hidden_product->save(); - - $query_params = array( - 'catalog_visibility' => 'visible', - ); - $request = new WP_REST_REQUEST( 'GET', '/wc-blocks/v1/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 5, count( $products ) ); - $this->assertEquals( 'Visible Product', $products[0]['name'] ); - - $query_params = array( - 'catalog_visibility' => 'catalog', - 'orderby' => 'id', - 'order' => 'asc', - ); - $request = new WP_REST_REQUEST( 'GET', '/wc-blocks/v1/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 6, count( $products ) ); - $this->assertEquals( 'Dummy Product', $products[0]['name'] ); - - $query_params = array( - 'catalog_visibility' => 'search', - 'orderby' => 'id', - 'order' => 'asc', - ); - $request = new WP_REST_REQUEST( 'GET', '/wc-blocks/v1/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 6, count( $products ) ); - $this->assertEquals( 'Dummy Product', $products[0]['name'] ); - - $query_params = array( - 'catalog_visibility' => 'hidden', - ); - $request = new WP_REST_REQUEST( 'GET', '/wc-blocks/v1/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $products ) ); - $this->assertEquals( 'Hidden Product', $products[0]['name'] ); - } - - /** - * Test product category intersection: Any product in either Single or Child (3). - * - * @since 3.6.0 - */ - public function test_get_products_in_any_categories_child() { - wp_set_current_user( $this->user ); - - $cats = $this->categories['child']['term_id'] . ',' . $this->categories['single']['term_id']; - - $request = new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ); - $request->set_param( 'category', $cats ); - $request->set_param( 'category_operator', 'in' ); - - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 3, count( $response_products ) ); - } - - /** - * Test product category intersection: Any product in both Single and Child (1). - * - * @since 3.6.0 - */ - public function test_get_products_in_all_categories_child() { - wp_set_current_user( $this->user ); - - $cats = $this->categories['child']['term_id'] . ',' . $this->categories['single']['term_id']; - - $request = new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ); - $request->set_param( 'category', $cats ); - $request->set_param( 'category_operator', 'and' ); - - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $response_products ) ); - } - - /** - * Test product category intersection: Any product in both Single and Parent (1). - * - * @since 3.6.0 - */ - public function test_get_products_in_all_categories_parent() { - wp_set_current_user( $this->user ); - - $cats = $this->categories['parent']['term_id'] . ',' . $this->categories['single']['term_id']; - - $request = new WP_REST_Request( 'GET', '/wc-blocks/v1/products' ); - $request->set_param( 'category', $cats ); - $request->set_param( 'category_operator', 'and' ); - - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $response_products ) ); - } -} From ec40302980369d0bdc1236bca73a7904be448780 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 16:15:20 +0100 Subject: [PATCH 093/440] Introduce woocommerce_rest_api_get_rest_namespaces filter --- src/RestApi.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/RestApi.php b/src/RestApi.php index bb5d7a9161d..90a8376fa68 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -57,13 +57,15 @@ class RestApi { * @return array List of Namespaces and Main controller classes. */ protected function get_rest_namespaces() { - return [ - 'wc/v1' => 'WC_REST_Controllers_V1', - 'wc/v2' => 'WC_REST_Controllers_V2', - 'wc/v3' => 'WC_REST_Controllers_V3', - 'wc/v4' => '\WooCommerce\RestApi\Version4\Controllers', - 'wc-blocks/v1' => 'WC_REST_Blocks_Controllers', - ]; + return apply_filters( + 'woocommerce_rest_api_get_rest_namespaces', + [ + 'wc/v1' => 'WC_REST_Controllers_V1', + 'wc/v2' => 'WC_REST_Controllers_V2', + 'wc/v3' => 'WC_REST_Controllers_V3', + 'wc/v4' => '\WooCommerce\RestApi\Version4\Controllers', + ] + ); } /** From 889b367670ce711b1173cc6eeb9c7d22e42f0892 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 16:17:53 +0100 Subject: [PATCH 094/440] Changelog update --- src/RestApi/Version4/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/RestApi/Version4/changelog.md b/src/RestApi/Version4/changelog.md index 822bc352dc7..e510d46c08c 100644 --- a/src/RestApi/Version4/changelog.md +++ b/src/RestApi/Version4/changelog.md @@ -3,6 +3,7 @@ ## Changes - All endpoints - Rewritten with namespaces as standalone classes. +- All endpoints - Normalized DELETE responses to return previous object. - Coupons - Added `search` parameter. - Orders - Added order number to schema. - Orders - Added currency_symbol to schema. From a5e4c3bf4d17e3830b93d6015a74c9cde3682f9e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Jun 2019 16:35:36 +0100 Subject: [PATCH 095/440] admin --- unit-tests/bin/install.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh index 269e4ed91a3..4cdcc6c5b49 100755 --- a/unit-tests/bin/install.sh +++ b/unit-tests/bin/install.sh @@ -180,9 +180,16 @@ install_deps() { cd "wp-content/plugins/" git clone --depth 1 https://github.com/woocommerce/woocommerce.git + git clone --depth 1 https://github.com/woocommerce/woocommerce-admin.git + + cd "woocommerce-admin" + composer install + npm install + npm run build cd "$WP_CORE_DIR" php wp-cli.phar plugin activate woocommerce + php wp-cli.phar plugin activate woocommerce-admin if [ "$BRANCH" != "" ]; then # Install the correct branch of the plugin, if running from Travis CI. @@ -196,4 +203,4 @@ install_deps() { install_wp install_test_suite install_db -install_deps \ No newline at end of file +install_deps From 2eff709060c93f0fd171d3bc24d3110fea6a1a16 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 12:19:14 +0100 Subject: [PATCH 096/440] Rename endpoints to controllers --- src/RestApi.php | 6 +++--- unit-tests/bin/install.sh | 7 ------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/RestApi.php b/src/RestApi.php index 90a8376fa68..3ccfaff8e63 100644 --- a/src/RestApi.php +++ b/src/RestApi.php @@ -28,7 +28,7 @@ class RestApi { * * @var array */ - protected $endpoints = []; + protected $controllers = []; /** * Hook into WordPress ready to init the REST API as needed. @@ -45,8 +45,8 @@ class RestApi { $controllers = $namespace_class::get_controllers(); foreach ( $controllers as $controller_name => $controller_class ) { - $this->endpoints[ $namespace ][ $controller_name ] = new $controller_class(); - $this->endpoints[ $namespace ][ $controller_name ]->register_routes(); + $this->controllers[ $namespace ][ $controller_name ] = new $controller_class(); + $this->controllers[ $namespace ][ $controller_name ]->register_routes(); } } } diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh index 4cdcc6c5b49..0b6747fc8a3 100755 --- a/unit-tests/bin/install.sh +++ b/unit-tests/bin/install.sh @@ -180,16 +180,9 @@ install_deps() { cd "wp-content/plugins/" git clone --depth 1 https://github.com/woocommerce/woocommerce.git - git clone --depth 1 https://github.com/woocommerce/woocommerce-admin.git - - cd "woocommerce-admin" - composer install - npm install - npm run build cd "$WP_CORE_DIR" php wp-cli.phar plugin activate woocommerce - php wp-cli.phar plugin activate woocommerce-admin if [ "$BRANCH" != "" ]; then # Install the correct branch of the plugin, if running from Travis CI. From 732eb4b4534b1329268bf00d5db57bda5f604336 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 13:09:20 +0100 Subject: [PATCH 097/440] Namespace and structure improvements --- composer.json | 9 +- init.php | 4 +- .../class-wc-rest-coupons-v1-controller.php | 0 ...-rest-customer-downloads-v1-controller.php | 0 .../class-wc-rest-customers-v1-controller.php | 0 ...lass-wc-rest-order-notes-v1-controller.php | 0 ...ss-wc-rest-order-refunds-v1-controller.php | 0 .../class-wc-rest-orders-v1-controller.php | 0 ...-product-attribute-terms-v1-controller.php | 0 ...-rest-product-attributes-v1-controller.php | 0 ...-rest-product-categories-v1-controller.php | 0 ...-wc-rest-product-reviews-v1-controller.php | 0 ...product-shipping-classes-v1-controller.php | 0 ...ass-wc-rest-product-tags-v1-controller.php | 0 .../class-wc-rest-products-v1-controller.php | 0 ...ass-wc-rest-report-sales-v1-controller.php | 0 ...-rest-report-top-sellers-v1-controller.php | 0 .../class-wc-rest-reports-v1-controller.php | 0 ...lass-wc-rest-tax-classes-v1-controller.php | 0 .../class-wc-rest-taxes-v1-controller.php | 0 ...-rest-webhook-deliveries-v1-controller.php | 0 .../class-wc-rest-webhooks-v1-controller.php | 0 .../class-wc-rest-coupons-v2-controller.php | 0 ...-rest-customer-downloads-v2-controller.php | 0 .../class-wc-rest-customers-v2-controller.php | 0 ...s-wc-rest-network-orders-v2-controller.php | 0 ...lass-wc-rest-order-notes-v2-controller.php | 0 ...ss-wc-rest-order-refunds-v2-controller.php | 0 .../class-wc-rest-orders-v2-controller.php | 0 ...wc-rest-payment-gateways-v2-controller.php | 0 ...-product-attribute-terms-v2-controller.php | 0 ...-rest-product-attributes-v2-controller.php | 0 ...-rest-product-categories-v2-controller.php | 0 ...-wc-rest-product-reviews-v2-controller.php | 0 ...product-shipping-classes-v2-controller.php | 0 ...ass-wc-rest-product-tags-v2-controller.php | 0 ...-rest-product-variations-v2-controller.php | 0 .../class-wc-rest-products-v2-controller.php | 0 ...ass-wc-rest-report-sales-v2-controller.php | 0 ...-rest-report-top-sellers-v2-controller.php | 0 .../class-wc-rest-reports-v2-controller.php | 0 ...-wc-rest-setting-options-v2-controller.php | 0 .../class-wc-rest-settings-v2-controller.php | 0 ...wc-rest-shipping-methods-v2-controller.php | 0 ...-shipping-zone-locations-v2-controller.php | 0 ...st-shipping-zone-methods-v2-controller.php | 0 ...s-wc-rest-shipping-zones-v2-controller.php | 0 ...rest-system-status-tools-v2-controller.php | 0 ...ss-wc-rest-system-status-v2-controller.php | 0 ...lass-wc-rest-tax-classes-v2-controller.php | 0 .../class-wc-rest-taxes-v2-controller.php | 0 ...-rest-webhook-deliveries-v2-controller.php | 0 .../class-wc-rest-webhooks-v2-controller.php | 0 .../Version3/class-wc-rest-controller.php | 0 .../class-wc-rest-coupons-controller.php | 0 .../class-wc-rest-crud-controller.php | 0 ...-wc-rest-customer-downloads-controller.php | 0 .../class-wc-rest-customers-controller.php | 0 ...ass-wc-rest-data-continents-controller.php | 0 .../class-wc-rest-data-controller.php | 0 ...lass-wc-rest-data-countries-controller.php | 0 ...ass-wc-rest-data-currencies-controller.php | 0 ...lass-wc-rest-network-orders-controller.php | 0 .../class-wc-rest-order-notes-controller.php | 0 ...class-wc-rest-order-refunds-controller.php | 0 .../class-wc-rest-orders-controller.php | 0 ...ss-wc-rest-payment-gateways-controller.php | 0 .../class-wc-rest-posts-controller.php | 0 ...est-product-attribute-terms-controller.php | 0 ...-wc-rest-product-attributes-controller.php | 0 ...-wc-rest-product-categories-controller.php | 0 ...ass-wc-rest-product-reviews-controller.php | 0 ...st-product-shipping-classes-controller.php | 0 .../class-wc-rest-product-tags-controller.php | 0 ...-wc-rest-product-variations-controller.php | 0 .../class-wc-rest-products-controller.php | 0 ...-rest-report-coupons-totals-controller.php | 0 ...est-report-customers-totals-controller.php | 0 ...c-rest-report-orders-totals-controller.php | 0 ...rest-report-products-totals-controller.php | 0 ...-rest-report-reviews-totals-controller.php | 0 .../class-wc-rest-report-sales-controller.php | 0 ...-wc-rest-report-top-sellers-controller.php | 0 .../class-wc-rest-reports-controller.php | 0 ...ass-wc-rest-setting-options-controller.php | 0 .../class-wc-rest-settings-controller.php | 0 ...ss-wc-rest-shipping-methods-controller.php | 0 ...est-shipping-zone-locations-controller.php | 0 ...-rest-shipping-zone-methods-controller.php | 0 ...wc-rest-shipping-zones-controller-base.php | 0 ...lass-wc-rest-shipping-zones-controller.php | 0 ...class-wc-rest-system-status-controller.php | 0 ...wc-rest-system-status-tools-controller.php | 0 .../class-wc-rest-tax-classes-controller.php | 0 .../class-wc-rest-taxes-controller.php | 0 .../class-wc-rest-terms-controller.php | 0 .../class-wc-rest-webhooks-controller.php | 0 .../Version4}/AbstractController.php | 2 +- .../Version4}/AbstractObjectsController.php | 2 +- .../Version4}/AbstractPostsController.php | 2 +- .../AbstractShippingZonesController.php | 2 +- .../Version4}/AbstractTermsContoller.php | 2 +- .../Version4}/AdminNotes.php | 2 +- .../Version4}/Coupons.php | 2 +- .../Version4}/CustomerDownloads.php | 2 +- .../Version4}/Customers.php | 4 +- .../Version4}/Data.php | 2 +- .../Version4}/Data/Continents.php | 4 +- .../Version4}/Data/Countries.php | 4 +- .../Version4}/Data/Currencies.php | 4 +- .../Version4}/Data/DownloadIPs.php | 4 +- .../Version4}/Leaderboards.php | 2 +- .../Version4}/NetworkOrders.php | 2 +- .../Version4}/OrderNotes.php | 6 +- .../Version4}/OrderRefunds.php | 2 +- .../Version4}/Orders.php | 2 +- .../Version4}/PaymentGateways.php | 2 +- .../Version4}/ProductAttributeTerms.php | 2 +- .../Version4}/ProductAttributes.php | 2 +- .../Version4}/ProductCategories.php | 2 +- .../Version4}/ProductReviews.php | 2 +- .../Version4}/ProductShippingClasses.php | 2 +- .../Version4}/ProductTags.php | 2 +- .../Version4}/ProductVariations.php | 4 +- .../Version4}/Products.php | 4 +- .../Version4}/Reports.php | 2 +- .../Version4}/Reports/Categories.php | 4 +- .../Version4}/Reports/CouponStats.php | 4 +- .../Version4}/Reports/Coupons.php | 4 +- .../Version4}/Reports/CustomerStats.php | 4 +- .../Version4}/Reports/Customers.php | 4 +- .../Version4}/Reports/DownloadStats.php | 4 +- .../Version4}/Reports/Downloads.php | 4 +- .../Version4}/Reports/Import.php | 4 +- .../Version4}/Reports/OrderStats.php | 4 +- .../Version4}/Reports/Orders.php | 4 +- .../Reports/PerformanceIndicators.php | 4 +- .../Version4}/Reports/ProductStats.php | 4 +- .../Version4}/Reports/Products.php | 4 +- .../Version4}/Reports/RevenueStats.php | 4 +- .../Version4}/Reports/Stock.php | 4 +- .../Version4}/Reports/StockStats.php | 4 +- .../Version4}/Reports/TaxStats.php | 4 +- .../Version4}/Reports/Taxes.php | 4 +- .../Version4}/Reports/Variations.php | 4 +- .../Version4}/Settings.php | 2 +- .../Version4}/SettingsOptions.php | 2 +- .../Version4}/ShippingMethods.php | 2 +- .../Version4}/ShippingZoneLocations.php | 2 +- .../Version4}/ShippingZoneMethods.php | 2 +- .../Version4}/ShippingZones.php | 2 +- .../Version4}/SystemStatus.php | 2 +- .../Version4}/SystemStatusTools.php | 2 +- .../Version4}/TaxClasses.php | 2 +- .../Version4}/Taxes.php | 2 +- .../Version4}/Webhooks.php | 118 ++++---- .../Version4/_changelog.md} | 0 src/RestApi.php | 91 ------ .../Version1/class-wc-rest-controllers-v1.php | 43 --- .../Version2/class-wc-rest-controllers-v2.php | 54 ---- .../Version3/class-wc-rest-controllers-v3.php | 62 ---- src/RestApi/Version4/Controllers.php | 87 ------ src/Server.php | 282 ++++++++++++++++++ src/Utilities/SingletonTrait.php | 4 +- unit-tests/Bootstrap.php | 24 +- version.php | 2 +- 166 files changed, 444 insertions(+), 508 deletions(-) rename src/{RestApi => Controllers}/Version1/class-wc-rest-coupons-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-customer-downloads-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-customers-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-order-notes-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-order-refunds-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-orders-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-product-attribute-terms-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-product-attributes-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-product-categories-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-product-reviews-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-product-shipping-classes-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-product-tags-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-products-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-report-sales-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-report-top-sellers-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-reports-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-tax-classes-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-taxes-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-webhook-deliveries-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version1/class-wc-rest-webhooks-v1-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-coupons-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-customer-downloads-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-customers-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-network-orders-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-order-notes-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-order-refunds-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-orders-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-payment-gateways-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-product-attribute-terms-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-product-attributes-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-product-categories-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-product-reviews-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-product-shipping-classes-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-product-tags-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-product-variations-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-products-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-report-sales-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-report-top-sellers-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-reports-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-setting-options-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-settings-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-shipping-methods-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-shipping-zones-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-system-status-tools-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-system-status-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-tax-classes-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-taxes-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-webhook-deliveries-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version2/class-wc-rest-webhooks-v2-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-coupons-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-crud-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-customer-downloads-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-customers-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-data-continents-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-data-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-data-countries-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-data-currencies-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-network-orders-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-order-notes-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-order-refunds-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-orders-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-payment-gateways-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-posts-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-product-attribute-terms-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-product-attributes-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-product-categories-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-product-reviews-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-product-shipping-classes-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-product-tags-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-product-variations-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-products-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-report-coupons-totals-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-report-customers-totals-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-report-orders-totals-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-report-products-totals-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-report-reviews-totals-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-report-sales-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-report-top-sellers-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-reports-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-setting-options-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-settings-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-shipping-methods-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-shipping-zone-locations-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-shipping-zone-methods-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-shipping-zones-controller-base.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-shipping-zones-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-system-status-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-system-status-tools-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-tax-classes-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-taxes-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-terms-controller.php (100%) rename src/{RestApi => Controllers}/Version3/class-wc-rest-webhooks-controller.php (100%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/AbstractController.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/AbstractObjectsController.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/AbstractPostsController.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/AbstractShippingZonesController.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/AbstractTermsContoller.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/AdminNotes.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Coupons.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/CustomerDownloads.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Customers.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Data.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Data/Continents.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Data/Countries.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Data/Currencies.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Data/DownloadIPs.php (97%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Leaderboards.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/NetworkOrders.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/OrderNotes.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/OrderRefunds.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Orders.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/PaymentGateways.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ProductAttributeTerms.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ProductAttributes.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ProductCategories.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ProductReviews.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ProductShippingClasses.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ProductTags.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ProductVariations.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Products.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Categories.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/CouponStats.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Coupons.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/CustomerStats.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Customers.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/DownloadStats.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Downloads.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Import.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/OrderStats.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Orders.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/PerformanceIndicators.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/ProductStats.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Products.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/RevenueStats.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Stock.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/StockStats.php (96%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/TaxStats.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Taxes.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Reports/Variations.php (98%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Settings.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/SettingsOptions.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ShippingMethods.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ShippingZoneLocations.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ShippingZoneMethods.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/ShippingZones.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/SystemStatus.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/SystemStatusTools.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/TaxClasses.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Taxes.php (99%) rename src/{RestApi/Version4/Controllers => Controllers/Version4}/Webhooks.php (90%) rename src/{RestApi/Version4/changelog.md => Controllers/Version4/_changelog.md} (100%) delete mode 100644 src/RestApi.php delete mode 100644 src/RestApi/Version1/class-wc-rest-controllers-v1.php delete mode 100644 src/RestApi/Version2/class-wc-rest-controllers-v2.php delete mode 100644 src/RestApi/Version3/class-wc-rest-controllers-v3.php delete mode 100644 src/RestApi/Version4/Controllers.php create mode 100644 src/Server.php diff --git a/composer.json b/composer.json index 3185cd520c3..419524bc60e 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,13 @@ "woocommerce/woocommerce-sniffs": "0.0.6" }, "autoload": { - "classmap": ["src"] + "classmap": [ + "src/Controllers/Version1", + "src/Controllers/Version2", + "src/Controllers/Version3" + ], + "psr-4": { + "WooCommerce\\RestApi\\": "src/" + } } } diff --git a/init.php b/init.php index d761c9af059..8085afe0a10 100644 --- a/init.php +++ b/init.php @@ -6,6 +6,6 @@ */ return function() { - require __DIR__ . '/src/RestApi.php'; - \WooCommerce\RestApi::instance()->init(); + require __DIR__ . '/src/Server.php'; + \WooCommerce\RestApi\Server::instance()->init(); }; diff --git a/src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php b/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-coupons-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-customer-downloads-v1-controller.php b/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-customer-downloads-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-customers-v1-controller.php b/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-customers-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-customers-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-order-notes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-order-notes-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-order-refunds-v1-controller.php b/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-order-refunds-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-orders-v1-controller.php b/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-orders-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-orders-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-product-attribute-terms-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-product-attribute-terms-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-product-attributes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-product-attributes-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-product-categories-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-product-categories-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-product-reviews-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-product-reviews-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-product-shipping-classes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-product-shipping-classes-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-product-tags-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-product-tags-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-products-v1-controller.php b/src/Controllers/Version1/class-wc-rest-products-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-products-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-products-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-report-sales-v1-controller.php b/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-report-sales-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-report-top-sellers-v1-controller.php b/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-report-top-sellers-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-reports-v1-controller.php b/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-reports-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-reports-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-tax-classes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-tax-classes-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-taxes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-taxes-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-webhook-deliveries-v1-controller.php b/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-webhook-deliveries-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php diff --git a/src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php b/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php similarity index 100% rename from src/RestApi/Version1/class-wc-rest-webhooks-v1-controller.php rename to src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php b/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-coupons-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-customer-downloads-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-customer-downloads-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-customers-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-customers-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-customers-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-network-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-network-orders-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-order-notes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-order-notes-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-order-refunds-v2-controller.php b/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-order-refunds-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-orders-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-orders-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-payment-gateways-v2-controller.php b/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-payment-gateways-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-product-attribute-terms-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-product-attribute-terms-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-product-attributes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-product-attributes-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-product-categories-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-product-categories-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-product-reviews-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-product-reviews-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-product-shipping-classes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-product-shipping-classes-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-product-tags-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-product-tags-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-product-variations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-product-variations-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-products-v2-controller.php b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-products-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-products-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-report-sales-v2-controller.php b/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-report-sales-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-report-top-sellers-v2-controller.php b/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-report-top-sellers-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-reports-v2-controller.php b/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-reports-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-reports-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-setting-options-v2-controller.php b/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-setting-options-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-settings-v2-controller.php b/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-settings-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-settings-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-shipping-methods-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-shipping-methods-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-shipping-zones-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-shipping-zones-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-system-status-tools-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-system-status-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-tax-classes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-tax-classes-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-taxes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-taxes-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-webhook-deliveries-v2-controller.php b/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-webhook-deliveries-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php diff --git a/src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php b/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php similarity index 100% rename from src/RestApi/Version2/class-wc-rest-webhooks-v2-controller.php rename to src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-controller.php b/src/Controllers/Version3/class-wc-rest-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-controller.php rename to src/Controllers/Version3/class-wc-rest-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-coupons-controller.php b/src/Controllers/Version3/class-wc-rest-coupons-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-coupons-controller.php rename to src/Controllers/Version3/class-wc-rest-coupons-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-crud-controller.php b/src/Controllers/Version3/class-wc-rest-crud-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-crud-controller.php rename to src/Controllers/Version3/class-wc-rest-crud-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-customer-downloads-controller.php b/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-customer-downloads-controller.php rename to src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-customers-controller.php b/src/Controllers/Version3/class-wc-rest-customers-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-customers-controller.php rename to src/Controllers/Version3/class-wc-rest-customers-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-data-continents-controller.php b/src/Controllers/Version3/class-wc-rest-data-continents-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-data-continents-controller.php rename to src/Controllers/Version3/class-wc-rest-data-continents-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-data-controller.php b/src/Controllers/Version3/class-wc-rest-data-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-data-controller.php rename to src/Controllers/Version3/class-wc-rest-data-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-data-countries-controller.php b/src/Controllers/Version3/class-wc-rest-data-countries-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-data-countries-controller.php rename to src/Controllers/Version3/class-wc-rest-data-countries-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-data-currencies-controller.php b/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-data-currencies-controller.php rename to src/Controllers/Version3/class-wc-rest-data-currencies-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-network-orders-controller.php b/src/Controllers/Version3/class-wc-rest-network-orders-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-network-orders-controller.php rename to src/Controllers/Version3/class-wc-rest-network-orders-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-order-notes-controller.php b/src/Controllers/Version3/class-wc-rest-order-notes-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-order-notes-controller.php rename to src/Controllers/Version3/class-wc-rest-order-notes-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-order-refunds-controller.php b/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-order-refunds-controller.php rename to src/Controllers/Version3/class-wc-rest-order-refunds-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-orders-controller.php b/src/Controllers/Version3/class-wc-rest-orders-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-orders-controller.php rename to src/Controllers/Version3/class-wc-rest-orders-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-payment-gateways-controller.php b/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-payment-gateways-controller.php rename to src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-posts-controller.php b/src/Controllers/Version3/class-wc-rest-posts-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-posts-controller.php rename to src/Controllers/Version3/class-wc-rest-posts-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-product-attribute-terms-controller.php b/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-product-attribute-terms-controller.php rename to src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-product-attributes-controller.php b/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-product-attributes-controller.php rename to src/Controllers/Version3/class-wc-rest-product-attributes-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-product-categories-controller.php b/src/Controllers/Version3/class-wc-rest-product-categories-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-product-categories-controller.php rename to src/Controllers/Version3/class-wc-rest-product-categories-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-product-reviews-controller.php b/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-product-reviews-controller.php rename to src/Controllers/Version3/class-wc-rest-product-reviews-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-product-shipping-classes-controller.php b/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-product-shipping-classes-controller.php rename to src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-product-tags-controller.php b/src/Controllers/Version3/class-wc-rest-product-tags-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-product-tags-controller.php rename to src/Controllers/Version3/class-wc-rest-product-tags-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-product-variations-controller.php b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-product-variations-controller.php rename to src/Controllers/Version3/class-wc-rest-product-variations-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-products-controller.php b/src/Controllers/Version3/class-wc-rest-products-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-products-controller.php rename to src/Controllers/Version3/class-wc-rest-products-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-report-coupons-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-report-coupons-totals-controller.php rename to src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-report-customers-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-report-customers-totals-controller.php rename to src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-report-orders-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-report-orders-totals-controller.php rename to src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-report-products-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-report-products-totals-controller.php rename to src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-report-reviews-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-report-reviews-totals-controller.php rename to src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-report-sales-controller.php b/src/Controllers/Version3/class-wc-rest-report-sales-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-report-sales-controller.php rename to src/Controllers/Version3/class-wc-rest-report-sales-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-report-top-sellers-controller.php b/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-report-top-sellers-controller.php rename to src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-reports-controller.php b/src/Controllers/Version3/class-wc-rest-reports-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-reports-controller.php rename to src/Controllers/Version3/class-wc-rest-reports-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-setting-options-controller.php b/src/Controllers/Version3/class-wc-rest-setting-options-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-setting-options-controller.php rename to src/Controllers/Version3/class-wc-rest-setting-options-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-settings-controller.php b/src/Controllers/Version3/class-wc-rest-settings-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-settings-controller.php rename to src/Controllers/Version3/class-wc-rest-settings-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-shipping-methods-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-shipping-methods-controller.php rename to src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-shipping-zone-locations-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-shipping-zone-locations-controller.php rename to src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-shipping-zone-methods-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-shipping-zone-methods-controller.php rename to src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-shipping-zones-controller-base.php b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-shipping-zones-controller-base.php rename to src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php diff --git a/src/RestApi/Version3/class-wc-rest-shipping-zones-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-shipping-zones-controller.php rename to src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-system-status-controller.php b/src/Controllers/Version3/class-wc-rest-system-status-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-system-status-controller.php rename to src/Controllers/Version3/class-wc-rest-system-status-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-system-status-tools-controller.php b/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-system-status-tools-controller.php rename to src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-tax-classes-controller.php b/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-tax-classes-controller.php rename to src/Controllers/Version3/class-wc-rest-tax-classes-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-taxes-controller.php b/src/Controllers/Version3/class-wc-rest-taxes-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-taxes-controller.php rename to src/Controllers/Version3/class-wc-rest-taxes-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-terms-controller.php b/src/Controllers/Version3/class-wc-rest-terms-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-terms-controller.php rename to src/Controllers/Version3/class-wc-rest-terms-controller.php diff --git a/src/RestApi/Version3/class-wc-rest-webhooks-controller.php b/src/Controllers/Version3/class-wc-rest-webhooks-controller.php similarity index 100% rename from src/RestApi/Version3/class-wc-rest-webhooks-controller.php rename to src/Controllers/Version3/class-wc-rest-webhooks-controller.php diff --git a/src/RestApi/Version4/Controllers/AbstractController.php b/src/Controllers/Version4/AbstractController.php similarity index 99% rename from src/RestApi/Version4/Controllers/AbstractController.php rename to src/Controllers/Version4/AbstractController.php index d381bceef54..e073d8d502a 100644 --- a/src/RestApi/Version4/Controllers/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -13,7 +13,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php similarity index 99% rename from src/RestApi/Version4/Controllers/AbstractObjectsController.php rename to src/Controllers/Version4/AbstractObjectsController.php index 6959d0127b5..047110ffe3e 100644 --- a/src/RestApi/Version4/Controllers/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -5,7 +5,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/AbstractPostsController.php b/src/Controllers/Version4/AbstractPostsController.php similarity index 99% rename from src/RestApi/Version4/Controllers/AbstractPostsController.php rename to src/Controllers/Version4/AbstractPostsController.php index b6609885d54..c07b7fe09d6 100644 --- a/src/RestApi/Version4/Controllers/AbstractPostsController.php +++ b/src/Controllers/Version4/AbstractPostsController.php @@ -5,7 +5,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php b/src/Controllers/Version4/AbstractShippingZonesController.php similarity index 98% rename from src/RestApi/Version4/Controllers/AbstractShippingZonesController.php rename to src/Controllers/Version4/AbstractShippingZonesController.php index 348d4a8a4f6..aa10f02f4a0 100644 --- a/src/RestApi/Version4/Controllers/AbstractShippingZonesController.php +++ b/src/Controllers/Version4/AbstractShippingZonesController.php @@ -8,7 +8,7 @@ * @since 3.0.0 */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php similarity index 99% rename from src/RestApi/Version4/Controllers/AbstractTermsContoller.php rename to src/Controllers/Version4/AbstractTermsContoller.php index 513005002f7..3508b79a5d2 100644 --- a/src/RestApi/Version4/Controllers/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -5,7 +5,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/AdminNotes.php b/src/Controllers/Version4/AdminNotes.php similarity index 99% rename from src/RestApi/Version4/Controllers/AdminNotes.php rename to src/Controllers/Version4/AdminNotes.php index ee39d96d727..17eb739d614 100644 --- a/src/RestApi/Version4/Controllers/AdminNotes.php +++ b/src/Controllers/Version4/AdminNotes.php @@ -7,7 +7,7 @@ * @package WooCommerce Admin/API */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/Coupons.php b/src/Controllers/Version4/Coupons.php similarity index 99% rename from src/RestApi/Version4/Controllers/Coupons.php rename to src/Controllers/Version4/Coupons.php index f4c4c9b13ac..a10208c0543 100644 --- a/src/RestApi/Version4/Controllers/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php similarity index 99% rename from src/RestApi/Version4/Controllers/CustomerDownloads.php rename to src/Controllers/Version4/CustomerDownloads.php index 0dcb39cf469..25e94097b04 100644 --- a/src/RestApi/Version4/Controllers/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/Customers.php b/src/Controllers/Version4/Customers.php similarity index 99% rename from src/RestApi/Version4/Controllers/Customers.php rename to src/Controllers/Version4/Customers.php index 4194b7d8ebf..018c5a6b0ef 100644 --- a/src/RestApi/Version4/Controllers/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; @@ -440,7 +440,7 @@ class Customers extends AbstractController { * Update a single user. * * @throws \WC_REST_Exception On invalid params. - * + * * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error\WP_REST_Response */ diff --git a/src/RestApi/Version4/Controllers/Data.php b/src/Controllers/Version4/Data.php similarity index 98% rename from src/RestApi/Version4/Controllers/Data.php rename to src/Controllers/Version4/Data.php index bb91d3fa18a..b5e654badbf 100644 --- a/src/RestApi/Version4/Controllers/Data.php +++ b/src/Controllers/Version4/Data.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php similarity index 98% rename from src/RestApi/Version4/Controllers/Data/Continents.php rename to src/Controllers/Version4/Data/Continents.php index 995196df4e5..69b76280515 100644 --- a/src/RestApi/Version4/Controllers/Data/Continents.php +++ b/src/Controllers/Version4/Data/Continents.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Data; +namespace WooCommerce\RestApi\Controllers\Version4\Data; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; +use \WooCommerce\RestApi\Controllers\Version4\Data as DataController; /** * REST API Data Continents controller class. diff --git a/src/RestApi/Version4/Controllers/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php similarity index 98% rename from src/RestApi/Version4/Controllers/Data/Countries.php rename to src/Controllers/Version4/Data/Countries.php index 8a76ad37789..c1993db8583 100644 --- a/src/RestApi/Version4/Controllers/Data/Countries.php +++ b/src/Controllers/Version4/Data/Countries.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Data; +namespace WooCommerce\RestApi\Controllers\Version4\Data; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; +use \WooCommerce\RestApi\Controllers\Version4\Data as DataController; /** * REST API Data Countries controller class. diff --git a/src/RestApi/Version4/Controllers/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php similarity index 98% rename from src/RestApi/Version4/Controllers/Data/Currencies.php rename to src/Controllers/Version4/Data/Currencies.php index f3e5acaa54d..3974edcaeb6 100644 --- a/src/RestApi/Version4/Controllers/Data/Currencies.php +++ b/src/Controllers/Version4/Data/Currencies.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Data; +namespace WooCommerce\RestApi\Controllers\Version4\Data; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; +use \WooCommerce\RestApi\Controllers\Version4\Data as DataController; /** * REST API Data Currencies controller class. diff --git a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php similarity index 97% rename from src/RestApi/Version4/Controllers/Data/DownloadIPs.php rename to src/Controllers/Version4/Data/DownloadIPs.php index 8e7637d4e67..9d27f037d94 100644 --- a/src/RestApi/Version4/Controllers/Data/DownloadIPs.php +++ b/src/Controllers/Version4/Data/DownloadIPs.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Data; +namespace WooCommerce\RestApi\Controllers\Version4\Data; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Data as DataController; +use \WooCommerce\RestApi\Controllers\Version4\Data as DataController; /** * Data Download IP controller. diff --git a/src/RestApi/Version4/Controllers/Leaderboards.php b/src/Controllers/Version4/Leaderboards.php similarity index 99% rename from src/RestApi/Version4/Controllers/Leaderboards.php rename to src/Controllers/Version4/Leaderboards.php index 7cc3b2d99b2..255e1779418 100644 --- a/src/RestApi/Version4/Controllers/Leaderboards.php +++ b/src/Controllers/Version4/Leaderboards.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/NetworkOrders.php b/src/Controllers/Version4/NetworkOrders.php similarity index 98% rename from src/RestApi/Version4/Controllers/NetworkOrders.php rename to src/Controllers/Version4/NetworkOrders.php index 5c3e5cde7ef..2db3d53916c 100644 --- a/src/RestApi/Version4/Controllers/NetworkOrders.php +++ b/src/Controllers/Version4/NetworkOrders.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php similarity index 99% rename from src/RestApi/Version4/Controllers/OrderNotes.php rename to src/Controllers/Version4/OrderNotes.php index af91feec133..ef4bc0c2dae 100644 --- a/src/RestApi/Version4/Controllers/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; @@ -35,7 +35,7 @@ class OrderNotes extends AbstractController { */ public function register_routes() { register_rest_route( - $this->namespace, + $this->namespace, '/' . $this->rest_base, array( 'args' => array( @@ -68,7 +68,7 @@ class OrderNotes extends AbstractController { ); register_rest_route( - $this->namespace, + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( diff --git a/src/RestApi/Version4/Controllers/OrderRefunds.php b/src/Controllers/Version4/OrderRefunds.php similarity index 99% rename from src/RestApi/Version4/Controllers/OrderRefunds.php rename to src/Controllers/Version4/OrderRefunds.php index 16af7ef6dba..a8ed226b12b 100644 --- a/src/RestApi/Version4/Controllers/OrderRefunds.php +++ b/src/Controllers/Version4/OrderRefunds.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/Orders.php b/src/Controllers/Version4/Orders.php similarity index 99% rename from src/RestApi/Version4/Controllers/Orders.php rename to src/Controllers/Version4/Orders.php index efbdb199951..d1e85b61850 100644 --- a/src/RestApi/Version4/Controllers/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php similarity index 99% rename from src/RestApi/Version4/Controllers/PaymentGateways.php rename to src/Controllers/Version4/PaymentGateways.php index 5a1b683820a..74d80d330f4 100644 --- a/src/RestApi/Version4/Controllers/PaymentGateways.php +++ b/src/Controllers/Version4/PaymentGateways.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php b/src/Controllers/Version4/ProductAttributeTerms.php similarity index 99% rename from src/RestApi/Version4/Controllers/ProductAttributeTerms.php rename to src/Controllers/Version4/ProductAttributeTerms.php index bfa6714bef4..eeb20f54edd 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributeTerms.php +++ b/src/Controllers/Version4/ProductAttributeTerms.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php similarity index 99% rename from src/RestApi/Version4/Controllers/ProductAttributes.php rename to src/Controllers/Version4/ProductAttributes.php index cea3491f897..70f955ea928 100644 --- a/src/RestApi/Version4/Controllers/ProductAttributes.php +++ b/src/Controllers/Version4/ProductAttributes.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ProductCategories.php b/src/Controllers/Version4/ProductCategories.php similarity index 99% rename from src/RestApi/Version4/Controllers/ProductCategories.php rename to src/Controllers/Version4/ProductCategories.php index 6e7ff08fd3b..76940158244 100644 --- a/src/RestApi/Version4/Controllers/ProductCategories.php +++ b/src/Controllers/Version4/ProductCategories.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php similarity index 99% rename from src/RestApi/Version4/Controllers/ProductReviews.php rename to src/Controllers/Version4/ProductReviews.php index 7a52f09481a..1a1b87be436 100644 --- a/src/RestApi/Version4/Controllers/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ProductShippingClasses.php b/src/Controllers/Version4/ProductShippingClasses.php similarity index 98% rename from src/RestApi/Version4/Controllers/ProductShippingClasses.php rename to src/Controllers/Version4/ProductShippingClasses.php index d9bc0c8c2de..0df19fc7600 100644 --- a/src/RestApi/Version4/Controllers/ProductShippingClasses.php +++ b/src/Controllers/Version4/ProductShippingClasses.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ProductTags.php b/src/Controllers/Version4/ProductTags.php similarity index 98% rename from src/RestApi/Version4/Controllers/ProductTags.php rename to src/Controllers/Version4/ProductTags.php index a1491bd3c34..ac4b08c586c 100644 --- a/src/RestApi/Version4/Controllers/ProductTags.php +++ b/src/Controllers/Version4/ProductTags.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php similarity index 99% rename from src/RestApi/Version4/Controllers/ProductVariations.php rename to src/Controllers/Version4/ProductVariations.php index f65cf24369d..ab0e9e143af 100644 --- a/src/RestApi/Version4/Controllers/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; @@ -286,7 +286,7 @@ class ProductVariations extends Products { * Set variation image. * * @throws \WC_REST_Exception REST API exceptions. - * + * * @param \WC_Product_Variation $variation Variation instance. * @param array $image Image data. * @return WC_Product_Variation diff --git a/src/RestApi/Version4/Controllers/Products.php b/src/Controllers/Version4/Products.php similarity index 99% rename from src/RestApi/Version4/Controllers/Products.php rename to src/Controllers/Version4/Products.php index 73477850733..1259175b973 100644 --- a/src/RestApi/Version4/Controllers/Products.php +++ b/src/Controllers/Version4/Products.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; @@ -1201,7 +1201,7 @@ class Products extends AbstractObjectsController { * Set product images. * * @throws \WC_REST_Exception REST API exceptions. - * + * * @param WC_Product $product Product instance. * @param array $images Images data. * @return WC_Product diff --git a/src/RestApi/Version4/Controllers/Reports.php b/src/Controllers/Version4/Reports.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports.php rename to src/Controllers/Version4/Reports.php index b187692b9d8..b989bb17dde 100644 --- a/src/RestApi/Version4/Controllers/Reports.php +++ b/src/Controllers/Version4/Reports.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/Reports/Categories.php b/src/Controllers/Version4/Reports/Categories.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/Categories.php rename to src/Controllers/Version4/Reports/Categories.php index 5d69e501b42..1c8a6d65572 100644 --- a/src/RestApi/Version4/Controllers/Reports/Categories.php +++ b/src/Controllers/Version4/Reports/Categories.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Categories Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/CouponStats.php b/src/Controllers/Version4/Reports/CouponStats.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/CouponStats.php rename to src/Controllers/Version4/Reports/CouponStats.php index 5b5bfdb2365..e837f249bc5 100644 --- a/src/RestApi/Version4/Controllers/Reports/CouponStats.php +++ b/src/Controllers/Version4/Reports/CouponStats.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API CouponStats Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Coupons.php b/src/Controllers/Version4/Reports/Coupons.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/Coupons.php rename to src/Controllers/Version4/Reports/Coupons.php index b4567d8168b..959e6b3fc2b 100644 --- a/src/RestApi/Version4/Controllers/Reports/Coupons.php +++ b/src/Controllers/Version4/Reports/Coupons.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Coupons Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php b/src/Controllers/Version4/Reports/CustomerStats.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/CustomerStats.php rename to src/Controllers/Version4/Reports/CustomerStats.php index def364100b1..cb7af69549d 100644 --- a/src/RestApi/Version4/Controllers/Reports/CustomerStats.php +++ b/src/Controllers/Version4/Reports/CustomerStats.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API CustomerStats Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Customers.php b/src/Controllers/Version4/Reports/Customers.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/Customers.php rename to src/Controllers/Version4/Reports/Customers.php index e96c3804a03..8d9dfd89248 100644 --- a/src/RestApi/Version4/Controllers/Reports/Customers.php +++ b/src/Controllers/Version4/Reports/Customers.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Customers Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php b/src/Controllers/Version4/Reports/DownloadStats.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/DownloadStats.php rename to src/Controllers/Version4/Reports/DownloadStats.php index 45e23d85e6f..6d660f7b8a7 100644 --- a/src/RestApi/Version4/Controllers/Reports/DownloadStats.php +++ b/src/Controllers/Version4/Reports/DownloadStats.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API DownloadStats Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Downloads.php b/src/Controllers/Version4/Reports/Downloads.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/Downloads.php rename to src/Controllers/Version4/Reports/Downloads.php index dff4cc63491..f4828e4d7b8 100644 --- a/src/RestApi/Version4/Controllers/Reports/Downloads.php +++ b/src/Controllers/Version4/Reports/Downloads.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Downloads Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Import.php b/src/Controllers/Version4/Reports/Import.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/Import.php rename to src/Controllers/Version4/Reports/Import.php index 10e168e3a53..ea7907617ae 100644 --- a/src/RestApi/Version4/Controllers/Reports/Import.php +++ b/src/Controllers/Version4/Reports/Import.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Import Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/OrderStats.php b/src/Controllers/Version4/Reports/OrderStats.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/OrderStats.php rename to src/Controllers/Version4/Reports/OrderStats.php index 894bde56073..bc3d75b4d6d 100644 --- a/src/RestApi/Version4/Controllers/Reports/OrderStats.php +++ b/src/Controllers/Version4/Reports/OrderStats.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API OrderStats Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Orders.php b/src/Controllers/Version4/Reports/Orders.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/Orders.php rename to src/Controllers/Version4/Reports/Orders.php index 622b4a18763..c4c71a12c9e 100644 --- a/src/RestApi/Version4/Controllers/Reports/Orders.php +++ b/src/Controllers/Version4/Reports/Orders.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Orders Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php b/src/Controllers/Version4/Reports/PerformanceIndicators.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php rename to src/Controllers/Version4/Reports/PerformanceIndicators.php index 7c4dae39174..164b34a2bec 100644 --- a/src/RestApi/Version4/Controllers/Reports/PerformanceIndicators.php +++ b/src/Controllers/Version4/Reports/PerformanceIndicators.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API PerformanceIndicators class. diff --git a/src/RestApi/Version4/Controllers/Reports/ProductStats.php b/src/Controllers/Version4/Reports/ProductStats.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/ProductStats.php rename to src/Controllers/Version4/Reports/ProductStats.php index d68a760e485..caceed9698a 100644 --- a/src/RestApi/Version4/Controllers/Reports/ProductStats.php +++ b/src/Controllers/Version4/Reports/ProductStats.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API ProductStats Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Products.php b/src/Controllers/Version4/Reports/Products.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/Products.php rename to src/Controllers/Version4/Reports/Products.php index ba420c494ec..fd91702dbc7 100644 --- a/src/RestApi/Version4/Controllers/Reports/Products.php +++ b/src/Controllers/Version4/Reports/Products.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Products Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php b/src/Controllers/Version4/Reports/RevenueStats.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/RevenueStats.php rename to src/Controllers/Version4/Reports/RevenueStats.php index 8d58294c2e4..50608095a0f 100644 --- a/src/RestApi/Version4/Controllers/Reports/RevenueStats.php +++ b/src/Controllers/Version4/Reports/RevenueStats.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API RevenueStats Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Stock.php b/src/Controllers/Version4/Reports/Stock.php similarity index 99% rename from src/RestApi/Version4/Controllers/Reports/Stock.php rename to src/Controllers/Version4/Reports/Stock.php index 6bcaeb4d4cd..ab9b601b5bc 100644 --- a/src/RestApi/Version4/Controllers/Reports/Stock.php +++ b/src/Controllers/Version4/Reports/Stock.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Stock Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/StockStats.php b/src/Controllers/Version4/Reports/StockStats.php similarity index 96% rename from src/RestApi/Version4/Controllers/Reports/StockStats.php rename to src/Controllers/Version4/Reports/StockStats.php index db704677959..625f3788abf 100644 --- a/src/RestApi/Version4/Controllers/Reports/StockStats.php +++ b/src/Controllers/Version4/Reports/StockStats.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API StockStats Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/TaxStats.php b/src/Controllers/Version4/Reports/TaxStats.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/TaxStats.php rename to src/Controllers/Version4/Reports/TaxStats.php index 1c816c4d857..5fc4c61963d 100644 --- a/src/RestApi/Version4/Controllers/Reports/TaxStats.php +++ b/src/Controllers/Version4/Reports/TaxStats.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API TaxesStats Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Taxes.php b/src/Controllers/Version4/Reports/Taxes.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/Taxes.php rename to src/Controllers/Version4/Reports/Taxes.php index 9ebc4e29d89..f19b99944d9 100644 --- a/src/RestApi/Version4/Controllers/Reports/Taxes.php +++ b/src/Controllers/Version4/Reports/Taxes.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Taxes Reports class. diff --git a/src/RestApi/Version4/Controllers/Reports/Variations.php b/src/Controllers/Version4/Reports/Variations.php similarity index 98% rename from src/RestApi/Version4/Controllers/Reports/Variations.php rename to src/Controllers/Version4/Reports/Variations.php index 988e40f761e..63a1f6c86ad 100644 --- a/src/RestApi/Version4/Controllers/Reports/Variations.php +++ b/src/Controllers/Version4/Reports/Variations.php @@ -7,11 +7,11 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers\Reports; +namespace WooCommerce\RestApi\Controllers\Version4\Reports; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Version4\Controllers\Reports as Reports; +use \WooCommerce\RestApi\Controllers\Version4\Reports as Reports; /** * REST API Variations Reports class. diff --git a/src/RestApi/Version4/Controllers/Settings.php b/src/Controllers/Version4/Settings.php similarity index 99% rename from src/RestApi/Version4/Controllers/Settings.php rename to src/Controllers/Version4/Settings.php index 68aca43c5be..959437f9f2b 100644 --- a/src/RestApi/Version4/Controllers/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php similarity index 99% rename from src/RestApi/Version4/Controllers/SettingsOptions.php rename to src/Controllers/Version4/SettingsOptions.php index 20f71ed9db4..dbe2c599acf 100644 --- a/src/RestApi/Version4/Controllers/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php similarity index 99% rename from src/RestApi/Version4/Controllers/ShippingMethods.php rename to src/Controllers/Version4/ShippingMethods.php index 529c2f92d53..a829609dbc6 100644 --- a/src/RestApi/Version4/Controllers/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php b/src/Controllers/Version4/ShippingZoneLocations.php similarity index 99% rename from src/RestApi/Version4/Controllers/ShippingZoneLocations.php rename to src/Controllers/Version4/ShippingZoneLocations.php index a6c004695ed..c1f79d92f07 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneLocations.php +++ b/src/Controllers/Version4/ShippingZoneLocations.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php similarity index 99% rename from src/RestApi/Version4/Controllers/ShippingZoneMethods.php rename to src/Controllers/Version4/ShippingZoneMethods.php index d731ad4f45e..717205ff2a8 100644 --- a/src/RestApi/Version4/Controllers/ShippingZoneMethods.php +++ b/src/Controllers/Version4/ShippingZoneMethods.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php similarity index 99% rename from src/RestApi/Version4/Controllers/ShippingZones.php rename to src/Controllers/Version4/ShippingZones.php index 55732940534..1c57fc75133 100644 --- a/src/RestApi/Version4/Controllers/ShippingZones.php +++ b/src/Controllers/Version4/ShippingZones.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php similarity index 99% rename from src/RestApi/Version4/Controllers/SystemStatus.php rename to src/Controllers/Version4/SystemStatus.php index e7da5376d68..654b0ccf7bd 100644 --- a/src/RestApi/Version4/Controllers/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php similarity index 99% rename from src/RestApi/Version4/Controllers/SystemStatusTools.php rename to src/Controllers/Version4/SystemStatusTools.php index 9ec0e03a034..d90f9e72789 100644 --- a/src/RestApi/Version4/Controllers/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/TaxClasses.php b/src/Controllers/Version4/TaxClasses.php similarity index 99% rename from src/RestApi/Version4/Controllers/TaxClasses.php rename to src/Controllers/Version4/TaxClasses.php index 724640dd646..770ad1599d6 100644 --- a/src/RestApi/Version4/Controllers/TaxClasses.php +++ b/src/Controllers/Version4/TaxClasses.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/Taxes.php b/src/Controllers/Version4/Taxes.php similarity index 99% rename from src/RestApi/Version4/Controllers/Taxes.php rename to src/Controllers/Version4/Taxes.php index ca787b552cc..64741ae8328 100644 --- a/src/RestApi/Version4/Controllers/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/RestApi/Version4/Controllers/Webhooks.php b/src/Controllers/Version4/Webhooks.php similarity index 90% rename from src/RestApi/Version4/Controllers/Webhooks.php rename to src/Controllers/Version4/Webhooks.php index e18dab3ff50..c652ad2a951 100644 --- a/src/RestApi/Version4/Controllers/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -7,7 +7,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Version4\Controllers; +namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; @@ -35,7 +35,8 @@ class Webhooks extends AbstractController { */ public function register_routes() { register_rest_route( - $this->namespace, '/' . $this->rest_base, + $this->namespace, + '/' . $this->rest_base, array( array( 'methods' => \WP_REST_Server::READABLE, @@ -47,18 +48,21 @@ class Webhooks extends AbstractController { 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( - 'topic' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Webhook topic.', 'woocommerce' ), - ), - 'delivery_url' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), - ), - ) ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), + array( + 'topic' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook topic.', 'woocommerce' ), + ), + 'delivery_url' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), + ), + ) + ), ), 'schema' => array( $this, 'get_public_item_schema' ), ), @@ -66,9 +70,10 @@ class Webhooks extends AbstractController { ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( + 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', @@ -106,7 +111,8 @@ class Webhooks extends AbstractController { ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', + $this->namespace, + '/' . $this->rest_base . '/batch', array( array( 'methods' => \WP_REST_Server::EDITABLE, @@ -251,13 +257,13 @@ class Webhooks extends AbstractController { $prepared_args['paginate'] = true; // Get the webhooks. - $webhooks = array(); - $data_store = \WC_Data_Store::load( 'webhook' ); - $results = $data_store->search_webhooks( $prepared_args ); - $webhook_ids = $results->webhooks; + $webhooks = array(); + $data_store = \WC_Data_Store::load( 'webhook' ); + $results = $data_store->search_webhooks( $prepared_args ); + $webhook_ids = $results->webhooks; foreach ( $webhook_ids as $webhook_id ) { - $data = $this->prepare_item_for_response( $webhook_id, $request ); + $data = $this->prepare_item_for_response( $webhook_id, $request ); $webhooks[] = $this->prepare_response_for_collection( $data ); } @@ -353,7 +359,7 @@ class Webhooks extends AbstractController { * @param \WP_REST_Request $request Request object. * @param bool $creating True when creating item, false when updating. */ - do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, true ); + do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, true ); $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); @@ -433,7 +439,7 @@ class Webhooks extends AbstractController { * @param \WP_REST_Request $request Request object. * @param bool $creating True when creating item, false when updating. */ - do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, false ); + do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, false ); $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); @@ -496,7 +502,7 @@ class Webhooks extends AbstractController { * @return \WP_Error|stdClass $data Post object. */ protected function prepare_item_for_database( $request ) { - $data = new \stdClass; + $data = new \stdClass(); // Post ID. if ( isset( $request['id'] ) ) { @@ -545,7 +551,7 @@ class Webhooks extends AbstractController { /** * Prepare a single webhook output for response. * - * @param int $id Webhook ID. + * @param int $id Webhook ID. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response */ @@ -598,7 +604,7 @@ class Webhooks extends AbstractController { */ protected function prepare_links( $id ) { $links = array( - 'self' => array( + 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $id ) ), ), 'collection' => array( @@ -716,23 +722,23 @@ class Webhooks extends AbstractController { $params['context']['default'] = 'view'; - $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['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['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['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + 'type' => 'integer', ), 'default' => array(), 'sanitize_callback' => 'wp_parse_id_list', @@ -741,36 +747,36 @@ class Webhooks extends AbstractController { 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + '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['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' => 'desc', - 'enum' => array( 'asc', 'desc' ), - '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( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( 'date', 'id', 'title', ), - 'validate_callback' => 'rest_validate_request_arg', + 'validate_callback' => 'rest_validate_request_arg', ); - $params['status'] = array( + $params['status'] = array( 'default' => 'all', 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce' ), 'type' => 'string', diff --git a/src/RestApi/Version4/changelog.md b/src/Controllers/Version4/_changelog.md similarity index 100% rename from src/RestApi/Version4/changelog.md rename to src/Controllers/Version4/_changelog.md diff --git a/src/RestApi.php b/src/RestApi.php deleted file mode 100644 index 3ccfaff8e63..00000000000 --- a/src/RestApi.php +++ /dev/null @@ -1,91 +0,0 @@ -get_rest_namespaces() as $namespace => $namespace_class ) { - $controllers = $namespace_class::get_controllers(); - - foreach ( $controllers as $controller_name => $controller_class ) { - $this->controllers[ $namespace ][ $controller_name ] = new $controller_class(); - $this->controllers[ $namespace ][ $controller_name ]->register_routes(); - } - } - } - - /** - * Get API namespaces - new namespaces should be registered here. - * - * @return array List of Namespaces and Main controller classes. - */ - protected function get_rest_namespaces() { - return apply_filters( - 'woocommerce_rest_api_get_rest_namespaces', - [ - 'wc/v1' => 'WC_REST_Controllers_V1', - 'wc/v2' => 'WC_REST_Controllers_V2', - 'wc/v3' => 'WC_REST_Controllers_V3', - 'wc/v4' => '\WooCommerce\RestApi\Version4\Controllers', - ] - ); - } - - /** - * Get data from a WooCommerce API endpoint. - * - * @param string $endpoint Endpoint. - * @param array $params Params to passwith request. - * @return array|WP_Error - */ - public function get_endpoint_data( $endpoint, $params = array() ) { - $request = new \WP_REST_Request( 'GET', $endpoint ); - - if ( $params ) { - $request->set_query_params( $params ); - } - - $response = \rest_do_request( $request ); - $server = \rest_get_server(); - $json = wp_json_encode( $server->response_to_data( $response, false ) ); - - return json_decode( $json, true ); - } -} diff --git a/src/RestApi/Version1/class-wc-rest-controllers-v1.php b/src/RestApi/Version1/class-wc-rest-controllers-v1.php deleted file mode 100644 index e4f468d4c25..00000000000 --- a/src/RestApi/Version1/class-wc-rest-controllers-v1.php +++ /dev/null @@ -1,43 +0,0 @@ - 'WC_REST_Coupons_V1_Controller', - 'customer-downloads' => 'WC_REST_Customer_Downloads_V1_Controller', - 'customers' => 'WC_REST_Customers_V1_Controller', - 'order-notes' => 'WC_REST_Order_Notes_V1_Controller', - 'order-refunds' => 'WC_REST_Order_Refunds_V1_Controller', - 'orders' => 'WC_REST_Orders_V1_Controller', - 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V1_Controller', - 'product-attributes' => 'WC_REST_Product_Attributes_V1_Controller', - 'product-categories' => 'WC_REST_Product_Categories_V1_Controller', - 'product-reviews' => 'WC_REST_Product_Reviews_V1_Controller', - 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V1_Controller', - 'product-tags' => 'WC_REST_Product_Tags_V1_Controller', - 'products' => 'WC_REST_Products_V1_Controller', - 'reports-sales' => 'WC_REST_Report_Sales_V1_Controller', - 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V1_Controller', - 'reports' => 'WC_REST_Reports_V1_Controller', - 'tax-classes' => 'WC_REST_Tax_Classes_V1_Controller', - 'taxes' => 'WC_REST_Taxes_V1_Controller', - 'webhooks' => 'WC_REST_Webhooks_V1_Controller', - 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V1_Controller', - ]; - } -} diff --git a/src/RestApi/Version2/class-wc-rest-controllers-v2.php b/src/RestApi/Version2/class-wc-rest-controllers-v2.php deleted file mode 100644 index 6a1d6a9de63..00000000000 --- a/src/RestApi/Version2/class-wc-rest-controllers-v2.php +++ /dev/null @@ -1,54 +0,0 @@ - 'WC_REST_Coupons_V2_Controller', - 'customer-downloads' => 'WC_REST_Customer_Downloads_V2_Controller', - 'customers' => 'WC_REST_Customers_V2_Controller', - 'network-orders' => 'WC_REST_Network_Orders_V2_Controller', - 'order-notes' => 'WC_REST_Order_Notes_V2_Controller', - 'order-refunds' => 'WC_REST_Order_Refunds_V2_Controller', - 'orders' => 'WC_REST_Orders_V2_Controller', - 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V2_Controller', - 'product-attributes' => 'WC_REST_Product_Attributes_V2_Controller', - 'product-categories' => 'WC_REST_Product_Categories_V2_Controller', - 'product-reviews' => 'WC_REST_Product_Reviews_V2_Controller', - 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V2_Controller', - 'product-tags' => 'WC_REST_Product_Tags_V2_Controller', - 'products' => 'WC_REST_Products_V2_Controller', - 'product-variations' => 'WC_REST_Product_Variations_V2_Controller', - 'reports-sales' => 'WC_REST_Report_Sales_V2_Controller', - 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V2_Controller', - 'reports' => 'WC_REST_Reports_V2_Controller', - 'settings' => 'WC_REST_Settings_V2_Controller', - 'settings-options' => 'WC_REST_Setting_Options_V2_Controller', - 'shipping-zones' => 'WC_REST_Shipping_Zones_V2_Controller', - 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_V2_Controller', - 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_V2_Controller', - 'tax-classes' => 'WC_REST_Tax_Classes_V2_Controller', - 'taxes' => 'WC_REST_Taxes_V2_Controller', - 'webhooks' => 'WC_REST_Webhooks_V2_Controller', - 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V2_Controller', - 'system-status' => 'WC_REST_System_Status_V2_Controller', - 'system-status-tools' => 'WC_REST_System_Status_Tools_V2_Controller', - 'shipping-methods' => 'WC_REST_Shipping_Methods_V2_Controller', - 'payment-gateways' => 'WC_REST_Payment_Gateways_V2_Controller', - ]; - } -} diff --git a/src/RestApi/Version3/class-wc-rest-controllers-v3.php b/src/RestApi/Version3/class-wc-rest-controllers-v3.php deleted file mode 100644 index 50f968afa22..00000000000 --- a/src/RestApi/Version3/class-wc-rest-controllers-v3.php +++ /dev/null @@ -1,62 +0,0 @@ - 'WC_REST_Coupons_Controller', - 'customer-downloads' => 'WC_REST_Customer_Downloads_Controller', - 'customers' => 'WC_REST_Customers_Controller', - 'network-orders' => 'WC_REST_Network_Orders_Controller', - 'order-notes' => 'WC_REST_Order_Notes_Controller', - 'order-refunds' => 'WC_REST_Order_Refunds_Controller', - 'orders' => 'WC_REST_Orders_Controller', - 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_Controller', - 'product-attributes' => 'WC_REST_Product_Attributes_Controller', - 'product-categories' => 'WC_REST_Product_Categories_Controller', - 'product-reviews' => 'WC_REST_Product_Reviews_Controller', - 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_Controller', - 'product-tags' => 'WC_REST_Product_Tags_Controller', - 'products' => 'WC_REST_Products_Controller', - 'product-variations' => 'WC_REST_Product_Variations_Controller', - 'reports-sales' => 'WC_REST_Report_Sales_Controller', - 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_Controller', - 'reports-orders-totals' => 'WC_REST_Report_Orders_Totals_Controller', - 'reports-products-totals' => 'WC_REST_Report_Products_Totals_Controller', - 'reports-customers-totals' => 'WC_REST_Report_Customers_Totals_Controller', - 'reports-coupons-totals' => 'WC_REST_Report_Coupons_Totals_Controller', - 'reports-reviews-totals' => 'WC_REST_Report_Reviews_Totals_Controller', - 'reports' => 'WC_REST_Reports_Controller', - 'settings' => 'WC_REST_Settings_Controller', - 'settings-options' => 'WC_REST_Setting_Options_Controller', - 'shipping-zones' => 'WC_REST_Shipping_Zones_Controller', - 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_Controller', - 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_Controller', - 'tax-classes' => 'WC_REST_Tax_Classes_Controller', - 'taxes' => 'WC_REST_Taxes_Controller', - 'webhooks' => 'WC_REST_Webhooks_Controller', - 'system-status' => 'WC_REST_System_Status_Controller', - 'system-status-tools' => 'WC_REST_System_Status_Tools_Controller', - 'shipping-methods' => 'WC_REST_Shipping_Methods_Controller', - 'payment-gateways' => 'WC_REST_Payment_Gateways_Controller', - 'data' => 'WC_REST_Data_Controller', - 'data-continents' => 'WC_REST_Data_Continents_Controller', - 'data-countries' => 'WC_REST_Data_Countries_Controller', - 'data-currencies' => 'WC_REST_Data_Currencies_Controller', - ]; - } -} diff --git a/src/RestApi/Version4/Controllers.php b/src/RestApi/Version4/Controllers.php deleted file mode 100644 index 703a3ee0b54..00000000000 --- a/src/RestApi/Version4/Controllers.php +++ /dev/null @@ -1,87 +0,0 @@ - __NAMESPACE__ . '\Controllers\Coupons', - 'customer-downloads' => __NAMESPACE__ . '\Controllers\CustomerDownloads', - 'customers' => __NAMESPACE__ . '\Controllers\Customers', - 'data' => __NAMESPACE__ . '\Controllers\Data', - 'data-continents' => __NAMESPACE__ . '\Controllers\Data\Continents', - 'data-countries' => __NAMESPACE__ . '\Controllers\Data\Countries', - 'data-currencies' => __NAMESPACE__ . '\Controllers\Data\Currencies', - 'data-download-ips' => __NAMESPACE__ . '\Controllers\Data\DownloadIPs', - 'leaderboards' => __NAMESPACE__ . '\Controllers\Leaderboards', - 'network-orders' => __NAMESPACE__ . '\Controllers\NetworkOrders', - 'order-notes' => __NAMESPACE__ . '\Controllers\OrderNotes', - 'order-refunds' => __NAMESPACE__ . '\Controllers\OrderRefunds', - 'orders' => __NAMESPACE__ . '\Controllers\Orders', - 'payment-gateways' => __NAMESPACE__ . '\Controllers\PaymentGateways', - 'product-attributes' => __NAMESPACE__ . '\Controllers\ProductAttributes', - 'product-attribute-terms' => __NAMESPACE__ . '\Controllers\ProductAttributeTerms', - 'product-categories' => __NAMESPACE__ . '\Controllers\ProductCategories', - 'product-reviews' => __NAMESPACE__ . '\Controllers\ProductReviews', - 'products' => __NAMESPACE__ . '\Controllers\Products', - 'product-shipping-classes' => __NAMESPACE__ . '\Controllers\ProductShippingClasses', - 'product-tags' => __NAMESPACE__ . '\Controllers\ProductTags', - 'product-variations' => __NAMESPACE__ . '\Controllers\ProductVariations', - 'reports' => __NAMESPACE__ . '\Controllers\Reports', - 'settings' => __NAMESPACE__ . '\Controllers\Settings', - 'settings-options' => __NAMESPACE__ . '\Controllers\SettingsOptions', - 'shipping-methods' => __NAMESPACE__ . '\Controllers\ShippingMethods', - 'shipping-zone-locations' => __NAMESPACE__ . '\Controllers\ShippingZoneLocations', - 'shipping-zone-methods' => __NAMESPACE__ . '\Controllers\ShippingZoneMethods', - 'shipping-zones' => __NAMESPACE__ . '\Controllers\ShippingZones', - 'system-status' => __NAMESPACE__ . '\Controllers\SystemStatus', - 'system-status-tools' => __NAMESPACE__ . '\Controllers\SystemStatusTools', - 'tax-classes' => __NAMESPACE__ . '\Controllers\TaxClasses', - 'taxes' => __NAMESPACE__ . '\Controllers\Taxes', - 'webhooks' => __NAMESPACE__ . '\Controllers\Webhooks', - ]; - - if ( class_exists( '\WC_Admin_Note' ) ) { - $controllers['admin-notes'] = __NAMESPACE__ . '\Controllers\AdminNotes'; - } - - if ( class_exists( '\WC_Admin_Reports_Sync' ) ) { - $controllers['reports-categories'] = __NAMESPACE__ . '\Controllers\Reports\Categories'; - $controllers['reports-coupons'] = __NAMESPACE__ . '\Controllers\Reports\Coupons'; - $controllers['reports-coupon-stats'] = __NAMESPACE__ . '\Controllers\Reports\CouponStats'; - $controllers['reports-customers'] = __NAMESPACE__ . '\Controllers\Reports\Customers'; - $controllers['reports-customer-stats'] = __NAMESPACE__ . '\Controllers\Reports\CustomerStats'; - $controllers['reports-downloads'] = __NAMESPACE__ . '\Controllers\Reports\Downloads'; - $controllers['reports-download-stats'] = __NAMESPACE__ . '\Controllers\Reports\DownloadStats'; - $controllers['reports-import'] = __NAMESPACE__ . '\Controllers\Reports\Import'; - $controllers['reports-orders'] = __NAMESPACE__ . '\Controllers\Reports\Orders'; - $controllers['reports-order-stats'] = __NAMESPACE__ . '\Controllers\Reports\OrderStats'; - $controllers['reports-performance-indicators'] = __NAMESPACE__ . '\Controllers\Reports\PerformanceIndicators'; - $controllers['reports-products'] = __NAMESPACE__ . '\Controllers\Reports\Products'; - $controllers['reports-product-stats'] = __NAMESPACE__ . '\Controllers\Reports\ProductStats'; - $controllers['reports-revenue-stats'] = __NAMESPACE__ . '\Controllers\Reports\RevenueStats'; - $controllers['reports-stock'] = __NAMESPACE__ . '\Controllers\Reports\Stock'; - $controllers['reports-stock-stats'] = __NAMESPACE__ . '\Controllers\Reports\StockStats'; - $controllers['reports-taxes'] = __NAMESPACE__ . '\Controllers\Reports\Taxes'; - $controllers['reports-tax-stats'] = __NAMESPACE__ . '\Controllers\Reports\TaxStats'; - $controllers['reports-variations'] = __NAMESPACE__ . '\Controllers\Reports\Variations'; - } - - return $controllers; - } -} diff --git a/src/Server.php b/src/Server.php new file mode 100644 index 00000000000..19164810338 --- /dev/null +++ b/src/Server.php @@ -0,0 +1,282 @@ +get_rest_namespaces() as $namespace => $controllers ) { + foreach ( $controllers as $controller_name => $controller_class ) { + $this->controllers[ $namespace ][ $controller_name ] = new $controller_class(); + $this->controllers[ $namespace ][ $controller_name ]->register_routes(); + } + } + } + + /** + * Get data from a WooCommerce API endpoint. + * + * @param string $endpoint Endpoint. + * @param array $params Params to passwith request. + * @return array|WP_Error + */ + public function get_endpoint_data( $endpoint, $params = array() ) { + $request = new \WP_REST_Request( 'GET', $endpoint ); + + if ( $params ) { + $request->set_query_params( $params ); + } + + $response = \rest_do_request( $request ); + $server = \rest_get_server(); + $json = wp_json_encode( $server->response_to_data( $response, false ) ); + + return json_decode( $json, true ); + } + + /** + * Get API namespaces - new namespaces should be registered here. + * + * @return array List of Namespaces and Main controller classes. + */ + protected function get_rest_namespaces() { + return apply_filters( + 'woocommerce_rest_api_get_rest_namespaces', + [ + 'wc/v1' => $this->get_v1_controllers(), + 'wc/v2' => $this->get_v2_controllers(), + 'wc/v3' => $this->get_v3_controllers(), + 'wc/v4' => $this->get_v4_controllers(), + ] + ); + } + + /** + * List of controllers in the wc/v1 namespace. + * + * @return array + */ + protected function get_v1_controllers() { + return [ + 'coupons' => 'WC_REST_Coupons_V1_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_V1_Controller', + 'customers' => 'WC_REST_Customers_V1_Controller', + 'order-notes' => 'WC_REST_Order_Notes_V1_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_V1_Controller', + 'orders' => 'WC_REST_Orders_V1_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V1_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_V1_Controller', + 'product-categories' => 'WC_REST_Product_Categories_V1_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_V1_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V1_Controller', + 'product-tags' => 'WC_REST_Product_Tags_V1_Controller', + 'products' => 'WC_REST_Products_V1_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_V1_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V1_Controller', + 'reports' => 'WC_REST_Reports_V1_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_V1_Controller', + 'taxes' => 'WC_REST_Taxes_V1_Controller', + 'webhooks' => 'WC_REST_Webhooks_V1_Controller', + 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V1_Controller', + ]; + } + + /** + * List of controllers in the wc/v2 namespace. + * + * @return array + */ + protected function get_v2_controllers() { + return [ + 'coupons' => 'WC_REST_Coupons_V2_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_V2_Controller', + 'customers' => 'WC_REST_Customers_V2_Controller', + 'network-orders' => 'WC_REST_Network_Orders_V2_Controller', + 'order-notes' => 'WC_REST_Order_Notes_V2_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_V2_Controller', + 'orders' => 'WC_REST_Orders_V2_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V2_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_V2_Controller', + 'product-categories' => 'WC_REST_Product_Categories_V2_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_V2_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V2_Controller', + 'product-tags' => 'WC_REST_Product_Tags_V2_Controller', + 'products' => 'WC_REST_Products_V2_Controller', + 'product-variations' => 'WC_REST_Product_Variations_V2_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_V2_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V2_Controller', + 'reports' => 'WC_REST_Reports_V2_Controller', + 'settings' => 'WC_REST_Settings_V2_Controller', + 'settings-options' => 'WC_REST_Setting_Options_V2_Controller', + 'shipping-zones' => 'WC_REST_Shipping_Zones_V2_Controller', + 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_V2_Controller', + 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_V2_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_V2_Controller', + 'taxes' => 'WC_REST_Taxes_V2_Controller', + 'webhooks' => 'WC_REST_Webhooks_V2_Controller', + 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V2_Controller', + 'system-status' => 'WC_REST_System_Status_V2_Controller', + 'system-status-tools' => 'WC_REST_System_Status_Tools_V2_Controller', + 'shipping-methods' => 'WC_REST_Shipping_Methods_V2_Controller', + 'payment-gateways' => 'WC_REST_Payment_Gateways_V2_Controller', + ]; + } + + /** + * List of controllers in the wc/v3 namespace. + * + * @return array + */ + protected function get_v3_controllers() { + return [ + 'coupons' => 'WC_REST_Coupons_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_Controller', + 'customers' => 'WC_REST_Customers_Controller', + 'network-orders' => 'WC_REST_Network_Orders_Controller', + 'order-notes' => 'WC_REST_Order_Notes_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_Controller', + 'orders' => 'WC_REST_Orders_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_Controller', + 'product-categories' => 'WC_REST_Product_Categories_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_Controller', + 'product-tags' => 'WC_REST_Product_Tags_Controller', + 'products' => 'WC_REST_Products_Controller', + 'product-variations' => 'WC_REST_Product_Variations_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_Controller', + 'reports-orders-totals' => 'WC_REST_Report_Orders_Totals_Controller', + 'reports-products-totals' => 'WC_REST_Report_Products_Totals_Controller', + 'reports-customers-totals' => 'WC_REST_Report_Customers_Totals_Controller', + 'reports-coupons-totals' => 'WC_REST_Report_Coupons_Totals_Controller', + 'reports-reviews-totals' => 'WC_REST_Report_Reviews_Totals_Controller', + 'reports' => 'WC_REST_Reports_Controller', + 'settings' => 'WC_REST_Settings_Controller', + 'settings-options' => 'WC_REST_Setting_Options_Controller', + 'shipping-zones' => 'WC_REST_Shipping_Zones_Controller', + 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_Controller', + 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_Controller', + 'taxes' => 'WC_REST_Taxes_Controller', + 'webhooks' => 'WC_REST_Webhooks_Controller', + 'system-status' => 'WC_REST_System_Status_Controller', + 'system-status-tools' => 'WC_REST_System_Status_Tools_Controller', + 'shipping-methods' => 'WC_REST_Shipping_Methods_Controller', + 'payment-gateways' => 'WC_REST_Payment_Gateways_Controller', + 'data' => 'WC_REST_Data_Controller', + 'data-continents' => 'WC_REST_Data_Continents_Controller', + 'data-countries' => 'WC_REST_Data_Countries_Controller', + 'data-currencies' => 'WC_REST_Data_Currencies_Controller', + ]; + } + + /** + * List of controllers in the wc/v4 namespace. + * + * @return array + */ + protected function get_v4_controllers() { + $namespace = __NAMESPACE__ . '\\Controllers\\Version4\\'; + $controllers = [ + 'coupons' => $namespace . 'Coupons', + 'customer-downloads' => $namespace . 'CustomerDownloads', + 'customers' => $namespace . 'Customers', + 'data' => $namespace . 'Data', + 'data-continents' => $namespace . 'Data\Continents', + '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', + 'orders' => $namespace . 'Orders', + 'payment-gateways' => $namespace . 'PaymentGateways', + 'product-attributes' => $namespace . 'ProductAttributes', + 'product-attribute-terms' => $namespace . 'ProductAttributeTerms', + 'product-categories' => $namespace . 'ProductCategories', + 'product-reviews' => $namespace . 'ProductReviews', + 'products' => $namespace . 'Products', + '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', + 'shipping-zone-locations' => $namespace . 'ShippingZoneLocations', + 'shipping-zone-methods' => $namespace . 'ShippingZoneMethods', + 'shipping-zones' => $namespace . 'ShippingZones', + 'system-status' => $namespace . 'SystemStatus', + 'system-status-tools' => $namespace . 'SystemStatusTools', + 'tax-classes' => $namespace . 'TaxClasses', + 'taxes' => $namespace . 'Taxes', + '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; + } +} diff --git a/src/Utilities/SingletonTrait.php b/src/Utilities/SingletonTrait.php index e39c1e35998..e51b76f4b59 100644 --- a/src/Utilities/SingletonTrait.php +++ b/src/Utilities/SingletonTrait.php @@ -2,12 +2,10 @@ /** * Abstract singleton class. * - * TODO: move to core? - * * @package WooCommerce/Utilities */ -namespace WooCommerce\Utilities; +namespace WooCommerce\RestApi\Utilities; /** * Singleton trait. diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index bab9057189e..747afe884eb 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -8,7 +8,7 @@ namespace WooCommerce\RestApi\UnitTests; require __DIR__ . '/../src/Utilities/SingletonTrait.php'; -use WooCommerce\Utilities\SingletonTrait; +use WooCommerce\RestApi\Utilities\SingletonTrait; class Bootstrap { use SingletonTrait; @@ -33,7 +33,7 @@ class Bootstrap { * @var string */ protected $wc_tests_dir; - + /** * This plugin directory. * @@ -79,15 +79,6 @@ class Bootstrap { return dirname( __FILE__ ); } - /** - * Does WC Admin exist? - * - * @return boolean - */ - protected function wc_admin_exists() { - return file_exists( $this->plugins_dir . '/woocommerce-admin/woocommerce-admin.php' ); - } - /** * Setup hooks. */ @@ -98,10 +89,6 @@ class Bootstrap { \tests_add_filter( 'muplugins_loaded', function() { require_once $this->plugins_dir . '/woocommerce/woocommerce.php'; require_once $this->plugin_dir . '/woocommerce-rest-api.php'; - - if ( $this->wc_admin_exists() ) { - require_once $this->plugins_dir . '/woocommerce-admin/woocommerce-admin.php'; - } } ); \tests_add_filter( 'setup_theme', function() { @@ -113,13 +100,6 @@ class Bootstrap { \WC_Install::install(); - if ( $this->wc_admin_exists() ) { - echo esc_html( 'Installing WooCommerce Admin...' . PHP_EOL ); - require_once $this->plugins_dir . '/woocommerce-admin/includes/class-wc-admin-install.php'; - \WC_Admin_Install::create_tables(); - \WC_Admin_Install::create_events(); - } - $GLOBALS['wp_roles'] = null; // WPCS: override ok. \wp_roles(); } ); diff --git a/version.php b/version.php index 7299ee74106..e26da460584 100644 --- a/version.php +++ b/version.php @@ -5,4 +5,4 @@ * @package WooCommerce/RestApi */ -return '1.1.1'; +return '1.0.0'; From e45cd8addfe56866011b361a8313fac4d213d7a5 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 13:17:16 +0100 Subject: [PATCH 098/440] get_endpoint_data should be in core --- src/Server.php | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/Server.php b/src/Server.php index 19164810338..11a58b05630 100644 --- a/src/Server.php +++ b/src/Server.php @@ -49,27 +49,6 @@ class Server { } } - /** - * Get data from a WooCommerce API endpoint. - * - * @param string $endpoint Endpoint. - * @param array $params Params to passwith request. - * @return array|WP_Error - */ - public function get_endpoint_data( $endpoint, $params = array() ) { - $request = new \WP_REST_Request( 'GET', $endpoint ); - - if ( $params ) { - $request->set_query_params( $params ); - } - - $response = \rest_do_request( $request ); - $server = \rest_get_server(); - $json = wp_json_encode( $server->response_to_data( $response, false ) ); - - return json_decode( $json, true ); - } - /** * Get API namespaces - new namespaces should be registered here. * From 4a860656c5911c650177edecfdcb136c0faf6538 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 13:17:26 +0100 Subject: [PATCH 099/440] Disable leaderboard tests if admin is not installed --- unit-tests/Tests/Version4/Leaderboards.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/unit-tests/Tests/Version4/Leaderboards.php b/unit-tests/Tests/Version4/Leaderboards.php index 4afb7185997..af90d308365 100644 --- a/unit-tests/Tests/Version4/Leaderboards.php +++ b/unit-tests/Tests/Version4/Leaderboards.php @@ -47,6 +47,10 @@ class Leaderboards extends WC_REST_Unit_Test_Case { * Setup our test server, endpoints, and user info. */ public function setUp() { + if ( ! class_exists( '\WC_Admin_Reports_Sync' ) ) { + $this->markTestSkipped( 'Skipping reports tests - WC_Admin_Reports_Sync class not found.' ); + return; + } parent::setUp(); wp_set_current_user( self::$user ); } From 7495fa71b516aa8eac2c599f04aa45aae6780213 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 16:09:18 +0100 Subject: [PATCH 100/440] Remove wc-admin endpoints --- src/Controllers/Version4/AdminNotes.php | 485 ---------------- src/Controllers/Version4/Leaderboards.php | 545 ------------------ .../Version4/Reports/Categories.php | 314 ---------- .../Version4/Reports/CouponStats.php | 346 ----------- src/Controllers/Version4/Reports/Coupons.php | 284 --------- .../Version4/Reports/CustomerStats.php | 359 ------------ .../Version4/Reports/Customers.php | 511 ---------------- .../Version4/Reports/DownloadStats.php | 366 ------------ .../Version4/Reports/Downloads.php | 374 ------------ src/Controllers/Version4/Reports/Import.php | 310 ---------- .../Version4/Reports/OrderStats.php | 487 ---------------- src/Controllers/Version4/Reports/Orders.php | 371 ------------ .../Reports/PerformanceIndicators.php | 499 ---------------- .../Version4/Reports/ProductStats.php | 410 ------------- src/Controllers/Version4/Reports/Products.php | 338 ----------- .../Version4/Reports/RevenueStats.php | 396 ------------- src/Controllers/Version4/Reports/Stock.php | 413 ------------- .../Version4/Reports/StockStats.php | 132 ----- src/Controllers/Version4/Reports/TaxStats.php | 385 ------------- src/Controllers/Version4/Reports/Taxes.php | 282 --------- .../Version4/Reports/Variations.php | 322 ----------- src/Controllers/Version4/_changelog.md | 20 - src/Server.php | 28 - 23 files changed, 7977 deletions(-) delete mode 100644 src/Controllers/Version4/AdminNotes.php delete mode 100644 src/Controllers/Version4/Leaderboards.php delete mode 100644 src/Controllers/Version4/Reports/Categories.php delete mode 100644 src/Controllers/Version4/Reports/CouponStats.php delete mode 100644 src/Controllers/Version4/Reports/Coupons.php delete mode 100644 src/Controllers/Version4/Reports/CustomerStats.php delete mode 100644 src/Controllers/Version4/Reports/Customers.php delete mode 100644 src/Controllers/Version4/Reports/DownloadStats.php delete mode 100644 src/Controllers/Version4/Reports/Downloads.php delete mode 100644 src/Controllers/Version4/Reports/Import.php delete mode 100644 src/Controllers/Version4/Reports/OrderStats.php delete mode 100644 src/Controllers/Version4/Reports/Orders.php delete mode 100644 src/Controllers/Version4/Reports/PerformanceIndicators.php delete mode 100644 src/Controllers/Version4/Reports/ProductStats.php delete mode 100644 src/Controllers/Version4/Reports/Products.php delete mode 100644 src/Controllers/Version4/Reports/RevenueStats.php delete mode 100644 src/Controllers/Version4/Reports/Stock.php delete mode 100644 src/Controllers/Version4/Reports/StockStats.php delete mode 100644 src/Controllers/Version4/Reports/TaxStats.php delete mode 100644 src/Controllers/Version4/Reports/Taxes.php delete mode 100644 src/Controllers/Version4/Reports/Variations.php 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; } } From 2c1094eae971183c0acc7d77de36c0821a4a7ef6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 16:55:43 +0100 Subject: [PATCH 101/440] Include autoloader in source control --- .gitignore | 4 +- composer.json | 3 - composer.lock | 425 +++-- vendor/autoload.php | 7 + vendor/composer/ClassLoader.php | 445 ++++++ vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 646 ++++++++ vendor/composer/autoload_files.php | 11 + vendor/composer/autoload_namespaces.php | 10 + vendor/composer/autoload_psr4.php | 16 + vendor/composer/autoload_real.php | 70 + vendor/composer/autoload_static.php | 729 +++++++++ vendor/composer/installed.json | 1954 +++++++++++++++++++++++ 13 files changed, 4243 insertions(+), 98 deletions(-) create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_files.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.json diff --git a/.gitignore b/.gitignore index b19a8d1f0ae..7ff207eee11 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,6 @@ Thumbs.db /logs # composer -vendor/ +vendor/* +!vendor/autoload.php +!vendor/composer/ diff --git a/composer.json b/composer.json index 419524bc60e..3a71677b536 100644 --- a/composer.json +++ b/composer.json @@ -6,9 +6,6 @@ "license": "GPL-3.0-or-later", "prefer-stable": true, "minimum-stability": "dev", - "require" : { - "composer/installers" : "~1.0" - }, "require-dev": { "phpunit/phpunit": "6.5.14", "woocommerce/woocommerce-sniffs": "0.0.6" diff --git a/composer.lock b/composer.lock index f5d62d80d4d..b6abe1a4fcc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,43 +4,40 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "353feb9c7787bea5fd95861d54bca06a", - "packages": [ + "content-hash": "5ccf61a66c975a3a1861e095855c10e4", + "packages": [], + "packages-dev": [ { - "name": "composer/installers", - "version": "v1.6.0", + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.5.0", "source": { "type": "git", - "url": "https://github.com/composer/installers.git", - "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b" + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "e749410375ff6fb7a040a68878c656c2e610b132" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b", - "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132", + "reference": "e749410375ff6fb7a040a68878c656c2e610b132", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0" - }, - "replace": { - "roundcube/plugin-installer": "*", - "shama/baton": "*" + "composer-plugin-api": "^1.0", + "php": "^5.3|^7", + "squizlabs/php_codesniffer": "^2|^3" }, "require-dev": { - "composer/composer": "1.0.*@dev", - "phpunit/phpunit": "^4.8.36" + "composer/composer": "*", + "phpcompatibility/php-compatibility": "^9.0", + "sensiolabs/security-checker": "^4.1.0" }, "type": "composer-plugin", "extra": { - "class": "Composer\\Installers\\Plugin", - "branch-alias": { - "dev-master": "1.0-dev" - } + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, "autoload": { "psr-4": { - "Composer\\Installers\\": "src/Composer/Installers" + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -49,85 +46,33 @@ ], "authors": [ { - "name": "Kyle Robinson Young", - "email": "kyle@dontkry.com", - "homepage": "https://github.com/shama" + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" } ], - "description": "A multi-framework Composer library installer", - "homepage": "https://composer.github.io/installers/", + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", "keywords": [ - "Craft", - "Dolibarr", - "Eliasis", - "Hurad", - "ImageCMS", - "Kanboard", - "Lan Management System", - "MODX Evo", - "Mautic", - "Maya", - "OXID", - "Plentymarkets", - "Porto", - "RadPHP", - "SMF", - "Thelia", - "WolfCMS", - "agl", - "aimeos", - "annotatecms", - "attogram", - "bitrix", - "cakephp", - "chef", - "cockpit", - "codeigniter", - "concrete5", - "croogo", - "dokuwiki", - "drupal", - "eZ Platform", - "elgg", - "expressionengine", - "fuelphp", - "grav", + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", "installer", - "itop", - "joomla", - "kohana", - "laravel", - "lavalite", - "lithium", - "magento", - "majima", - "mako", - "mediawiki", - "modulework", - "modx", - "moodle", - "osclass", - "phpbb", - "piwik", - "ppi", - "puppet", - "pxcms", - "reindex", - "roundcube", - "shopware", - "silverstripe", - "sydes", - "symfony", - "typo3", - "wordpress", - "yawik", - "zend", - "zikula" + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" ], - "time": "2018-08-27T06:10:37+00:00" - } - ], - "packages-dev": [ + "time": "2018-10-26T13:21:45+00:00" + }, { "name": "doctrine/instantiator", "version": "1.2.0", @@ -334,6 +279,164 @@ "description": "Library for handling version information and constraints", "time": "2017-03-05T17:38:23+00:00" }, + { + "name": "phpcompatibility/php-compatibility", + "version": "9.1.1", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", + "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/2b63c5d284ab8857f7b1d5c240ddb507a6b2293c", + "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" + }, + "conflict": { + "squizlabs/php_codesniffer": "2.6.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Contributors", + "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" + }, + { + "name": "Wim Godden", + "homepage": "https://github.com/wimg", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + } + ], + "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", + "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", + "keywords": [ + "compatibility", + "phpcs", + "standards" + ], + "time": "2018-12-30T23:16:27+00:00" + }, + { + "name": "phpcompatibility/phpcompatibility-paragonie", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", + "reference": "9160de79fcd683b5c99e9c4133728d91529753ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/9160de79fcd683b5c99e9c4133728d91529753ea", + "reference": "9160de79fcd683b5c99e9c4133728d91529753ea", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "lead" + } + ], + "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", + "homepage": "http://phpcompatibility.com/", + "keywords": [ + "compatibility", + "paragonie", + "phpcs", + "polyfill", + "standards" + ], + "time": "2018-12-16T19:10:44+00:00" + }, + { + "name": "phpcompatibility/phpcompatibility-wp", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", + "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/cb303f0067cd5b366a41d4fb0e254fb40ff02efd", + "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/phpcompatibility-paragonie": "^1.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "lead" + } + ], + "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", + "homepage": "http://phpcompatibility.com/", + "keywords": [ + "compatibility", + "phpcs", + "standards", + "wordpress" + ], + "time": "2018-10-07T18:31:37+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "1.0.1", @@ -1501,6 +1604,57 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.4.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2019-04-10T23:49:02+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.11.0", @@ -1649,6 +1803,89 @@ "validate" ], "time": "2018-12-25T11:19:39+00:00" + }, + { + "name": "woocommerce/woocommerce-sniffs", + "version": "0.0.6", + "source": { + "type": "git", + "url": "https://github.com/woocommerce/woocommerce-sniffs.git", + "reference": "a3032bdddd60c71d1330f591e1a9128e115f81ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/a3032bdddd60c71d1330f591e1a9128e115f81ee", + "reference": "a3032bdddd60c71d1330f591e1a9128e115f81ee", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", + "php": ">=7.0", + "phpcompatibility/phpcompatibility-wp": "2.0.0", + "wp-coding-standards/wpcs": "^1.2" + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Claudio Sanches", + "email": "claudio@automattic.com" + } + ], + "description": "WooCommerce sniffs", + "keywords": [ + "phpcs", + "standards", + "woocommerce", + "wordpress" + ], + "time": "2019-03-11T15:30:23+00:00" + }, + { + "name": "wp-coding-standards/wpcs", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git", + "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c", + "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" + }, + "require-dev": { + "phpcompatibility/php-compatibility": "^9.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Contributors", + "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", + "keywords": [ + "phpcs", + "standards", + "wordpress" + ], + "time": "2018-12-18T09:43:51+00:00" } ], "aliases": [], diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 00000000000..f8128b854ed --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 00000000000..f27399a042d --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000000..49a7d1158b8 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,646 @@ + $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', + 'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit\\Framework\\CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit\\Framework\\Constraint\\ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit\\Framework\\Constraint\\Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit\\Framework\\Constraint\\Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit\\Framework\\Constraint\\Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit\\Framework\\Constraint\\Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', + 'PHPUnit\\Framework\\Constraint\\Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', + 'PHPUnit\\Framework\\Constraint\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit\\Framework\\Constraint\\GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit\\Framework\\Constraint\\IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit\\Framework\\Constraint\\IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit\\Framework\\Constraint\\IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit\\Framework\\Constraint\\IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit\\Framework\\Constraint\\IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit\\Framework\\Constraint\\IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit\\Framework\\Constraint\\IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit\\Framework\\Constraint\\IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit\\Framework\\Constraint\\IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit\\Framework\\Constraint\\IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', + 'PHPUnit\\Framework\\Constraint\\IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit\\Framework\\Constraint\\IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit\\Framework\\Constraint\\IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', + 'PHPUnit\\Framework\\Constraint\\LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', + 'PHPUnit\\Framework\\Constraint\\LogicalNot' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', + 'PHPUnit\\Framework\\Constraint\\LogicalOr' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', + 'PHPUnit\\Framework\\Constraint\\LogicalXor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit\\Framework\\Constraint\\StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', + 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', + 'PHPUnit\\Framework\\DataProviderTestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', + 'PHPUnit\\Framework\\Error\\Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit\\Framework\\Error\\Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Error.php', + 'PHPUnit\\Framework\\Error\\Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit\\Framework\\Error\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit\\Framework\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit\\Framework\\ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit\\Framework\\ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit\\Framework\\IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit\\Framework\\IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit\\Framework\\IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit\\Framework\\InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit\\Framework\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', + 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/BadMethodCallException.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Match.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/NamespaceMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/ObjectInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invokable.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/ConsecutiveParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtIndex.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedRecorder.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/StatelessInvocation.php', + 'PHPUnit\\Framework\\MockObject\\MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/MockBuilder.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/ForwardCompatibility/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/MatcherCollection.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Verifiable.php', + 'PHPUnit\\Framework\\OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit\\Framework\\RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit\\Framework\\RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit\\Framework\\SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit\\Framework\\SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit\\Framework\\SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit\\Framework\\SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit\\Framework\\SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit\\Framework\\SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit\\Framework\\TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', + 'PHPUnit\\Framework\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit\\Framework\\TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', + 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit\\Framework\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit\\Framework\\WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit\\Runner\\BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit\\Runner\\Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Runner/PhptTestCase.php', + 'PHPUnit\\Runner\\StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit\\Runner\\TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit\\Runner\\Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit\\TextUI\\Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit\\TextUI\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit\\TextUI\\TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit\\Util\\Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit\\Util\\Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit\\Util\\ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit\\Util\\ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit\\Util\\Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit\\Util\\Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit\\Util\\Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit\\Util\\Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit\\Util\\GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit\\Util\\InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit\\Util\\Json' => $vendorDir . '/phpunit/phpunit/src/Util/Json.php', + 'PHPUnit\\Util\\Log\\JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit\\Util\\Log\\TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', + 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', + 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', + 'PHPUnit\\Util\\Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit\\Util\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Util/RegularExpression.php', + 'PHPUnit\\Util\\Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit\\Util\\TestDox\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', + 'PHPUnit\\Util\\TextTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', + 'PHPUnit\\Util\\Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit\\Util\\Xml' => $vendorDir . '/phpunit/phpunit/src/Util/Xml.php', + 'PHPUnit\\Util\\XmlTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', + 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/MockObject.php', + 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php', + 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php', + 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php', + 'PharIo\\Manifest\\AuthorCollection' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollection.php', + 'PharIo\\Manifest\\AuthorCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', + 'PharIo\\Manifest\\AuthorElement' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElement.php', + 'PharIo\\Manifest\\AuthorElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElementCollection.php', + 'PharIo\\Manifest\\BundledComponent' => $vendorDir . '/phar-io/manifest/src/values/BundledComponent.php', + 'PharIo\\Manifest\\BundledComponentCollection' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollection.php', + 'PharIo\\Manifest\\BundledComponentCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', + 'PharIo\\Manifest\\BundlesElement' => $vendorDir . '/phar-io/manifest/src/xml/BundlesElement.php', + 'PharIo\\Manifest\\ComponentElement' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElement.php', + 'PharIo\\Manifest\\ComponentElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElementCollection.php', + 'PharIo\\Manifest\\ContainsElement' => $vendorDir . '/phar-io/manifest/src/xml/ContainsElement.php', + 'PharIo\\Manifest\\CopyrightElement' => $vendorDir . '/phar-io/manifest/src/xml/CopyrightElement.php', + 'PharIo\\Manifest\\CopyrightInformation' => $vendorDir . '/phar-io/manifest/src/values/CopyrightInformation.php', + 'PharIo\\Manifest\\ElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ElementCollection.php', + 'PharIo\\Manifest\\Email' => $vendorDir . '/phar-io/manifest/src/values/Email.php', + 'PharIo\\Manifest\\Exception' => $vendorDir . '/phar-io/manifest/src/exceptions/Exception.php', + 'PharIo\\Manifest\\ExtElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtElement.php', + 'PharIo\\Manifest\\ExtElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ExtElementCollection.php', + 'PharIo\\Manifest\\Extension' => $vendorDir . '/phar-io/manifest/src/values/Extension.php', + 'PharIo\\Manifest\\ExtensionElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtensionElement.php', + 'PharIo\\Manifest\\InvalidApplicationNameException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', + 'PharIo\\Manifest\\InvalidEmailException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', + 'PharIo\\Manifest\\InvalidUrlException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', + 'PharIo\\Manifest\\Library' => $vendorDir . '/phar-io/manifest/src/values/Library.php', + 'PharIo\\Manifest\\License' => $vendorDir . '/phar-io/manifest/src/values/License.php', + 'PharIo\\Manifest\\LicenseElement' => $vendorDir . '/phar-io/manifest/src/xml/LicenseElement.php', + 'PharIo\\Manifest\\Manifest' => $vendorDir . '/phar-io/manifest/src/values/Manifest.php', + 'PharIo\\Manifest\\ManifestDocument' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocument.php', + 'PharIo\\Manifest\\ManifestDocumentException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', + 'PharIo\\Manifest\\ManifestDocumentLoadingException' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', + 'PharIo\\Manifest\\ManifestDocumentMapper' => $vendorDir . '/phar-io/manifest/src/ManifestDocumentMapper.php', + 'PharIo\\Manifest\\ManifestDocumentMapperException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', + 'PharIo\\Manifest\\ManifestElement' => $vendorDir . '/phar-io/manifest/src/xml/ManifestElement.php', + 'PharIo\\Manifest\\ManifestElementException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestElementException.php', + 'PharIo\\Manifest\\ManifestLoader' => $vendorDir . '/phar-io/manifest/src/ManifestLoader.php', + 'PharIo\\Manifest\\ManifestLoaderException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', + 'PharIo\\Manifest\\ManifestSerializer' => $vendorDir . '/phar-io/manifest/src/ManifestSerializer.php', + 'PharIo\\Manifest\\PhpElement' => $vendorDir . '/phar-io/manifest/src/xml/PhpElement.php', + 'PharIo\\Manifest\\PhpExtensionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', + 'PharIo\\Manifest\\PhpVersionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpVersionRequirement.php', + 'PharIo\\Manifest\\Requirement' => $vendorDir . '/phar-io/manifest/src/values/Requirement.php', + 'PharIo\\Manifest\\RequirementCollection' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollection.php', + 'PharIo\\Manifest\\RequirementCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', + 'PharIo\\Manifest\\RequiresElement' => $vendorDir . '/phar-io/manifest/src/xml/RequiresElement.php', + 'PharIo\\Manifest\\Type' => $vendorDir . '/phar-io/manifest/src/values/Type.php', + 'PharIo\\Manifest\\Url' => $vendorDir . '/phar-io/manifest/src/values/Url.php', + 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/AnyVersionConstraint.php', + 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/InvalidVersionException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/HHVM.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeCoverage\\Version' => $vendorDir . '/phpunit/php-code-coverage/src/Version.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php', + 'SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\OperatingSystem' => $vendorDir . '/sebastian/environment/src/OperatingSystem.php', + 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/exceptions/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/exceptions/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\Exception' => $vendorDir . '/sebastian/object-reflector/src/Exception.php', + 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => $vendorDir . '/sebastian/object-reflector/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => $vendorDir . '/sebastian/object-reflector/src/ObjectReflector.php', + 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', + 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', + 'TheSeer\\Tokenizer\\Exception' => $vendorDir . '/theseer/tokenizer/src/Exception.php', + 'TheSeer\\Tokenizer\\NamespaceUri' => $vendorDir . '/theseer/tokenizer/src/NamespaceUri.php', + 'TheSeer\\Tokenizer\\NamespaceUriException' => $vendorDir . '/theseer/tokenizer/src/NamespaceUriException.php', + 'TheSeer\\Tokenizer\\Token' => $vendorDir . '/theseer/tokenizer/src/Token.php', + 'TheSeer\\Tokenizer\\TokenCollection' => $vendorDir . '/theseer/tokenizer/src/TokenCollection.php', + 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php', + 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php', + 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php', + 'WC_REST_CRUD_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 00000000000..814add31a67 --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,11 @@ + $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000000..b24b2176e1b --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,10 @@ + array($vendorDir . '/phpspec/prophecy/src'), +); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php new file mode 100644 index 00000000000..e7ca92e0b6c --- /dev/null +++ b/vendor/composer/autoload_psr4.php @@ -0,0 +1,16 @@ + array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'), + 'WooCommerce\\RestApi\\' => array($baseDir . '/src'), + 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), + 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), + 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), + 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => array($vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 00000000000..0f499015edf --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,70 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInitf71e7bc9895f702f48d84a180f514421::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequiref71e7bc9895f702f48d84a180f514421($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequiref71e7bc9895f702f48d84a180f514421($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 00000000000..36f0b52cdc7 --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,729 @@ + __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'p' => + array ( + 'phpDocumentor\\Reflection\\' => 25, + ), + 'W' => + array ( + 'WooCommerce\\RestApi\\' => 20, + 'Webmozart\\Assert\\' => 17, + ), + 'S' => + array ( + 'Symfony\\Polyfill\\Ctype\\' => 23, + ), + 'D' => + array ( + 'Doctrine\\Instantiator\\' => 22, + 'DeepCopy\\' => 9, + 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => 55, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'phpDocumentor\\Reflection\\' => + array ( + 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', + 1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', + 2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', + ), + 'WooCommerce\\RestApi\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + 'Webmozart\\Assert\\' => + array ( + 0 => __DIR__ . '/..' . '/webmozart/assert/src', + ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), + 'Doctrine\\Instantiator\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', + ), + 'DeepCopy\\' => + array ( + 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy', + ), + 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => + array ( + 0 => __DIR__ . '/..' . '/dealerdirect/phpcodesniffer-composer-installer/src', + ), + ); + + public static $prefixesPsr0 = array ( + 'P' => + array ( + 'Prophecy\\' => + array ( + 0 => __DIR__ . '/..' . '/phpspec/prophecy/src', + ), + ), + ); + + public static $classMap = array ( + 'File_Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php', + 'PHPUnit\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit\\Framework\\BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit\\Framework\\CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit\\Framework\\Constraint\\ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit\\Framework\\Constraint\\Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit\\Framework\\Constraint\\Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit\\Framework\\Constraint\\Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit\\Framework\\Constraint\\Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', + 'PHPUnit\\Framework\\Constraint\\Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', + 'PHPUnit\\Framework\\Constraint\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit\\Framework\\Constraint\\GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit\\Framework\\Constraint\\IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit\\Framework\\Constraint\\IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit\\Framework\\Constraint\\IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit\\Framework\\Constraint\\IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit\\Framework\\Constraint\\IsFinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit\\Framework\\Constraint\\IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\IsInfinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit\\Framework\\Constraint\\IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit\\Framework\\Constraint\\IsNan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit\\Framework\\Constraint\\IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit\\Framework\\Constraint\\IsReadable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', + 'PHPUnit\\Framework\\Constraint\\IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit\\Framework\\Constraint\\IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit\\Framework\\Constraint\\IsWritable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', + 'PHPUnit\\Framework\\Constraint\\LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', + 'PHPUnit\\Framework\\Constraint\\LogicalNot' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', + 'PHPUnit\\Framework\\Constraint\\LogicalOr' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', + 'PHPUnit\\Framework\\Constraint\\LogicalXor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit\\Framework\\Constraint\\StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', + 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', + 'PHPUnit\\Framework\\DataProviderTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', + 'PHPUnit\\Framework\\Error\\Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit\\Framework\\Error\\Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Error.php', + 'PHPUnit\\Framework\\Error\\Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit\\Framework\\Error\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit\\Framework\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit\\Framework\\ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit\\Framework\\ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit\\Framework\\IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit\\Framework\\IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit\\Framework\\IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit\\Framework\\InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit\\Framework\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', + 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/BadMethodCallException.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Match.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/NamespaceMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/ObjectInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invokable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invokable.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/ConsecutiveParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtIndex.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedRecorder.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/StatelessInvocation.php', + 'PHPUnit\\Framework\\MockObject\\MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/MockBuilder.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/ForwardCompatibility/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/MatcherCollection.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Verifiable.php', + 'PHPUnit\\Framework\\OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit\\Framework\\RiskyTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit\\Framework\\RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit\\Framework\\SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit\\Framework\\SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit\\Framework\\SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit\\Framework\\SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit\\Framework\\SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit\\Framework\\SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit\\Framework\\TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', + 'PHPUnit\\Framework\\TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit\\Framework\\TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', + 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit\\Framework\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit\\Framework\\WarningTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit\\Runner\\BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit\\Runner\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/PhptTestCase.php', + 'PHPUnit\\Runner\\StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit\\Runner\\TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit\\Runner\\Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit\\TextUI\\Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit\\TextUI\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit\\TextUI\\TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit\\Util\\Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit\\Util\\Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit\\Util\\ConfigurationGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit\\Util\\ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit\\Util\\Fileloader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit\\Util\\Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit\\Util\\Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit\\Util\\Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit\\Util\\GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit\\Util\\InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit\\Util\\Json' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Json.php', + 'PHPUnit\\Util\\Log\\JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit\\Util\\Log\\TeamCity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', + 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', + 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', + 'PHPUnit\\Util\\Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit\\Util\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/RegularExpression.php', + 'PHPUnit\\Util\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit\\Util\\TestDox\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', + 'PHPUnit\\Util\\TextTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', + 'PHPUnit\\Util\\Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit\\Util\\Xml' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Xml.php', + 'PHPUnit\\Util\\XmlTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', + 'PHPUnit_Framework_MockObject_MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/MockObject.php', + 'PHP_Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PharIo\\Manifest\\Application' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Application.php', + 'PharIo\\Manifest\\ApplicationName' => __DIR__ . '/..' . '/phar-io/manifest/src/values/ApplicationName.php', + 'PharIo\\Manifest\\Author' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Author.php', + 'PharIo\\Manifest\\AuthorCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollection.php', + 'PharIo\\Manifest\\AuthorCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', + 'PharIo\\Manifest\\AuthorElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElement.php', + 'PharIo\\Manifest\\AuthorElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElementCollection.php', + 'PharIo\\Manifest\\BundledComponent' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponent.php', + 'PharIo\\Manifest\\BundledComponentCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollection.php', + 'PharIo\\Manifest\\BundledComponentCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', + 'PharIo\\Manifest\\BundlesElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/BundlesElement.php', + 'PharIo\\Manifest\\ComponentElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElement.php', + 'PharIo\\Manifest\\ComponentElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElementCollection.php', + 'PharIo\\Manifest\\ContainsElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ContainsElement.php', + 'PharIo\\Manifest\\CopyrightElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/CopyrightElement.php', + 'PharIo\\Manifest\\CopyrightInformation' => __DIR__ . '/..' . '/phar-io/manifest/src/values/CopyrightInformation.php', + 'PharIo\\Manifest\\ElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ElementCollection.php', + 'PharIo\\Manifest\\Email' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Email.php', + 'PharIo\\Manifest\\Exception' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/Exception.php', + 'PharIo\\Manifest\\ExtElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElement.php', + 'PharIo\\Manifest\\ExtElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElementCollection.php', + 'PharIo\\Manifest\\Extension' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Extension.php', + 'PharIo\\Manifest\\ExtensionElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtensionElement.php', + 'PharIo\\Manifest\\InvalidApplicationNameException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', + 'PharIo\\Manifest\\InvalidEmailException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', + 'PharIo\\Manifest\\InvalidUrlException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', + 'PharIo\\Manifest\\Library' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Library.php', + 'PharIo\\Manifest\\License' => __DIR__ . '/..' . '/phar-io/manifest/src/values/License.php', + 'PharIo\\Manifest\\LicenseElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/LicenseElement.php', + 'PharIo\\Manifest\\Manifest' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Manifest.php', + 'PharIo\\Manifest\\ManifestDocument' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocument.php', + 'PharIo\\Manifest\\ManifestDocumentException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', + 'PharIo\\Manifest\\ManifestDocumentLoadingException' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', + 'PharIo\\Manifest\\ManifestDocumentMapper' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestDocumentMapper.php', + 'PharIo\\Manifest\\ManifestDocumentMapperException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', + 'PharIo\\Manifest\\ManifestElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestElement.php', + 'PharIo\\Manifest\\ManifestElementException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestElementException.php', + 'PharIo\\Manifest\\ManifestLoader' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestLoader.php', + 'PharIo\\Manifest\\ManifestLoaderException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', + 'PharIo\\Manifest\\ManifestSerializer' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestSerializer.php', + 'PharIo\\Manifest\\PhpElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/PhpElement.php', + 'PharIo\\Manifest\\PhpExtensionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', + 'PharIo\\Manifest\\PhpVersionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpVersionRequirement.php', + 'PharIo\\Manifest\\Requirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Requirement.php', + 'PharIo\\Manifest\\RequirementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollection.php', + 'PharIo\\Manifest\\RequirementCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', + 'PharIo\\Manifest\\RequiresElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/RequiresElement.php', + 'PharIo\\Manifest\\Type' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Type.php', + 'PharIo\\Manifest\\Url' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Url.php', + 'PharIo\\Version\\AbstractVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/AnyVersionConstraint.php', + 'PharIo\\Version\\ExactVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => __DIR__ . '/..' . '/phar-io/version/src/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidVersionException' => __DIR__ . '/..' . '/phar-io/version/src/InvalidVersionException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => __DIR__ . '/..' . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => __DIR__ . '/..' . '/phar-io/version/src/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => __DIR__ . '/..' . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => __DIR__ . '/..' . '/phar-io/version/src/VersionNumber.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/HHVM.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeCoverage\\Version' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Version.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => __DIR__ . '/..' . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\Exception' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/Exception.php', + 'SebastianBergmann\\Diff\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\OperatingSystem' => __DIR__ . '/..' . '/sebastian/environment/src/OperatingSystem.php', + 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\Exception' => __DIR__ . '/..' . '/sebastian/object-reflector/src/Exception.php', + 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-reflector/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => __DIR__ . '/..' . '/sebastian/object-reflector/src/ObjectReflector.php', + 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => __DIR__ . '/..' . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', + 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php', + 'TheSeer\\Tokenizer\\Exception' => __DIR__ . '/..' . '/theseer/tokenizer/src/Exception.php', + 'TheSeer\\Tokenizer\\NamespaceUri' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUri.php', + 'TheSeer\\Tokenizer\\NamespaceUriException' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUriException.php', + 'TheSeer\\Tokenizer\\Token' => __DIR__ . '/..' . '/theseer/tokenizer/src/Token.php', + 'TheSeer\\Tokenizer\\TokenCollection' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollection.php', + 'TheSeer\\Tokenizer\\TokenCollectionException' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollectionException.php', + 'TheSeer\\Tokenizer\\Tokenizer' => __DIR__ . '/..' . '/theseer/tokenizer/src/Tokenizer.php', + 'TheSeer\\Tokenizer\\XMLSerializer' => __DIR__ . '/..' . '/theseer/tokenizer/src/XMLSerializer.php', + 'WC_REST_CRUD_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixesPsr0; + $loader->classMap = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 00000000000..5502be2629b --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,1954 @@ +[ + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.5.0", + "version_normalized": "0.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "e749410375ff6fb7a040a68878c656c2e610b132" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132", + "reference": "e749410375ff6fb7a040a68878c656c2e610b132", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": "^5.3|^7", + "squizlabs/php_codesniffer": "^2|^3" + }, + "require-dev": { + "composer/composer": "*", + "phpcompatibility/php-compatibility": "^9.0", + "sensiolabs/security-checker": "^4.1.0" + }, + "time": "2018-10-26T13:21:45+00:00", + "type": "composer-plugin", + "extra": { + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ] + }, + { + "name": "doctrine/instantiator", + "version": "1.2.0", + "version_normalized": "1.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "a2c590166b2133a4633738648b6b064edae0814a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "time": "2019-03-17T17:37:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ] + }, + { + "name": "myclabs/deep-copy", + "version": "1.9.1", + "version_normalized": "1.9.1.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "time": "2019-04-07T13:18:21+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ] + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "time": "2017-03-05T18:14:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "time": "2017-03-05T17:38:23+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints" + }, + { + "name": "phpcompatibility/php-compatibility", + "version": "9.1.1", + "version_normalized": "9.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", + "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/2b63c5d284ab8857f7b1d5c240ddb507a6b2293c", + "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" + }, + "conflict": { + "squizlabs/php_codesniffer": "2.6.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "time": "2018-12-30T23:16:27+00:00", + "type": "phpcodesniffer-standard", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Contributors", + "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" + }, + { + "name": "Wim Godden", + "homepage": "https://github.com/wimg", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + } + ], + "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", + "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", + "keywords": [ + "compatibility", + "phpcs", + "standards" + ] + }, + { + "name": "phpcompatibility/phpcompatibility-paragonie", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", + "reference": "9160de79fcd683b5c99e9c4133728d91529753ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/9160de79fcd683b5c99e9c4133728d91529753ea", + "reference": "9160de79fcd683b5c99e9c4133728d91529753ea", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "time": "2018-12-16T19:10:44+00:00", + "type": "phpcodesniffer-standard", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "lead" + } + ], + "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", + "homepage": "http://phpcompatibility.com/", + "keywords": [ + "compatibility", + "paragonie", + "phpcs", + "polyfill", + "standards" + ] + }, + { + "name": "phpcompatibility/phpcompatibility-wp", + "version": "2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", + "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/cb303f0067cd5b366a41d4fb0e254fb40ff02efd", + "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/phpcompatibility-paragonie": "^1.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "time": "2018-10-07T18:31:37+00:00", + "type": "phpcodesniffer-standard", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "lead" + } + ], + "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", + "homepage": "http://phpcompatibility.com/", + "keywords": [ + "compatibility", + "phpcs", + "standards", + "wordpress" + ] + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "time": "2017-09-11T18:02:19+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ] + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.1", + "version_normalized": "4.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "time": "2019-04-30T17:48:53+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock." + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "version_normalized": "0.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "time": "2017-07-14T14:27:02+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ] + }, + { + "name": "phpspec/prophecy", + "version": "1.8.0", + "version_normalized": "1.8.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "time": "2018-08-05T17:53:17+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ] + }, + { + "name": "phpunit/php-code-coverage", + "version": "5.3.2", + "version_normalized": "5.3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.0", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^2.0.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-xdebug": "^2.5.5" + }, + "time": "2018-04-06T15:36:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ] + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "version_normalized": "1.4.5.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2017-11-27T13:52:08+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ] + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-06-21T13:50:34+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ] + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "version_normalized": "1.0.9.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "time": "2017-02-26T11:10:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ] + }, + { + "name": "phpunit/php-token-stream", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "791198a2c6254db10131eecfe8c06670700904db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2.4" + }, + "time": "2017-11-27T05:48:46+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ] + }, + { + "name": "phpunit/phpunit", + "version": "6.5.14", + "version_normalized": "6.5.14.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", + "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.3", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^1.0.9", + "phpunit/phpunit-mock-objects": "^5.0.9", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^2.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^1.1" + }, + "time": "2019-02-01T05:22:47+00:00", + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ] + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "5.0.10", + "version_normalized": "5.0.10.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.0", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "conflict": { + "phpunit/phpunit": "<6.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5.11" + }, + "suggest": { + "ext-soap": "*" + }, + "time": "2018-08-09T05:50:03+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "abandoned": true + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "time": "2017-03-04T06:30:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/" + }, + { + "name": "sebastian/comparator", + "version": "2.1.3", + "version_normalized": "2.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^6.4" + }, + "time": "2018-02-01T13:46:46+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ] + }, + { + "name": "sebastian/diff", + "version": "2.0.1", + "version_normalized": "2.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "time": "2017-08-03T08:09:46+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ] + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "version_normalized": "3.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "time": "2017-07-01T08:51:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ] + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "version_normalized": "3.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "time": "2017-04-03T13:19:02+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ] + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "time": "2017-04-27T15:39:26+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ] + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "version_normalized": "3.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-08-03T12:35:26+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-03-29T09:07:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "version_normalized": "3.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-03-03T06:23:57+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "time": "2015-07-28T20:34:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "version_normalized": "2.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "time": "2016-10-03T07:35:21+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.4.2", + "version_normalized": "3.4.2.0", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "time": "2019-04-10T23:49:02+00:00", + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ] + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.11.0", + "version_normalized": "1.11.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "82ebae02209c21113908c229e9883c419720738a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", + "reference": "82ebae02209c21113908c229e9883c419720738a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2019-02-06T07:57:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ] + }, + { + "name": "theseer/tokenizer", + "version": "1.1.2", + "version_normalized": "1.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8", + "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "time": "2019-04-04T09:56:43+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats" + }, + { + "name": "webmozart/assert", + "version": "1.4.0", + "version_normalized": "1.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", + "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "time": "2018-12-25T11:19:39+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ] + }, + { + "name": "woocommerce/woocommerce-sniffs", + "version": "0.0.6", + "version_normalized": "0.0.6.0", + "source": { + "type": "git", + "url": "https://github.com/woocommerce/woocommerce-sniffs.git", + "reference": "a3032bdddd60c71d1330f591e1a9128e115f81ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/a3032bdddd60c71d1330f591e1a9128e115f81ee", + "reference": "a3032bdddd60c71d1330f591e1a9128e115f81ee", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", + "php": ">=7.0", + "phpcompatibility/phpcompatibility-wp": "2.0.0", + "wp-coding-standards/wpcs": "^1.2" + }, + "time": "2019-03-11T15:30:23+00:00", + "type": "phpcodesniffer-standard", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Claudio Sanches", + "email": "claudio@automattic.com" + } + ], + "description": "WooCommerce sniffs", + "keywords": [ + "phpcs", + "standards", + "woocommerce", + "wordpress" + ] + }, + { + "name": "wp-coding-standards/wpcs", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git", + "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c", + "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" + }, + "require-dev": { + "phpcompatibility/php-compatibility": "^9.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." + }, + "time": "2018-12-18T09:43:51+00:00", + "type": "phpcodesniffer-standard", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Contributors", + "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", + "keywords": [ + "phpcs", + "standards", + "wordpress" + ] + } +] From 3d89793c4295b592a0d980d090c54fb4013f7bdb Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 18:47:35 +0100 Subject: [PATCH 102/440] Force use of autoloader --- .gitignore | 4 +--- src/Server.php | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 7ff207eee11..b19a8d1f0ae 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,4 @@ Thumbs.db /logs # composer -vendor/* -!vendor/autoload.php -!vendor/composer/ +vendor/ diff --git a/src/Server.php b/src/Server.php index 307d7a6dd19..f6207ede15d 100644 --- a/src/Server.php +++ b/src/Server.php @@ -12,7 +12,7 @@ defined( 'ABSPATH' ) || exit; if ( file_exists( __DIR__ . '/../vendor/autoload.php' ) ) { require __DIR__ . '/../vendor/autoload.php'; } else { - return; + wp_die( 'WooCommerce Rest API build required' ); } use WooCommerce\RestApi\Utilities\SingletonTrait; From 07f6dbcf269df8d4e06b0a0d444ece317a48ec6f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 18:50:18 +0100 Subject: [PATCH 103/440] .gitignore fix --- vendor/autoload.php | 7 - vendor/composer/ClassLoader.php | 445 ------ vendor/composer/LICENSE | 21 - vendor/composer/autoload_classmap.php | 646 -------- vendor/composer/autoload_files.php | 11 - vendor/composer/autoload_namespaces.php | 10 - vendor/composer/autoload_psr4.php | 16 - vendor/composer/autoload_real.php | 70 - vendor/composer/autoload_static.php | 729 --------- vendor/composer/installed.json | 1954 ----------------------- 10 files changed, 3909 deletions(-) delete mode 100644 vendor/autoload.php delete mode 100644 vendor/composer/ClassLoader.php delete mode 100644 vendor/composer/LICENSE delete mode 100644 vendor/composer/autoload_classmap.php delete mode 100644 vendor/composer/autoload_files.php delete mode 100644 vendor/composer/autoload_namespaces.php delete mode 100644 vendor/composer/autoload_psr4.php delete mode 100644 vendor/composer/autoload_real.php delete mode 100644 vendor/composer/autoload_static.php delete mode 100644 vendor/composer/installed.json diff --git a/vendor/autoload.php b/vendor/autoload.php deleted file mode 100644 index f8128b854ed..00000000000 --- a/vendor/autoload.php +++ /dev/null @@ -1,7 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - // PSR-4 - private $prefixLengthsPsr4 = array(); - private $prefixDirsPsr4 = array(); - private $fallbackDirsPsr4 = array(); - - // PSR-0 - private $prefixesPsr0 = array(); - private $fallbackDirsPsr0 = array(); - - private $useIncludePath = false; - private $classMap = array(); - private $classMapAuthoritative = false; - private $missingClasses = array(); - private $apcuPrefix; - - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); - } - - return array(); - } - - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - */ - public function add($prefix, $paths, $prepend = false) - { - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - (array) $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - (array) $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - (array) $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - (array) $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - } - - /** - * Unregisters this instance as an autoloader. - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - includeFile($file); - - return true; - } - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } -} - -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; -} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE deleted file mode 100644 index f27399a042d..00000000000 --- a/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php deleted file mode 100644 index 49a7d1158b8..00000000000 --- a/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,646 +0,0 @@ - $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', - 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', - 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', - 'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', - 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', - 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', - 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', - 'PHPUnit\\Framework\\CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', - 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', - 'PHPUnit\\Framework\\Constraint\\ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', - 'PHPUnit\\Framework\\Constraint\\Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', - 'PHPUnit\\Framework\\Constraint\\Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', - 'PHPUnit\\Framework\\Constraint\\Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', - 'PHPUnit\\Framework\\Constraint\\Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', - 'PHPUnit\\Framework\\Constraint\\Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', - 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', - 'PHPUnit\\Framework\\Constraint\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', - 'PHPUnit\\Framework\\Constraint\\GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', - 'PHPUnit\\Framework\\Constraint\\IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', - 'PHPUnit\\Framework\\Constraint\\IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', - 'PHPUnit\\Framework\\Constraint\\IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', - 'PHPUnit\\Framework\\Constraint\\IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', - 'PHPUnit\\Framework\\Constraint\\IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', - 'PHPUnit\\Framework\\Constraint\\IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', - 'PHPUnit\\Framework\\Constraint\\IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', - 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', - 'PHPUnit\\Framework\\Constraint\\IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', - 'PHPUnit\\Framework\\Constraint\\IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', - 'PHPUnit\\Framework\\Constraint\\IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', - 'PHPUnit\\Framework\\Constraint\\IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', - 'PHPUnit\\Framework\\Constraint\\IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', - 'PHPUnit\\Framework\\Constraint\\IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', - 'PHPUnit\\Framework\\Constraint\\IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', - 'PHPUnit\\Framework\\Constraint\\LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', - 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', - 'PHPUnit\\Framework\\Constraint\\LogicalNot' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', - 'PHPUnit\\Framework\\Constraint\\LogicalOr' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', - 'PHPUnit\\Framework\\Constraint\\LogicalXor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', - 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', - 'PHPUnit\\Framework\\Constraint\\StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', - 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', - 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', - 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', - 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', - 'PHPUnit\\Framework\\DataProviderTestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', - 'PHPUnit\\Framework\\Error\\Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', - 'PHPUnit\\Framework\\Error\\Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Error.php', - 'PHPUnit\\Framework\\Error\\Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', - 'PHPUnit\\Framework\\Error\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', - 'PHPUnit\\Framework\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', - 'PHPUnit\\Framework\\ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', - 'PHPUnit\\Framework\\ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', - 'PHPUnit\\Framework\\IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', - 'PHPUnit\\Framework\\IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', - 'PHPUnit\\Framework\\IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', - 'PHPUnit\\Framework\\InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', - 'PHPUnit\\Framework\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', - 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/BadMethodCallException.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Identity.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Match.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/MethodNameMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/NamespaceMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/ParametersMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Builder/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Generator.php', - 'PHPUnit\\Framework\\MockObject\\Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/ObjectInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Invokable.php', - 'PHPUnit\\Framework\\MockObject\\Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/AnyInvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/AnyParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/ConsecutiveParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtIndex.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastOnce.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtMostCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedRecorder.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/MethodName.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/Parameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Matcher/StatelessInvocation.php', - 'PHPUnit\\Framework\\MockObject\\MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/MockBuilder.php', - 'PHPUnit\\Framework\\MockObject\\MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/ForwardCompatibility/MockObject.php', - 'PHPUnit\\Framework\\MockObject\\RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Exception/RuntimeException.php', - 'PHPUnit\\Framework\\MockObject\\Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ConsecutiveCalls.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/MatcherCollection.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnArgument.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnCallback.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnReference.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnSelf.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnStub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Stub/ReturnValueMap.php', - 'PHPUnit\\Framework\\MockObject\\Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Verifiable.php', - 'PHPUnit\\Framework\\OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', - 'PHPUnit\\Framework\\RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', - 'PHPUnit\\Framework\\RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', - 'PHPUnit\\Framework\\SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', - 'PHPUnit\\Framework\\SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', - 'PHPUnit\\Framework\\SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', - 'PHPUnit\\Framework\\SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', - 'PHPUnit\\Framework\\SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', - 'PHPUnit\\Framework\\SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', - 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', - 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', - 'PHPUnit\\Framework\\TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', - 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', - 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', - 'PHPUnit\\Framework\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', - 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', - 'PHPUnit\\Framework\\TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', - 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', - 'PHPUnit\\Framework\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', - 'PHPUnit\\Framework\\WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', - 'PHPUnit\\Runner\\BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', - 'PHPUnit\\Runner\\Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', - 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', - 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', - 'PHPUnit\\Runner\\PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Runner/PhptTestCase.php', - 'PHPUnit\\Runner\\StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', - 'PHPUnit\\Runner\\TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', - 'PHPUnit\\Runner\\Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', - 'PHPUnit\\TextUI\\Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', - 'PHPUnit\\TextUI\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', - 'PHPUnit\\TextUI\\TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', - 'PHPUnit\\Util\\Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', - 'PHPUnit\\Util\\Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', - 'PHPUnit\\Util\\ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', - 'PHPUnit\\Util\\ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', - 'PHPUnit\\Util\\Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', - 'PHPUnit\\Util\\Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', - 'PHPUnit\\Util\\Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', - 'PHPUnit\\Util\\Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', - 'PHPUnit\\Util\\GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', - 'PHPUnit\\Util\\InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', - 'PHPUnit\\Util\\Json' => $vendorDir . '/phpunit/phpunit/src/Util/Json.php', - 'PHPUnit\\Util\\Log\\JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', - 'PHPUnit\\Util\\Log\\TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', - 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', - 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', - 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', - 'PHPUnit\\Util\\Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', - 'PHPUnit\\Util\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Util/RegularExpression.php', - 'PHPUnit\\Util\\Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', - 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', - 'PHPUnit\\Util\\TestDox\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', - 'PHPUnit\\Util\\TextTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', - 'PHPUnit\\Util\\Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', - 'PHPUnit\\Util\\Xml' => $vendorDir . '/phpunit/phpunit/src/Util/Xml.php', - 'PHPUnit\\Util\\XmlTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', - 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/MockObject.php', - 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', - 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', - 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', - 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php', - 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php', - 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php', - 'PharIo\\Manifest\\AuthorCollection' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollection.php', - 'PharIo\\Manifest\\AuthorCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', - 'PharIo\\Manifest\\AuthorElement' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElement.php', - 'PharIo\\Manifest\\AuthorElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElementCollection.php', - 'PharIo\\Manifest\\BundledComponent' => $vendorDir . '/phar-io/manifest/src/values/BundledComponent.php', - 'PharIo\\Manifest\\BundledComponentCollection' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollection.php', - 'PharIo\\Manifest\\BundledComponentCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', - 'PharIo\\Manifest\\BundlesElement' => $vendorDir . '/phar-io/manifest/src/xml/BundlesElement.php', - 'PharIo\\Manifest\\ComponentElement' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElement.php', - 'PharIo\\Manifest\\ComponentElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElementCollection.php', - 'PharIo\\Manifest\\ContainsElement' => $vendorDir . '/phar-io/manifest/src/xml/ContainsElement.php', - 'PharIo\\Manifest\\CopyrightElement' => $vendorDir . '/phar-io/manifest/src/xml/CopyrightElement.php', - 'PharIo\\Manifest\\CopyrightInformation' => $vendorDir . '/phar-io/manifest/src/values/CopyrightInformation.php', - 'PharIo\\Manifest\\ElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ElementCollection.php', - 'PharIo\\Manifest\\Email' => $vendorDir . '/phar-io/manifest/src/values/Email.php', - 'PharIo\\Manifest\\Exception' => $vendorDir . '/phar-io/manifest/src/exceptions/Exception.php', - 'PharIo\\Manifest\\ExtElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtElement.php', - 'PharIo\\Manifest\\ExtElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ExtElementCollection.php', - 'PharIo\\Manifest\\Extension' => $vendorDir . '/phar-io/manifest/src/values/Extension.php', - 'PharIo\\Manifest\\ExtensionElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtensionElement.php', - 'PharIo\\Manifest\\InvalidApplicationNameException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', - 'PharIo\\Manifest\\InvalidEmailException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', - 'PharIo\\Manifest\\InvalidUrlException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', - 'PharIo\\Manifest\\Library' => $vendorDir . '/phar-io/manifest/src/values/Library.php', - 'PharIo\\Manifest\\License' => $vendorDir . '/phar-io/manifest/src/values/License.php', - 'PharIo\\Manifest\\LicenseElement' => $vendorDir . '/phar-io/manifest/src/xml/LicenseElement.php', - 'PharIo\\Manifest\\Manifest' => $vendorDir . '/phar-io/manifest/src/values/Manifest.php', - 'PharIo\\Manifest\\ManifestDocument' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocument.php', - 'PharIo\\Manifest\\ManifestDocumentException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', - 'PharIo\\Manifest\\ManifestDocumentLoadingException' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', - 'PharIo\\Manifest\\ManifestDocumentMapper' => $vendorDir . '/phar-io/manifest/src/ManifestDocumentMapper.php', - 'PharIo\\Manifest\\ManifestDocumentMapperException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', - 'PharIo\\Manifest\\ManifestElement' => $vendorDir . '/phar-io/manifest/src/xml/ManifestElement.php', - 'PharIo\\Manifest\\ManifestElementException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestElementException.php', - 'PharIo\\Manifest\\ManifestLoader' => $vendorDir . '/phar-io/manifest/src/ManifestLoader.php', - 'PharIo\\Manifest\\ManifestLoaderException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', - 'PharIo\\Manifest\\ManifestSerializer' => $vendorDir . '/phar-io/manifest/src/ManifestSerializer.php', - 'PharIo\\Manifest\\PhpElement' => $vendorDir . '/phar-io/manifest/src/xml/PhpElement.php', - 'PharIo\\Manifest\\PhpExtensionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', - 'PharIo\\Manifest\\PhpVersionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpVersionRequirement.php', - 'PharIo\\Manifest\\Requirement' => $vendorDir . '/phar-io/manifest/src/values/Requirement.php', - 'PharIo\\Manifest\\RequirementCollection' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollection.php', - 'PharIo\\Manifest\\RequirementCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', - 'PharIo\\Manifest\\RequiresElement' => $vendorDir . '/phar-io/manifest/src/xml/RequiresElement.php', - 'PharIo\\Manifest\\Type' => $vendorDir . '/phar-io/manifest/src/values/Type.php', - 'PharIo\\Manifest\\Url' => $vendorDir . '/phar-io/manifest/src/values/Url.php', - 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/AbstractVersionConstraint.php', - 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/AndVersionConstraintGroup.php', - 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/AnyVersionConstraint.php', - 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/ExactVersionConstraint.php', - 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/Exception.php', - 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/GreaterThanOrEqualToVersionConstraint.php', - 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/InvalidVersionException.php', - 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/OrVersionConstraintGroup.php', - 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php', - 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/SpecificMajorAndMinorVersionConstraint.php', - 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/SpecificMajorVersionConstraint.php', - 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/UnsupportedVersionConstraintException.php', - 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php', - 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/VersionConstraint.php', - 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php', - 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php', - 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php', - 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', - 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/HHVM.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', - 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', - 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php', - 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', - 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', - 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', - 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', - 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', - 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', - 'SebastianBergmann\\CodeCoverage\\Version' => $vendorDir . '/phpunit/php-code-coverage/src/Version.php', - 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', - 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', - 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', - 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', - 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', - 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', - 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', - 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', - 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', - 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', - 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', - 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', - 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', - 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', - 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', - 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', - 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', - 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', - 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', - 'SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php', - 'SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', - 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', - 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', - 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', - 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', - 'SebastianBergmann\\Environment\\OperatingSystem' => $vendorDir . '/sebastian/environment/src/OperatingSystem.php', - 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', - 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', - 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', - 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', - 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/exceptions/Exception.php', - 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', - 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/exceptions/RuntimeException.php', - 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', - 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', - 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', - 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\Exception' => $vendorDir . '/sebastian/object-reflector/src/Exception.php', - 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => $vendorDir . '/sebastian/object-reflector/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => $vendorDir . '/sebastian/object-reflector/src/ObjectReflector.php', - 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', - 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', - 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', - 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', - 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', - 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', - 'TheSeer\\Tokenizer\\Exception' => $vendorDir . '/theseer/tokenizer/src/Exception.php', - 'TheSeer\\Tokenizer\\NamespaceUri' => $vendorDir . '/theseer/tokenizer/src/NamespaceUri.php', - 'TheSeer\\Tokenizer\\NamespaceUriException' => $vendorDir . '/theseer/tokenizer/src/NamespaceUriException.php', - 'TheSeer\\Tokenizer\\Token' => $vendorDir . '/theseer/tokenizer/src/Token.php', - 'TheSeer\\Tokenizer\\TokenCollection' => $vendorDir . '/theseer/tokenizer/src/TokenCollection.php', - 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php', - 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php', - 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php', - 'WC_REST_CRUD_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-controller.php', - 'WC_REST_Coupons_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', -); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php deleted file mode 100644 index 814add31a67..00000000000 --- a/vendor/composer/autoload_files.php +++ /dev/null @@ -1,11 +0,0 @@ - $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', - '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', -); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php deleted file mode 100644 index b24b2176e1b..00000000000 --- a/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,10 +0,0 @@ - array($vendorDir . '/phpspec/prophecy/src'), -); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php deleted file mode 100644 index e7ca92e0b6c..00000000000 --- a/vendor/composer/autoload_psr4.php +++ /dev/null @@ -1,16 +0,0 @@ - array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'), - 'WooCommerce\\RestApi\\' => array($baseDir . '/src'), - 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), - 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), - 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), - 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), - 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => array($vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src'), -); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php deleted file mode 100644 index 0f499015edf..00000000000 --- a/vendor/composer/autoload_real.php +++ /dev/null @@ -1,70 +0,0 @@ -= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInitf71e7bc9895f702f48d84a180f514421::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } - - $loader->register(true); - - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequiref71e7bc9895f702f48d84a180f514421($fileIdentifier, $file); - } - - return $loader; - } -} - -function composerRequiref71e7bc9895f702f48d84a180f514421($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php deleted file mode 100644 index 36f0b52cdc7..00000000000 --- a/vendor/composer/autoload_static.php +++ /dev/null @@ -1,729 +0,0 @@ - __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', - '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'p' => - array ( - 'phpDocumentor\\Reflection\\' => 25, - ), - 'W' => - array ( - 'WooCommerce\\RestApi\\' => 20, - 'Webmozart\\Assert\\' => 17, - ), - 'S' => - array ( - 'Symfony\\Polyfill\\Ctype\\' => 23, - ), - 'D' => - array ( - 'Doctrine\\Instantiator\\' => 22, - 'DeepCopy\\' => 9, - 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => 55, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'phpDocumentor\\Reflection\\' => - array ( - 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', - 1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', - 2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', - ), - 'WooCommerce\\RestApi\\' => - array ( - 0 => __DIR__ . '/../..' . '/src', - ), - 'Webmozart\\Assert\\' => - array ( - 0 => __DIR__ . '/..' . '/webmozart/assert/src', - ), - 'Symfony\\Polyfill\\Ctype\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', - ), - 'Doctrine\\Instantiator\\' => - array ( - 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', - ), - 'DeepCopy\\' => - array ( - 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy', - ), - 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => - array ( - 0 => __DIR__ . '/..' . '/dealerdirect/phpcodesniffer-composer-installer/src', - ), - ); - - public static $prefixesPsr0 = array ( - 'P' => - array ( - 'Prophecy\\' => - array ( - 0 => __DIR__ . '/..' . '/phpspec/prophecy/src', - ), - ), - ); - - public static $classMap = array ( - 'File_Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php', - 'File_Iterator_Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php', - 'File_Iterator_Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php', - 'PHPUnit\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php', - 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php', - 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', - 'PHPUnit\\Framework\\BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/BaseTestListener.php', - 'PHPUnit\\Framework\\CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', - 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', - 'PHPUnit\\Framework\\Constraint\\ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', - 'PHPUnit\\Framework\\Constraint\\Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', - 'PHPUnit\\Framework\\Constraint\\Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', - 'PHPUnit\\Framework\\Constraint\\Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', - 'PHPUnit\\Framework\\Constraint\\Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', - 'PHPUnit\\Framework\\Constraint\\Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php', - 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', - 'PHPUnit\\Framework\\Constraint\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', - 'PHPUnit\\Framework\\Constraint\\GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', - 'PHPUnit\\Framework\\Constraint\\IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', - 'PHPUnit\\Framework\\Constraint\\IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', - 'PHPUnit\\Framework\\Constraint\\IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', - 'PHPUnit\\Framework\\Constraint\\IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', - 'PHPUnit\\Framework\\Constraint\\IsFinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', - 'PHPUnit\\Framework\\Constraint\\IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', - 'PHPUnit\\Framework\\Constraint\\IsInfinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', - 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', - 'PHPUnit\\Framework\\Constraint\\IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', - 'PHPUnit\\Framework\\Constraint\\IsNan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', - 'PHPUnit\\Framework\\Constraint\\IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', - 'PHPUnit\\Framework\\Constraint\\IsReadable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', - 'PHPUnit\\Framework\\Constraint\\IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', - 'PHPUnit\\Framework\\Constraint\\IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', - 'PHPUnit\\Framework\\Constraint\\IsWritable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', - 'PHPUnit\\Framework\\Constraint\\LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', - 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', - 'PHPUnit\\Framework\\Constraint\\LogicalNot' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', - 'PHPUnit\\Framework\\Constraint\\LogicalOr' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', - 'PHPUnit\\Framework\\Constraint\\LogicalXor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', - 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', - 'PHPUnit\\Framework\\Constraint\\StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', - 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', - 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', - 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', - 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', - 'PHPUnit\\Framework\\DataProviderTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', - 'PHPUnit\\Framework\\Error\\Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', - 'PHPUnit\\Framework\\Error\\Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Error.php', - 'PHPUnit\\Framework\\Error\\Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php', - 'PHPUnit\\Framework\\Error\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php', - 'PHPUnit\\Framework\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception.php', - 'PHPUnit\\Framework\\ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', - 'PHPUnit\\Framework\\ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', - 'PHPUnit\\Framework\\IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php', - 'PHPUnit\\Framework\\IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', - 'PHPUnit\\Framework\\IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', - 'PHPUnit\\Framework\\InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', - 'PHPUnit\\Framework\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', - 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/BadMethodCallException.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Identity.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Match.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/MethodNameMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/NamespaceMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/ParametersMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Builder/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Generator' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Generator.php', - 'PHPUnit\\Framework\\MockObject\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/ObjectInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invokable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Invokable.php', - 'PHPUnit\\Framework\\MockObject\\Matcher' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/AnyInvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/AnyParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/ConsecutiveParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtIndex.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtLeastOnce.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedAtMostCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/InvokedRecorder.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/MethodName.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/Parameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Matcher/StatelessInvocation.php', - 'PHPUnit\\Framework\\MockObject\\MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/MockBuilder.php', - 'PHPUnit\\Framework\\MockObject\\MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/ForwardCompatibility/MockObject.php', - 'PHPUnit\\Framework\\MockObject\\RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Exception/RuntimeException.php', - 'PHPUnit\\Framework\\MockObject\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ConsecutiveCalls.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/MatcherCollection.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnArgument.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnCallback.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnReference.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnSelf.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnStub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Stub/ReturnValueMap.php', - 'PHPUnit\\Framework\\MockObject\\Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Verifiable.php', - 'PHPUnit\\Framework\\OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/OutputError.php', - 'PHPUnit\\Framework\\RiskyTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTest.php', - 'PHPUnit\\Framework\\RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTestError.php', - 'PHPUnit\\Framework\\SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php', - 'PHPUnit\\Framework\\SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php', - 'PHPUnit\\Framework\\SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', - 'PHPUnit\\Framework\\SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestError.php', - 'PHPUnit\\Framework\\SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', - 'PHPUnit\\Framework\\SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SyntheticError.php', - 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php', - 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php', - 'PHPUnit\\Framework\\TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php', - 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php', - 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', - 'PHPUnit\\Framework\\TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php', - 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php', - 'PHPUnit\\Framework\\TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', - 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', - 'PHPUnit\\Framework\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Warning.php', - 'PHPUnit\\Framework\\WarningTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/WarningTestCase.php', - 'PHPUnit\\Runner\\BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', - 'PHPUnit\\Runner\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php', - 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php', - 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', - 'PHPUnit\\Runner\\PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/PhptTestCase.php', - 'PHPUnit\\Runner\\StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', - 'PHPUnit\\Runner\\TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', - 'PHPUnit\\Runner\\Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php', - 'PHPUnit\\TextUI\\Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php', - 'PHPUnit\\TextUI\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', - 'PHPUnit\\TextUI\\TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php', - 'PHPUnit\\Util\\Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php', - 'PHPUnit\\Util\\Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php', - 'PHPUnit\\Util\\ConfigurationGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', - 'PHPUnit\\Util\\ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php', - 'PHPUnit\\Util\\Fileloader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Fileloader.php', - 'PHPUnit\\Util\\Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php', - 'PHPUnit\\Util\\Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php', - 'PHPUnit\\Util\\Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php', - 'PHPUnit\\Util\\GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php', - 'PHPUnit\\Util\\InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', - 'PHPUnit\\Util\\Json' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Json.php', - 'PHPUnit\\Util\\Log\\JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php', - 'PHPUnit\\Util\\Log\\TeamCity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TeamCity.php', - 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', - 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', - 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', - 'PHPUnit\\Util\\Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php', - 'PHPUnit\\Util\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/RegularExpression.php', - 'PHPUnit\\Util\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php', - 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', - 'PHPUnit\\Util\\TestDox\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', - 'PHPUnit\\Util\\TextTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', - 'PHPUnit\\Util\\Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php', - 'PHPUnit\\Util\\Xml' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Xml.php', - 'PHPUnit\\Util\\XmlTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', - 'PHPUnit_Framework_MockObject_MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/MockObject.php', - 'PHP_Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php', - 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ASYNC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AWAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMPILER_HALT_OFFSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENUM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUALS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_JOIN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_CP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_OP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ONUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SHAPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SUPER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php', - 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', - 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHERE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_ATTRIBUTE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CHILDREN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_REQUIRED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TEXT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', - 'PharIo\\Manifest\\Application' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Application.php', - 'PharIo\\Manifest\\ApplicationName' => __DIR__ . '/..' . '/phar-io/manifest/src/values/ApplicationName.php', - 'PharIo\\Manifest\\Author' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Author.php', - 'PharIo\\Manifest\\AuthorCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollection.php', - 'PharIo\\Manifest\\AuthorCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', - 'PharIo\\Manifest\\AuthorElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElement.php', - 'PharIo\\Manifest\\AuthorElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElementCollection.php', - 'PharIo\\Manifest\\BundledComponent' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponent.php', - 'PharIo\\Manifest\\BundledComponentCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollection.php', - 'PharIo\\Manifest\\BundledComponentCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', - 'PharIo\\Manifest\\BundlesElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/BundlesElement.php', - 'PharIo\\Manifest\\ComponentElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElement.php', - 'PharIo\\Manifest\\ComponentElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElementCollection.php', - 'PharIo\\Manifest\\ContainsElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ContainsElement.php', - 'PharIo\\Manifest\\CopyrightElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/CopyrightElement.php', - 'PharIo\\Manifest\\CopyrightInformation' => __DIR__ . '/..' . '/phar-io/manifest/src/values/CopyrightInformation.php', - 'PharIo\\Manifest\\ElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ElementCollection.php', - 'PharIo\\Manifest\\Email' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Email.php', - 'PharIo\\Manifest\\Exception' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/Exception.php', - 'PharIo\\Manifest\\ExtElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElement.php', - 'PharIo\\Manifest\\ExtElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElementCollection.php', - 'PharIo\\Manifest\\Extension' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Extension.php', - 'PharIo\\Manifest\\ExtensionElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtensionElement.php', - 'PharIo\\Manifest\\InvalidApplicationNameException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', - 'PharIo\\Manifest\\InvalidEmailException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', - 'PharIo\\Manifest\\InvalidUrlException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', - 'PharIo\\Manifest\\Library' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Library.php', - 'PharIo\\Manifest\\License' => __DIR__ . '/..' . '/phar-io/manifest/src/values/License.php', - 'PharIo\\Manifest\\LicenseElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/LicenseElement.php', - 'PharIo\\Manifest\\Manifest' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Manifest.php', - 'PharIo\\Manifest\\ManifestDocument' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocument.php', - 'PharIo\\Manifest\\ManifestDocumentException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', - 'PharIo\\Manifest\\ManifestDocumentLoadingException' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', - 'PharIo\\Manifest\\ManifestDocumentMapper' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestDocumentMapper.php', - 'PharIo\\Manifest\\ManifestDocumentMapperException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', - 'PharIo\\Manifest\\ManifestElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestElement.php', - 'PharIo\\Manifest\\ManifestElementException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestElementException.php', - 'PharIo\\Manifest\\ManifestLoader' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestLoader.php', - 'PharIo\\Manifest\\ManifestLoaderException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', - 'PharIo\\Manifest\\ManifestSerializer' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestSerializer.php', - 'PharIo\\Manifest\\PhpElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/PhpElement.php', - 'PharIo\\Manifest\\PhpExtensionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', - 'PharIo\\Manifest\\PhpVersionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpVersionRequirement.php', - 'PharIo\\Manifest\\Requirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Requirement.php', - 'PharIo\\Manifest\\RequirementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollection.php', - 'PharIo\\Manifest\\RequirementCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', - 'PharIo\\Manifest\\RequiresElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/RequiresElement.php', - 'PharIo\\Manifest\\Type' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Type.php', - 'PharIo\\Manifest\\Url' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Url.php', - 'PharIo\\Version\\AbstractVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/AbstractVersionConstraint.php', - 'PharIo\\Version\\AndVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/AndVersionConstraintGroup.php', - 'PharIo\\Version\\AnyVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/AnyVersionConstraint.php', - 'PharIo\\Version\\ExactVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/ExactVersionConstraint.php', - 'PharIo\\Version\\Exception' => __DIR__ . '/..' . '/phar-io/version/src/Exception.php', - 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/GreaterThanOrEqualToVersionConstraint.php', - 'PharIo\\Version\\InvalidVersionException' => __DIR__ . '/..' . '/phar-io/version/src/InvalidVersionException.php', - 'PharIo\\Version\\OrVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/OrVersionConstraintGroup.php', - 'PharIo\\Version\\PreReleaseSuffix' => __DIR__ . '/..' . '/phar-io/version/src/PreReleaseSuffix.php', - 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/SpecificMajorAndMinorVersionConstraint.php', - 'PharIo\\Version\\SpecificMajorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/SpecificMajorVersionConstraint.php', - 'PharIo\\Version\\UnsupportedVersionConstraintException' => __DIR__ . '/..' . '/phar-io/version/src/UnsupportedVersionConstraintException.php', - 'PharIo\\Version\\Version' => __DIR__ . '/..' . '/phar-io/version/src/Version.php', - 'PharIo\\Version\\VersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraint.php', - 'PharIo\\Version\\VersionConstraintParser' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintParser.php', - 'PharIo\\Version\\VersionConstraintValue' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintValue.php', - 'PharIo\\Version\\VersionNumber' => __DIR__ . '/..' . '/phar-io/version/src/VersionNumber.php', - 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php', - 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Driver.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/HHVM.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', - 'SebastianBergmann\\CodeCoverage\\Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/Exception.php', - 'SebastianBergmann\\CodeCoverage\\Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Filter.php', - 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', - 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Builder.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Node\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/File.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Iterator.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Clover.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Crap4j.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', - 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/PHP.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Text.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', - 'SebastianBergmann\\CodeCoverage\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', - 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', - 'SebastianBergmann\\CodeCoverage\\Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Util.php', - 'SebastianBergmann\\CodeCoverage\\Version' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Version.php', - 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => __DIR__ . '/..' . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', - 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php', - 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php', - 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php', - 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php', - 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php', - 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php', - 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php', - 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php', - 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php', - 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php', - 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php', - 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php', - 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php', - 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php', - 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php', - 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php', - 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php', - 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php', - 'SebastianBergmann\\Diff\\Exception' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/Exception.php', - 'SebastianBergmann\\Diff\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php', - 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', - 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', - 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php', - 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php', - 'SebastianBergmann\\Environment\\OperatingSystem' => __DIR__ . '/..' . '/sebastian/environment/src/OperatingSystem.php', - 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php', - 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php', - 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php', - 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php', - 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/Exception.php', - 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php', - 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/RuntimeException.php', - 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php', - 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Enumerator.php', - 'SebastianBergmann\\ObjectEnumerator\\Exception' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Exception.php', - 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\Exception' => __DIR__ . '/..' . '/sebastian/object-reflector/src/Exception.php', - 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-reflector/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => __DIR__ . '/..' . '/sebastian/object-reflector/src/ObjectReflector.php', - 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php', - 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php', - 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php', - 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => __DIR__ . '/..' . '/sebastian/resource-operations/src/ResourceOperations.php', - 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', - 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php', - 'TheSeer\\Tokenizer\\Exception' => __DIR__ . '/..' . '/theseer/tokenizer/src/Exception.php', - 'TheSeer\\Tokenizer\\NamespaceUri' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUri.php', - 'TheSeer\\Tokenizer\\NamespaceUriException' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUriException.php', - 'TheSeer\\Tokenizer\\Token' => __DIR__ . '/..' . '/theseer/tokenizer/src/Token.php', - 'TheSeer\\Tokenizer\\TokenCollection' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollection.php', - 'TheSeer\\Tokenizer\\TokenCollectionException' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollectionException.php', - 'TheSeer\\Tokenizer\\Tokenizer' => __DIR__ . '/..' . '/theseer/tokenizer/src/Tokenizer.php', - 'TheSeer\\Tokenizer\\XMLSerializer' => __DIR__ . '/..' . '/theseer/tokenizer/src/XMLSerializer.php', - 'WC_REST_CRUD_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-controller.php', - 'WC_REST_Coupons_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$prefixesPsr0; - $loader->classMap = ComposerStaticInitf71e7bc9895f702f48d84a180f514421::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json deleted file mode 100644 index 5502be2629b..00000000000 --- a/vendor/composer/installed.json +++ /dev/null @@ -1,1954 +0,0 @@ -[ - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.5.0", - "version_normalized": "0.5.0.0", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "e749410375ff6fb7a040a68878c656c2e610b132" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132", - "reference": "e749410375ff6fb7a040a68878c656c2e610b132", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0", - "php": "^5.3|^7", - "squizlabs/php_codesniffer": "^2|^3" - }, - "require-dev": { - "composer/composer": "*", - "phpcompatibility/php-compatibility": "^9.0", - "sensiolabs/security-checker": "^4.1.0" - }, - "time": "2018-10-26T13:21:45+00:00", - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ] - }, - { - "name": "doctrine/instantiator", - "version": "1.2.0", - "version_normalized": "1.2.0.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "a2c590166b2133a4633738648b6b064edae0814a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", - "reference": "a2c590166b2133a4633738648b6b064edae0814a", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" - }, - "time": "2019-03-17T17:37:11+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ] - }, - { - "name": "myclabs/deep-copy", - "version": "1.9.1", - "version_normalized": "1.9.1.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "time": "2019-04-07T13:18:21+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ] - }, - { - "name": "phar-io/manifest", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" - }, - "time": "2017-03-05T18:14:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)" - }, - { - "name": "phar-io/version", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "time": "2017-03-05T17:38:23+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints" - }, - { - "name": "phpcompatibility/php-compatibility", - "version": "9.1.1", - "version_normalized": "9.1.1.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/2b63c5d284ab8857f7b1d5c240ddb507a6b2293c", - "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" - }, - "conflict": { - "squizlabs/php_codesniffer": "2.6.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "time": "2018-12-30T23:16:27+00:00", - "type": "phpcodesniffer-standard", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Contributors", - "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" - }, - { - "name": "Wim Godden", - "homepage": "https://github.com/wimg", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - } - ], - "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", - "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", - "keywords": [ - "compatibility", - "phpcs", - "standards" - ] - }, - { - "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "9160de79fcd683b5c99e9c4133728d91529753ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/9160de79fcd683b5c99e9c4133728d91529753ea", - "reference": "9160de79fcd683b5c99e9c4133728d91529753ea", - "shasum": "" - }, - "require": { - "phpcompatibility/php-compatibility": "^9.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "time": "2018-12-16T19:10:44+00:00", - "type": "phpcodesniffer-standard", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } - ], - "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", - "homepage": "http://phpcompatibility.com/", - "keywords": [ - "compatibility", - "paragonie", - "phpcs", - "polyfill", - "standards" - ] - }, - { - "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.0.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/cb303f0067cd5b366a41d4fb0e254fb40ff02efd", - "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd", - "shasum": "" - }, - "require": { - "phpcompatibility/php-compatibility": "^9.0", - "phpcompatibility/phpcompatibility-paragonie": "^1.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "time": "2018-10-07T18:31:37+00:00", - "type": "phpcodesniffer-standard", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } - ], - "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", - "homepage": "http://phpcompatibility.com/", - "keywords": [ - "compatibility", - "phpcs", - "standards", - "wordpress" - ] - }, - { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" - }, - "time": "2017-09-11T18:02:19+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ] - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.1", - "version_normalized": "4.3.1.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "~1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "time": "2019-04-30T17:48:53+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock." - }, - { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", - "version_normalized": "0.4.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", - "shasum": "" - }, - "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" - }, - "time": "2017-07-14T14:27:02+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ] - }, - { - "name": "phpspec/prophecy", - "version": "1.8.0", - "version_normalized": "1.8.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "time": "2018-08-05T17:53:17+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ] - }, - { - "name": "phpunit/php-code-coverage", - "version": "5.3.2", - "version_normalized": "5.3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-xdebug": "^2.5.5" - }, - "time": "2018-04-06T15:36:58+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.3.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ] - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "version_normalized": "1.4.5.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2017-11-27T13:52:08+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ] - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "version_normalized": "1.2.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2015-06-21T13:50:34+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ] - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "version_normalized": "1.0.9.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "time": "2017-02-26T11:10:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ] - }, - { - "name": "phpunit/php-token-stream", - "version": "2.0.2", - "version_normalized": "2.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2.4" - }, - "time": "2017-11-27T05:48:46+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ] - }, - { - "name": "phpunit/phpunit", - "version": "6.5.14", - "version_normalized": "6.5.14.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.9", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" - }, - "time": "2019-02-01T05:22:47+00:00", - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.5.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ] - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.10", - "version_normalized": "5.0.10.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5.11" - }, - "suggest": { - "ext-soap": "*" - }, - "time": "2018-08-09T05:50:03+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "abandoned": true - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "time": "2017-03-04T06:30:41+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/" - }, - { - "name": "sebastian/comparator", - "version": "2.1.3", - "version_normalized": "2.1.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.4" - }, - "time": "2018-02-01T13:46:46+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ] - }, - { - "name": "sebastian/diff", - "version": "2.0.1", - "version_normalized": "2.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2" - }, - "time": "2017-08-03T08:09:46+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ] - }, - { - "name": "sebastian/environment", - "version": "3.1.0", - "version_normalized": "3.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.1" - }, - "time": "2017-07-01T08:51:00+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ] - }, - { - "name": "sebastian/exporter", - "version": "3.1.0", - "version_normalized": "3.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "time": "2017-04-03T13:19:02+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ] - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "time": "2017-04-27T15:39:26+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ] - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "version_normalized": "3.0.3.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "time": "2017-08-03T12:35:26+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "version_normalized": "1.1.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "time": "2017-03-29T09:07:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "version_normalized": "3.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "time": "2017-03-03T06:23:57+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context" - }, - { - "name": "sebastian/resource-operations", - "version": "1.0.0", - "version_normalized": "1.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "time": "2015-07-28T20:34:47+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "version_normalized": "2.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "time": "2016-10-03T07:35:21+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.4.2", - "version_normalized": "3.4.2.0", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", - "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "time": "2019-04-10T23:49:02+00:00", - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ] - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.11.0", - "version_normalized": "1.11.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "82ebae02209c21113908c229e9883c419720738a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", - "reference": "82ebae02209c21113908c229e9883c419720738a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "time": "2019-02-06T07:57:58+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - }, - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ] - }, - { - "name": "theseer/tokenizer", - "version": "1.1.2", - "version_normalized": "1.1.2.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8", - "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "time": "2019-04-04T09:56:43+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats" - }, - { - "name": "webmozart/assert", - "version": "1.4.0", - "version_normalized": "1.4.0.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "time": "2018-12-25T11:19:39+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ] - }, - { - "name": "woocommerce/woocommerce-sniffs", - "version": "0.0.6", - "version_normalized": "0.0.6.0", - "source": { - "type": "git", - "url": "https://github.com/woocommerce/woocommerce-sniffs.git", - "reference": "a3032bdddd60c71d1330f591e1a9128e115f81ee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/a3032bdddd60c71d1330f591e1a9128e115f81ee", - "reference": "a3032bdddd60c71d1330f591e1a9128e115f81ee", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", - "php": ">=7.0", - "phpcompatibility/phpcompatibility-wp": "2.0.0", - "wp-coding-standards/wpcs": "^1.2" - }, - "time": "2019-03-11T15:30:23+00:00", - "type": "phpcodesniffer-standard", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Claudio Sanches", - "email": "claudio@automattic.com" - } - ], - "description": "WooCommerce sniffs", - "keywords": [ - "phpcs", - "standards", - "woocommerce", - "wordpress" - ] - }, - { - "name": "wp-coding-standards/wpcs", - "version": "1.2.1", - "version_normalized": "1.2.1.0", - "source": { - "type": "git", - "url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git", - "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c", - "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" - }, - "require-dev": { - "phpcompatibility/php-compatibility": "^9.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." - }, - "time": "2018-12-18T09:43:51+00:00", - "type": "phpcodesniffer-standard", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Contributors", - "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", - "keywords": [ - "phpcs", - "standards", - "wordpress" - ] - } -] From 977a84cdce362d12fc6864a44bcaa126330bca30 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 19:06:10 +0100 Subject: [PATCH 104/440] Default type --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 3a71677b536..2d30523e350 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,6 @@ "name": "woocommerce/woocommerce-rest-api", "description": "The WooCommerce core REST API.", "homepage": "https://github.com/woocommerce/woocommerce-rest-api", - "type": "wordpress-plugin", "license": "GPL-3.0-or-later", "prefer-stable": true, "minimum-stability": "dev", From a986bfc4c0381a8f6282cbc716495c6a93f6b98b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 19:12:46 +0100 Subject: [PATCH 105/440] project type --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 2d30523e350..2c6b8fd7ece 100644 --- a/composer.json +++ b/composer.json @@ -2,6 +2,7 @@ "name": "woocommerce/woocommerce-rest-api", "description": "The WooCommerce core REST API.", "homepage": "https://github.com/woocommerce/woocommerce-rest-api", + "type": "project", "license": "GPL-3.0-or-later", "prefer-stable": true, "minimum-stability": "dev", From ee949427e3d7a0f7d8dcc1d5170ebd687f486344 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 12 Jun 2019 20:47:46 +0100 Subject: [PATCH 106/440] New autoloader --- .scrutinizer.yml | 1 + classmap.php | 104 +++++++++++++++++++++++++++++++++++++++++++++ composer.json | 25 ++++++++++- composer.lock | 50 +++++++++++++++++++++- init.php | 8 +++- src/Autoloader.php | 82 +++++++++++++++++++++++++++++++++++ src/Server.php | 6 --- 7 files changed, 267 insertions(+), 9 deletions(-) create mode 100644 classmap.php create mode 100644 src/Autoloader.php diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 261f5dcc6d9..01ebf9d2aac 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -27,3 +27,4 @@ filter: - src/RestApi/Version2/ - src/RestApi/Version3/ - unit-tests/ + - vendor/ diff --git a/classmap.php b/classmap.php new file mode 100644 index 00000000000..1120d34c766 --- /dev/null +++ b/classmap.php @@ -0,0 +1,104 @@ + $baseDir . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', +); diff --git a/composer.json b/composer.json index 2c6b8fd7ece..714453b2d35 100644 --- a/composer.json +++ b/composer.json @@ -4,11 +4,26 @@ "homepage": "https://github.com/woocommerce/woocommerce-rest-api", "type": "project", "license": "GPL-3.0-or-later", + "type": "wordpress-plugin", "prefer-stable": true, "minimum-stability": "dev", "require-dev": { "phpunit/phpunit": "6.5.14", - "woocommerce/woocommerce-sniffs": "0.0.6" + "woocommerce/woocommerce-sniffs": "0.0.6", + "slowprog/composer-copy-file": "~0.3" + }, + "scripts": { + "post-install-cmd": [ + "composer dump-autoload" + ], + "post-update-cmd": [ + "composer dump-autoload" + ], + "pre-autoload-dump": [ + "composer dump-autoload --no-dev --no-scripts", + "SlowProg\\CopyFile\\ScriptHandler::copy", + "sed -i '' 's/\\$baseDir = dirname(\\$vendorDir)/\\$baseDir = __DIR__/g' classmap.php" + ] }, "autoload": { "classmap": [ @@ -19,5 +34,13 @@ "psr-4": { "WooCommerce\\RestApi\\": "src/" } + }, + "extra": { + "copy-file": { + "vendor/composer/autoload_classmap.php": "classmap.php" + }, + "copy-file-dev": { + "vendor/composer/autoload_classmap.php": "classmap.php" + } } } diff --git a/composer.lock b/composer.lock index b6abe1a4fcc..e5d3819d5a8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5ccf61a66c975a3a1861e095855c10e4", + "content-hash": "e99b4d430b010135822c6362c7ebd4a6", "packages": [], "packages-dev": [ { @@ -1604,6 +1604,54 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "slowprog/composer-copy-file", + "version": "0.3.1", + "source": { + "type": "git", + "url": "https://github.com/slowprog/CopyFile.git", + "reference": "5a82ba4613948f70b2d4b041c13c1c9259fc6477" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slowprog/CopyFile/zipball/5a82ba4613948f70b2d4b041c13c1c9259fc6477", + "reference": "5a82ba4613948f70b2d4b041c13c1c9259fc6477", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "mikey179/vfsstream": "~1", + "php-mock/php-mock-phpunit": "~1", + "phpunit/phpunit": "5.7.27", + "symfony/filesystem": "~2.7", + "symfony/finder": "~2.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "SlowProg\\CopyFile\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Tyshev", + "email": "slowprog@gmail.com" + } + ], + "description": "Composer script copying your files after install", + "homepage": "https://github.com/SlowProg/composer-copy-file", + "keywords": [ + "copy file" + ], + "time": "2019-01-10T05:06:10+00:00" + }, { "name": "squizlabs/php_codesniffer", "version": "3.4.2", diff --git a/init.php b/init.php index 8085afe0a10..76f449f9bea 100644 --- a/init.php +++ b/init.php @@ -6,6 +6,12 @@ */ return function() { - require __DIR__ . '/src/Server.php'; + if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { + require __DIR__ . '/vendor/autoload.php'; + } else { + require __DIR__ . '/src/Autoloader.php'; + $classmap = require 'classmap.php'; + \WooCommerce\RestApi\Autoloader::register( $classmap ); + } \WooCommerce\RestApi\Server::instance()->init(); }; diff --git a/src/Autoloader.php b/src/Autoloader.php new file mode 100644 index 00000000000..805b072ebbb --- /dev/null +++ b/src/Autoloader.php @@ -0,0 +1,82 @@ + Date: Thu, 13 Jun 2019 10:47:16 +0100 Subject: [PATCH 107/440] code standards --- .scrutinizer.yml | 7 +-- src/Controllers/Version4/Data/Continents.php | 8 +-- src/Controllers/Version4/Data/Countries.php | 4 +- src/Controllers/Version4/Data/Currencies.php | 4 +- src/Controllers/Version4/Data/DownloadIPs.php | 2 +- src/Controllers/Version4/Orders.php | 38 ++++++------- .../Version4/ProductAttributeTerms.php | 10 ++-- .../Version4/ProductShippingClasses.php | 2 +- src/Controllers/Version4/Products.php | 54 ++++++++++++------- 9 files changed, 72 insertions(+), 57 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 01ebf9d2aac..123a68901cd 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -23,8 +23,9 @@ checks: verify_property_names: false filter: excluded_paths: - - src/RestApi/Version1/ - - src/RestApi/Version2/ - - src/RestApi/Version3/ + - src/Controllers/Version1/ + - src/Controllers/Version2/ + - src/Controllers/Version3/ - unit-tests/ - vendor/ + - classmap.php diff --git a/src/Controllers/Version4/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php index 69b76280515..557f9023448 100644 --- a/src/Controllers/Version4/Data/Continents.php +++ b/src/Controllers/Version4/Data/Continents.php @@ -67,7 +67,7 @@ class Continents extends DataController { * Return the list of countries and states for a given continent. * * @since 3.5.0 - * @param string $continent_code Continent code. + * @param string $continent_code Continent code. * @param \WP_REST_Request $request Request data. * @return array|mixed Response data, ready for insertion into collection data. */ @@ -175,7 +175,7 @@ class Continents extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $data = $this->get_continent( strtoupper( $request['location'] ), $request ); @@ -189,7 +189,7 @@ class Continents extends DataController { * Prepare the data object for response. * * @since 3.5.0 - * @param object $item Data object. + * @param object $item Data object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ @@ -206,7 +206,7 @@ class Continents extends DataController { * Allows modification of the loction data right before it is returned. * * @param \WP_REST_Response $response The response object. - * @param array $item The original list of continent(s), countries, and states. + * @param array $item The original list of continent(s), countries, and states. * @param \WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'woocommerce_rest_prepare_data_continent', $response, $item, $request ); diff --git a/src/Controllers/Version4/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php index c1993db8583..60c78e97d73 100644 --- a/src/Controllers/Version4/Data/Countries.php +++ b/src/Controllers/Version4/Data/Countries.php @@ -66,7 +66,7 @@ class Countries extends DataController { /** * Get a list of countries and states. * - * @param string $country_code Country code. + * @param string $country_code Country code. * @param \WP_REST_Request $request Request data. * @return array|mixed Response data, ready for insertion into collection data. */ @@ -136,7 +136,7 @@ class Countries extends DataController { * Prepare the data object for response. * * @since 3.5.0 - * @param object $item Data object. + * @param object $item Data object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ diff --git a/src/Controllers/Version4/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php index 3974edcaeb6..169767cc29c 100644 --- a/src/Controllers/Version4/Data/Currencies.php +++ b/src/Controllers/Version4/Data/Currencies.php @@ -76,7 +76,7 @@ class Currencies extends DataController { /** * Get currency information. * - * @param string $code Currency code. + * @param string $code Currency code. * @param \WP_REST_Request $request Request data. * @return array|mixed Response data, ready for insertion into collection data. */ @@ -142,7 +142,7 @@ class Currencies extends DataController { /** * Prepare the data object for response. * - * @param object $item Data object. + * @param object $item Data object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ diff --git a/src/Controllers/Version4/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php index 9d27f037d94..07d737792b7 100644 --- a/src/Controllers/Version4/Data/DownloadIPs.php +++ b/src/Controllers/Version4/Data/DownloadIPs.php @@ -84,7 +84,7 @@ class DownloadIPs extends DataController { * Prepare the data object for response. * * @since 3.5.0 - * @param object $item Data object. + * @param object $item Data object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index d1e85b61850..a082444c830 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -131,7 +131,7 @@ class Orders extends AbstractObjectsController { * * @since 3.0.0 * @param int $id Object ID. - * @return WC_Data|bool + * @return \WC_Data|bool */ protected function get_object( $id ) { $order = wc_get_order( $id ); @@ -146,7 +146,7 @@ class Orders extends AbstractObjectsController { /** * Expands an order item to get its data. * - * @param WC_Order_item $item Order item data. + * @param \WC_Order_item $item Order item data. * @return array */ protected function get_order_item_data( $item ) { @@ -198,7 +198,7 @@ class Orders extends AbstractObjectsController { * Get formatted item data. * * @since 3.0.0 - * @param WC_Data $object WC_Data instance. + * @param \WC_Data $object WC_Data instance. * @return array */ protected function get_formatted_item_data( $object ) { @@ -312,7 +312,7 @@ class Orders extends AbstractObjectsController { * refers to object type being prepared for the response. * * @param \WP_REST_Response $response The response object. - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); @@ -460,7 +460,7 @@ class Orders extends AbstractObjectsController { /** * Prepare a single order for create or update. * - * @throws WC_REST_Exception When fails to set any item. + * @throws \WC_REST_Exception When fails to set any item. * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data @@ -522,7 +522,7 @@ class Orders extends AbstractObjectsController { * The dynamic portion of the hook name, `$this->post_type`, * refers to the object type slug. * - * @param WC_Data $order Object object. + * @param \WC_Data $order Object object. * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ @@ -531,10 +531,10 @@ class Orders extends AbstractObjectsController { /** * Save an object data. - * * + * * @param \WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. - * @return WC_Data|\WP_Error + * @return \WC_Data|\WP_Error * @throws \WC_REST_Exception But all errors are validated before returning any data. */ protected function save_object( $request, $creating = false ) { @@ -710,8 +710,8 @@ class Orders extends AbstractObjectsController { * @param array $posted $shipping Item data. * @param string $action 'create' to add shipping or 'update' to update it. * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Shipping - * @throws WC_REST_Exception Invalid data, server error. + * @return \WC_Order_Item_Shipping + * @throws \WC_REST_Exception Invalid data, server error. */ protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { $item = is_null( $item ) ? new \WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; @@ -734,8 +734,8 @@ class Orders extends AbstractObjectsController { * @param array $posted Item data. * @param string $action 'create' to add fee or 'update' to update it. * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Fee - * @throws WC_REST_Exception Invalid data, server error. + * @return \WC_Order_Item_Fee + * @throws \WC_REST_Exception Invalid data, server error. */ protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { $item = is_null( $item ) ? new \WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; @@ -758,8 +758,8 @@ class Orders extends AbstractObjectsController { * @param array $posted Item data. * @param string $action 'create' to add coupon or 'update' to update it. * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Coupon - * @throws WC_REST_Exception Invalid data, server error. + * @return \WC_Order_Item_Coupon + * @throws \WC_REST_Exception Invalid data, server error. */ protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) { $item = is_null( $item ) ? new \WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; @@ -781,10 +781,10 @@ class Orders extends AbstractObjectsController { * When updating, the item ID provided is checked to ensure it is associated * with the order. * - * @param WC_Order $order order object. - * @param string $item_type The item type. - * @param array $posted item provided in the request body. - * @throws WC_REST_Exception If item ID is not associated with order. + * @param \WC_Order $order order object. + * @param string $item_type The item type. + * @param array $posted item provided in the request body. + * @throws \WC_REST_Exception If item ID is not associated with order. */ protected function set_item( $order, $item_type, $posted ) { global $wpdb; @@ -1707,7 +1707,7 @@ class Orders extends AbstractObjectsController { public function get_collection_params() { $params = parent::get_collection_params(); - $params['status'] = array( + $params['status'] = array( 'default' => 'any', 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce' ), 'type' => 'array', diff --git a/src/Controllers/Version4/ProductAttributeTerms.php b/src/Controllers/Version4/ProductAttributeTerms.php index eeb20f54edd..7d831e0b633 100644 --- a/src/Controllers/Version4/ProductAttributeTerms.php +++ b/src/Controllers/Version4/ProductAttributeTerms.php @@ -31,7 +31,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { $this->namespace, '/' . $this->rest_base, array( - 'args' => array( + 'args' => array( 'attribute_id' => array( 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), 'type' => 'integer', @@ -67,8 +67,8 @@ class ProductAttributeTerms extends AbstractTermsContoller { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( + 'args' => array( + 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), @@ -133,7 +133,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { /** * Prepare a single product attribute term output for response. * - * @param WP_Term $item Term object. + * @param \WP_Term $item Term object. * @param \WP_REST_Request $request Request params. * @return \WP_REST_Response $response */ @@ -173,7 +173,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { /** * Update term meta fields. * - * @param WP_Term $term Term object. + * @param \WP_Term $term Term object. * @param \WP_REST_Request $request Request params. * @return bool|\WP_Error */ diff --git a/src/Controllers/Version4/ProductShippingClasses.php b/src/Controllers/Version4/ProductShippingClasses.php index 0df19fc7600..57c3a5fc5c5 100644 --- a/src/Controllers/Version4/ProductShippingClasses.php +++ b/src/Controllers/Version4/ProductShippingClasses.php @@ -33,7 +33,7 @@ class ProductShippingClasses extends AbstractTermsContoller { /** * Prepare a single product shipping class output for response. * - * @param obj $item Term object. + * @param object $item Term object. * @param \WP_REST_Request $request Request params. * @return \WP_REST_Response $response */ diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 1259175b973..bd27277997a 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -136,7 +136,7 @@ class Products extends AbstractObjectsController { * @param int $id Object ID. * * @since 3.0.0 - * @return WC_Data + * @return \WC_Data */ protected function get_object( $id ) { return wc_get_product( $id ); @@ -145,7 +145,7 @@ class Products extends AbstractObjectsController { /** * Prepare a single product output for response. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * * @since 3.0.0 @@ -177,7 +177,7 @@ class Products extends AbstractObjectsController { * refers to object type being prepared for the response. * * @param \WP_REST_Response $response The response object. - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); @@ -187,8 +187,8 @@ class Products extends AbstractObjectsController { * Prepare a single product for create or update. * * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WP_Error|WC_Data + * @param bool $creating If is creating a new object. + * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; @@ -1173,7 +1173,7 @@ class Products extends AbstractObjectsController { /** * Prepare links for the request. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * * @return array Links for the given post. @@ -1368,11 +1368,9 @@ class Products extends AbstractObjectsController { /** * Save default attributes. * - * @param WC_Product $product Product instance. + * @param \WC_Product $product Product instance. * @param \WP_REST_Request $request Request data. - * - * @since 3.0.0 - * @return WC_Product + * @return \WC_Product */ protected function save_default_attributes( $product, $request ) { if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { @@ -2187,12 +2185,13 @@ class Products extends AbstractObjectsController { public function get_collection_params() { $params = parent::get_collection_params(); - $params['slug'] = array( + $params['slug'] = array( 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); - $params['status'] = array( + + $params['status'] = array( 'default' => 'any', 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), 'type' => 'string', @@ -2200,49 +2199,57 @@ class Products extends AbstractObjectsController { 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); - $params['type'] = array( + + $params['type'] = array( 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_types() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); - $params['sku'] = array( + + $params['sku'] = array( 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); - $params['featured'] = array( + + $params['featured'] = array( 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); - $params['category'] = array( + + $params['category'] = array( 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); - $params['tag'] = array( + + $params['tag'] = array( 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); + $params['shipping_class'] = array( 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); - $params['attribute'] = array( + + $params['attribute'] = array( 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); + $params['attribute_term'] = array( 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), 'type' => 'string', @@ -2259,24 +2266,28 @@ class Products extends AbstractObjectsController { 'validate_callback' => 'rest_validate_request_arg', ); } - $params['on_sale'] = array( + + $params['on_sale'] = array( 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); + $params['min_price'] = array( 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); + $params['max_price'] = array( 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); + $params['stock_status'] = array( 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), 'type' => 'string', @@ -2284,17 +2295,20 @@ class Products extends AbstractObjectsController { 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); + $params['low_in_stock'] = array( 'description' => __( 'Limit result set to products that are low or out of stock.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'wc_string_to_bool', ); - $params['search'] = array( + + $params['search'] = array( 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); return $params; From e3b1d88506f66c587ddfaf172315d2e75f6fa1e8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 10:57:16 +0100 Subject: [PATCH 108/440] Pass directory when registering package --- woocommerce-rest-api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index dc3fc671cac..cca8b5c50fe 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -31,7 +31,7 @@ $register_callback = function() use ( $version, $init_callback ) { if ( ! is_callable( array( wc()->api, 'register' ) ) ) { return; } - wc()->api->register( $version, $init_callback ); + wc()->api->register( $version, $init_callback, __DIR__ ); }; add_action( 'woocommerce_loaded', $register_callback ); From ddfdb5b2f82add55470766c1f9c2469dc9ab92ce Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 11:13:25 +0100 Subject: [PATCH 109/440] Remove unused code from v4 and v4 tests --- .../Version4/AbstractController.php | 10 +- .../Version4/AbstractObjectsController.php | 290 +++++-- .../Version4/AbstractPostsController.php | 714 ------------------ unit-tests/Tests/Version4/AdminNotes.php | 325 -------- unit-tests/Tests/Version4/Leaderboards.php | 175 ----- .../Tests/Version4/Reports/Categories.php | 169 ----- unit-tests/Tests/Version4/Reports/Coupons.php | 178 ----- .../Tests/Version4/Reports/CouponsStats.php | 173 ----- .../Tests/Version4/Reports/CustomerStats.php | 162 ---- .../Tests/Version4/Reports/Customers.php | 392 ---------- .../Tests/Version4/Reports/DownloadStats.php | 358 --------- .../Tests/Version4/Reports/Downloads.php | 409 ---------- unit-tests/Tests/Version4/Reports/Import.php | 393 ---------- .../Tests/Version4/Reports/OrderStats.php | 119 --- unit-tests/Tests/Version4/Reports/Orders.php | 118 --- .../Reports/PerformanceIndicators.php | 172 ----- .../Tests/Version4/Reports/ProductStats.php | 161 ---- .../Tests/Version4/Reports/Products.php | 161 ---- .../Tests/Version4/Reports/RevenueStats.php | 126 ---- unit-tests/Tests/Version4/Reports/Stock.php | 114 --- .../Tests/Version4/Reports/StockStats.php | 131 ---- .../Tests/Version4/Reports/TaxStats.php | 163 ---- unit-tests/Tests/Version4/Reports/Taxes.php | 351 --------- .../Tests/Version4/Reports/Variations.php | 173 ----- 24 files changed, 235 insertions(+), 5302 deletions(-) delete mode 100644 src/Controllers/Version4/AbstractPostsController.php delete mode 100644 unit-tests/Tests/Version4/AdminNotes.php delete mode 100644 unit-tests/Tests/Version4/Leaderboards.php delete mode 100644 unit-tests/Tests/Version4/Reports/Categories.php delete mode 100644 unit-tests/Tests/Version4/Reports/Coupons.php delete mode 100644 unit-tests/Tests/Version4/Reports/CouponsStats.php delete mode 100644 unit-tests/Tests/Version4/Reports/CustomerStats.php delete mode 100644 unit-tests/Tests/Version4/Reports/Customers.php delete mode 100644 unit-tests/Tests/Version4/Reports/DownloadStats.php delete mode 100644 unit-tests/Tests/Version4/Reports/Downloads.php delete mode 100644 unit-tests/Tests/Version4/Reports/Import.php delete mode 100644 unit-tests/Tests/Version4/Reports/OrderStats.php delete mode 100644 unit-tests/Tests/Version4/Reports/Orders.php delete mode 100644 unit-tests/Tests/Version4/Reports/PerformanceIndicators.php delete mode 100644 unit-tests/Tests/Version4/Reports/ProductStats.php delete mode 100644 unit-tests/Tests/Version4/Reports/Products.php delete mode 100644 unit-tests/Tests/Version4/Reports/RevenueStats.php delete mode 100644 unit-tests/Tests/Version4/Reports/Stock.php delete mode 100644 unit-tests/Tests/Version4/Reports/StockStats.php delete mode 100644 unit-tests/Tests/Version4/Reports/TaxStats.php delete mode 100644 unit-tests/Tests/Version4/Reports/Taxes.php delete mode 100644 unit-tests/Tests/Version4/Reports/Variations.php diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index e073d8d502a..cedb052b590 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -331,7 +331,7 @@ abstract class AbstractController extends WP_REST_Controller { * @return string|\WP_Error */ public function validate_setting_checkbox_field( $value, $setting ) { - if ( in_array( $value, array( 'yes', 'no' ) ) ) { + if ( in_array( $value, array( 'yes', 'no' ), true ) ) { return $value; } elseif ( empty( $value ) ) { $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; @@ -377,7 +377,7 @@ abstract class AbstractController extends WP_REST_Controller { */ protected function add_meta_query( $args, $meta_query ) { if ( empty( $args['meta_query'] ) ) { - $args['meta_query'] = array(); + $args['meta_query'] = []; // phpcs:ignore } $args['meta_query'][] = $meta_query; @@ -401,7 +401,7 @@ abstract class AbstractController extends WP_REST_Controller { 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( - 'type' => 'object', + 'type' => 'object', ), ), 'update' => array( @@ -409,7 +409,7 @@ abstract class AbstractController extends WP_REST_Controller { 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( - 'type' => 'object', + 'type' => 'object', ), ), 'delete' => array( @@ -417,7 +417,7 @@ abstract class AbstractController extends WP_REST_Controller { 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( - 'type' => 'integer', + 'type' => 'integer', ), ), ), diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 047110ffe3e..1c593393341 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -12,7 +12,7 @@ defined( 'ABSPATH' ) || exit; /** * CRUD Object Controller. */ -abstract class AbstractObjectsController extends AbstractPostsController { +abstract class AbstractObjectsController extends AbstractController { /** * If object is hierarchical. @@ -21,17 +21,38 @@ abstract class AbstractObjectsController extends AbstractPostsController { */ protected $hierarchical = false; + /** + * Post type. + * + * @var string + */ + protected $post_type = ''; + /** * Get object. * * @param int $id Object ID. - * @return object WC_Data object or \WP_Error object. + * @return \WP_Error|\WC_Data */ protected function get_object( $id ) { // translators: %s: Class method name. return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); } + /** + * Check if a given request has access to read items. + * + * @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_post_permissions( $this->post_type, 'read' ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + /** * Check if a given request has access to read an item. * @@ -48,6 +69,20 @@ abstract class AbstractObjectsController extends AbstractPostsController { return true; } + /** + * Check if a given request has access to create an item. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + /** * Check if a given request has access to update an item. * @@ -80,6 +115,21 @@ abstract class AbstractObjectsController extends AbstractPostsController { return true; } + /** + * Check if a given request has access batch create, update and delete items. + * + * @param \WP_REST_Request $request Full details about the request. + * + * @return boolean|\WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + /** * Get object permalink. * @@ -94,7 +144,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Prepares the object for the REST response. * * @since 3.0.0 - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return \WP_Error|\WP_REST_Response Response object on success, or \WP_Error object on failure. */ @@ -108,7 +158,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * * @since 3.0.0 * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. + * @param bool $creating If is creating a new object. * @return \WP_Error|WC_Data The prepared item, or \WP_Error object on failure. */ protected function prepare_object_for_database( $request, $creating = false ) { @@ -144,7 +194,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * * @since 3.0.0 * @param \WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. + * @param bool $creating If is creating a new object. * @return WC_Data|\WP_Error */ protected function save_object( $request, $creating = false ) { @@ -169,7 +219,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Create a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -196,7 +246,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Fires after a single object is created or updated via the REST API. * - * @param WC_Data $object Inserted object. + * @param \WC_Data $object Inserted object. * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating object, false when updating. */ @@ -215,7 +265,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Update a single post. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function update_item( $request ) { $object = $this->get_object( (int) $request['id'] ); @@ -241,7 +291,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Fires after a single object is created or updated via the REST API. * - * @param WC_Data $object Inserted object. + * @param \WC_Data $object Inserted object. * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating object, false when updating. */ @@ -298,7 +348,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * 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 array $args Key value array of query var to query value. * @param \WP_REST_Request $request The request used. */ $args = apply_filters( "woocommerce_rest_{$this->post_type}_object_query", $args, $request ); @@ -337,7 +387,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { * Get a collection of posts. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $query_args = $this->prepare_objects_query( $request ); @@ -370,7 +420,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { $attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] ); $attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset ); if ( isset( $request[ $attrib_name ] ) ) { - $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); + $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); } } } @@ -455,7 +505,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Fires after a single object is deleted or trashed via the REST API. * - * @param WC_Data $object The deleted or trashed object. + * @param \WC_Data $object The deleted or trashed object. * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ @@ -467,7 +517,7 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Can this object be trashed? * - * @oaram object $object Object to check. + * @param object $object Object to check. * @return boolean */ protected function supports_trash( $object ) { @@ -487,13 +537,13 @@ abstract class AbstractObjectsController extends AbstractPostsController { /** * Prepare links for the request. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ protected function prepare_links( $object, $request ) { $links = array( - 'self' => array( + 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), ), 'collection' => array( @@ -515,83 +565,92 @@ abstract class AbstractObjectsController extends AbstractPostsController { $params['context']['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, + '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', + '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['search'] = array( - 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', + 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + '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', + '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', + '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['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + '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', + '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', + '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' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', + '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( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( 'date', 'id', 'include', 'title', 'slug', ), - 'validate_callback' => 'rest_validate_request_arg', + 'validate_callback' => 'rest_validate_request_arg', ); if ( $this->hierarchical ) { @@ -599,16 +658,17 @@ abstract class AbstractObjectsController extends AbstractPostsController { 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + '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', + 'type' => 'integer', ), 'sanitize_callback' => 'wp_parse_id_list', 'default' => array(), @@ -626,8 +686,118 @@ abstract class AbstractObjectsController extends AbstractPostsController { * `rest_{$this->post_type}_query` filter to set \WP_Query parameters. * * @param array $query_params JSON Schema-formatted collection parameters. - * @param WP_Post_Type $post_type Post type object. + * @param \WP_Post_Type $post_type Post type object. */ return apply_filters( "rest_{$this->post_type}_collection_params", $params, $this->post_type ); } + + /** + * Determine the allowed query_vars for a get_items() response and + * prepare for \WP_Query. + * + * @param array $prepared_args Prepared arguments. + * @param \WP_REST_Request $request Request object. + * @return array $query_args + */ + protected function prepare_items_query( $prepared_args = array(), $request = null ) { + $valid_vars = array_flip( $this->get_allowed_query_vars() ); + $query_args = array(); + foreach ( $valid_vars as $var => $index ) { + if ( isset( $prepared_args[ $var ] ) ) { + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $var, refers to the query_var key. + * + * @param mixed $prepared_args[ $var ] The query_var value. + */ + $query_args[ $var ] = apply_filters( "woocommerce_rest_query_var_{$var}", $prepared_args[ $var ] ); + } + } + + $query_args['ignore_sticky_posts'] = true; + + if ( 'include' === $query_args['orderby'] ) { + $query_args['orderby'] = 'post__in'; + } elseif ( 'id' === $query_args['orderby'] ) { + $query_args['orderby'] = 'ID'; // ID must be capitalized. + } elseif ( 'slug' === $query_args['orderby'] ) { + $query_args['orderby'] = 'name'; + } + + return $query_args; + } + + /** + * Get all the WP Query vars that are allowed for the API request. + * + * @return array + */ + protected function get_allowed_query_vars() { + global $wp; + + /** + * Filter the publicly allowed query vars. + * + * Allows adjusting of the default query vars that are made public. + * + * @param array Array of allowed \WP_Query query vars. + */ + $valid_vars = apply_filters( 'query_vars', $wp->public_query_vars ); + + $post_type_obj = get_post_type_object( $this->post_type ); + if ( current_user_can( $post_type_obj->cap->edit_posts ) ) { + /** + * Filter the allowed 'private' query vars for authorized users. + * + * If the user has the `edit_posts` capability, we also allow use of + * private query parameters, which are only undesirable on the + * frontend, but are safe for use in query strings. + * + * To disable anyway, use + * `add_filter( 'woocommerce_rest_private_query_vars', '__return_empty_array' );` + * + * @param array $private_query_vars Array of allowed query vars for authorized users. + * } + */ + $private = apply_filters( 'woocommerce_rest_private_query_vars', $wp->private_query_vars ); + $valid_vars = array_merge( $valid_vars, $private ); + } + // Define our own in addition to WP's normal vars. + $rest_valid = array( + 'date_query', + 'ignore_sticky_posts', + 'offset', + 'post__in', + 'post__not_in', + 'post_parent', + 'post_parent__in', + 'post_parent__not_in', + 'posts_per_page', + 'meta_query', + 'tax_query', + 'meta_key', + 'meta_value', + 'meta_compare', + 'meta_value_num', + ); + $valid_vars = array_merge( $valid_vars, $rest_valid ); + + /** + * Filter allowed query vars for the REST API. + * + * This filter allows you to add or remove query vars from the final allowed + * list for all requests, including unauthenticated ones. To alter the + * vars for editors only. + * + * @param array { + * Array of allowed \WP_Query query vars. + * + * @param string $allowed_query_var The query var to allow. + * } + */ + $valid_vars = apply_filters( 'woocommerce_rest_query_vars', $valid_vars ); + + return $valid_vars; + } } diff --git a/src/Controllers/Version4/AbstractPostsController.php b/src/Controllers/Version4/AbstractPostsController.php deleted file mode 100644 index c07b7fe09d6..00000000000 --- a/src/Controllers/Version4/AbstractPostsController.php +++ /dev/null @@ -1,714 +0,0 @@ -post_type, 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $post = get_post( (int) $request['id'] ); - - if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $post = get_post( (int) $request['id'] ); - - if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - $post = get_post( (int) $request['id'] ); - - if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return boolean|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $post = get_post( $id ); - - if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); - } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $data = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $data ); - - if ( $this->public ) { - $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) ); - } - - return $response; - } - - /** - * Create a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $post = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $post ) ) { - return $post; - } - - $post->post_type = $this->post_type; - $post_id = wp_insert_post( $post, true ); - - if ( is_wp_error( $post_id ) ) { - - if ( in_array( $post_id->get_error_code(), array( 'db_insert_error' ) ) ) { - $post_id->add_data( array( 'status' => 500 ) ); - } else { - $post_id->add_data( array( 'status' => 400 ) ); - } - return $post_id; - } - $post->ID = $post_id; - $post = get_post( $post_id ); - - $this->update_additional_fields_for_object( $post, $request ); - - // Add meta fields. - $meta_fields = $this->add_post_meta_fields( $post, $request ); - if ( is_wp_error( $meta_fields ) ) { - // Remove post. - $this->delete_post( $post ); - - return $meta_fields; - } - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post_id ) ) ); - - return $response; - } - - /** - * Add post meta fields. - * - * @param WP_Post $post Post Object. - * @param \WP_REST_Request $request \WP_REST_Request Object. - * @return bool|\WP_Error - */ - protected function add_post_meta_fields( $post, $request ) { - return true; - } - - /** - * Delete post. - * - * @param WP_Post $post Post object. - */ - protected function delete_post( $post ) { - wp_delete_post( $post->ID, true ); - } - - /** - * Update a single post. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response - */ - public function update_item( $request ) { - $id = (int) $request['id']; - $post = get_post( $id ); - - if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); - } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - $post = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $post ) ) { - return $post; - } - // Convert the post object to an array, otherwise wp_update_post will expect non-escaped input. - $post_id = wp_update_post( (array) $post, true ); - if ( is_wp_error( $post_id ) ) { - if ( in_array( $post_id->get_error_code(), array( 'db_update_error' ) ) ) { - $post_id->add_data( array( 'status' => 500 ) ); - } else { - $post_id->add_data( array( 'status' => 400 ) ); - } - return $post_id; - } - - $post = get_post( $post_id ); - $this->update_additional_fields_for_object( $post, $request ); - - // Update meta fields. - $meta_fields = $this->update_post_meta_fields( $post, $request ); - if ( is_wp_error( $meta_fields ) ) { - return $meta_fields; - } - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - return rest_ensure_response( $response ); - } - - /** - * Get a collection of posts. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response - */ - public function get_items( $request ) { - $args = array(); - $args['offset'] = $request['offset']; - $args['order'] = $request['order']; - $args['orderby'] = $request['orderby']; - $args['paged'] = $request['page']; - $args['post__in'] = $request['include']; - $args['post__not_in'] = $request['exclude']; - $args['posts_per_page'] = $request['per_page']; - $args['name'] = $request['slug']; - $args['post_parent__in'] = $request['parent']; - $args['post_parent__not_in'] = $request['parent_exclude']; - $args['s'] = $request['search']; - - $args['date_query'] = array(); - // Set before into date query. Date query must be specified as an array of an array. - if ( isset( $request['before'] ) ) { - $args['date_query'][0]['before'] = $request['before']; - } - - // Set after into date query. Date query must be specified as an array of an array. - if ( isset( $request['after'] ) ) { - $args['date_query'][0]['after'] = $request['after']; - } - - if ( 'wc/v1' === $this->namespace ) { - if ( is_array( $request['filter'] ) ) { - $args = array_merge( $args, $request['filter'] ); - unset( $args['filter'] ); - } - } - - // Force the post_type argument, since it's not a user input variable. - $args['post_type'] = $this->post_type; - - /** - * 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_{$this->post_type}_query", $args, $request ); - $query_args = $this->prepare_items_query( $args, $request ); - - $posts_query = new \WP_Query(); - $query_result = $posts_query->query( $query_args ); - - $posts = array(); - foreach ( $query_result as $post ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { - continue; - } - - $data = $this->prepare_item_for_response( $post, $request ); - $posts[] = $this->prepare_response_for_collection( $data ); - } - - $page = (int) $query_args['paged']; - $total_posts = $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; - } - - $max_pages = ceil( $total_posts / (int) $query_args['posts_per_page'] ); - - $response = rest_ensure_response( $posts ); - $response->header( 'X-WP-Total', (int) $total_posts ); - $response->header( 'X-WP-TotalPages', (int) $max_pages ); - - $request_params = $request->get_query_params(); - if ( ! empty( $request_params['filter'] ) ) { - // Normalize the pagination params. - unset( $request_params['filter']['posts_per_page'] ); - unset( $request_params['filter']['paged'] ); - } - $base = add_query_arg( $request_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; - } - - /** - * Delete a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Response|\WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = (bool) $request['force']; - $post = get_post( $id ); - - if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $supports_trash = EMPTY_TRASH_DAYS > 0; - - /** - * Filter whether an item is trashable. - * - * Return false to disable trash support for the item. - * - * @param boolean $supports_trash Whether the item type support trashing. - * @param WP_Post $post The Post object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); - - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - - // If we're forcing, then delete permanently. - if ( $force ) { - $result = wp_delete_post( $id, true ); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); - } - - // Otherwise, only trash if we haven't already. - if ( 'trash' === $post->post_status ) { - /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); - } - - // (Note that internally this falls through to `wp_delete_post` if - // the trash is disabled.) - $result = wp_trash_post( $id ); - } - - if ( ! $result ) { - /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); - } - - /** - * Fires after a single item is deleted or trashed via the REST API. - * - * @param object $post The deleted or trashed item. - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * @return array Links for the given post. - */ - protected function prepare_links( $post, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Determine the allowed query_vars for a get_items() response and - * prepare for \WP_Query. - * - * @param array $prepared_args Prepared arguments. - * @param \WP_REST_Request $request Request object. - * @return array $query_args - */ - protected function prepare_items_query( $prepared_args = array(), $request = null ) { - - $valid_vars = array_flip( $this->get_allowed_query_vars() ); - $query_args = array(); - foreach ( $valid_vars as $var => $index ) { - if ( isset( $prepared_args[ $var ] ) ) { - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $var, refers to the query_var key. - * - * @param mixed $prepared_args[ $var ] The query_var value. - */ - $query_args[ $var ] = apply_filters( "woocommerce_rest_query_var-{$var}", $prepared_args[ $var ] ); - } - } - - $query_args['ignore_sticky_posts'] = true; - - if ( 'include' === $query_args['orderby'] ) { - $query_args['orderby'] = 'post__in'; - } elseif ( 'id' === $query_args['orderby'] ) { - $query_args['orderby'] = 'ID'; // ID must be capitalized. - } elseif ( 'slug' === $query_args['orderby'] ) { - $query_args['orderby'] = 'name'; - } - - return $query_args; - } - - /** - * Get all the WP Query vars that are allowed for the API request. - * - * @return array - */ - protected function get_allowed_query_vars() { - global $wp; - - /** - * Filter the publicly allowed query vars. - * - * Allows adjusting of the default query vars that are made public. - * - * @param array Array of allowed \WP_Query query vars. - */ - $valid_vars = apply_filters( 'query_vars', $wp->public_query_vars ); - - $post_type_obj = get_post_type_object( $this->post_type ); - if ( current_user_can( $post_type_obj->cap->edit_posts ) ) { - /** - * Filter the allowed 'private' query vars for authorized users. - * - * If the user has the `edit_posts` capability, we also allow use of - * private query parameters, which are only undesirable on the - * frontend, but are safe for use in query strings. - * - * To disable anyway, use - * `add_filter( 'woocommerce_rest_private_query_vars', '__return_empty_array' );` - * - * @param array $private_query_vars Array of allowed query vars for authorized users. - * } - */ - $private = apply_filters( 'woocommerce_rest_private_query_vars', $wp->private_query_vars ); - $valid_vars = array_merge( $valid_vars, $private ); - } - // Define our own in addition to WP's normal vars. - $rest_valid = array( - 'date_query', - 'ignore_sticky_posts', - 'offset', - 'post__in', - 'post__not_in', - 'post_parent', - 'post_parent__in', - 'post_parent__not_in', - 'posts_per_page', - 'meta_query', - 'tax_query', - 'meta_key', - 'meta_value', - 'meta_compare', - 'meta_value_num', - ); - $valid_vars = array_merge( $valid_vars, $rest_valid ); - - /** - * Filter allowed query vars for the REST API. - * - * This filter allows you to add or remove query vars from the final allowed - * list for all requests, including unauthenticated ones. To alter the - * vars for editors only. - * - * @param array { - * Array of allowed \WP_Query query vars. - * - * @param string $allowed_query_var The query var to allow. - * } - */ - $valid_vars = apply_filters( 'woocommerce_rest_query_vars', $valid_vars ); - - return $valid_vars; - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['context']['default'] = 'view'; - - $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['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' => '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', - 'id', - 'include', - 'title', - 'slug', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - $post_type_obj = get_post_type_object( $this->post_type ); - - if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) { - $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(), - ); - } - - if ( 'wc/v1' === $this->namespace ) { - $params['filter'] = array( - 'type' => 'object', - 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce' ), - ); - } - - return $params; - } - - /** - * Update post meta fields. - * - * @param WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * @return bool|\WP_Error - */ - protected function update_post_meta_fields( $post, $request ) { - return true; - } -} diff --git a/unit-tests/Tests/Version4/AdminNotes.php b/unit-tests/Tests/Version4/AdminNotes.php deleted file mode 100644 index 090f0cf4b26..00000000000 --- a/unit-tests/Tests/Version4/AdminNotes.php +++ /dev/null @@ -1,325 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup test admin notes data. Called before every test. - * - * @since 3.5.0 - */ - public function setUp() { - if ( ! class_exists( '\WC_Admin_Note' ) ) { - $this->markTestSkipped( 'Skipping admin notes tests - WC_Admin_Note class not found.' ); - return; - } - - parent::setUp(); - wp_set_current_user( self::$user ); - AdminNotesHelper::reset_notes_dbs(); - AdminNotesHelper::add_notes_for_tests(); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting a single note. - * - * @since 3.5.0 - */ - public function test_get_note() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); - $note = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 1, $note['id'] ); - $this->assertEquals( 'PHPUNIT_TEST_NOTE_NAME', $note['name'] ); - $this->assertEquals( \WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL, $note['type'] ); - $this->assertArrayHasKey( 'locale', $note ); - $this->assertEquals( 'PHPUNIT_TEST_NOTE_1_TITLE', $note['title'] ); - - $this->assertEquals( 'PHPUNIT_TEST_NOTE_1_CONTENT', $note['content'] ); - $this->assertEquals( 'info', $note['icon'] ); - $this->assertArrayHasKey( 'content_data', $note ); - $this->assertEquals( 1.23, $note['content_data']->amount ); - $this->assertEquals( \WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED, $note['status'] ); - $this->assertEquals( 'PHPUNIT_TEST', $note['source'] ); - - $this->assertArrayHasKey( 'date_created', $note ); - $this->assertArrayHasKey( 'date_created_gmt', $note ); - $this->assertArrayHasKey( 'date_reminder', $note ); - $this->assertArrayHasKey( 'date_reminder_gmt', $note ); - $this->assertArrayHasKey( 'actions', $note ); - - $this->assertEquals( 'PHPUNIT_TEST_NOTE_1_ACTION_1_SLUG', $note['actions'][0]->name ); - $this->assertEquals( 'http://example.org/wp-admin/admin.php?s=PHPUNIT_TEST_NOTE_1_ACTION_1_URL', $note['actions'][0]->url ); - } - - /** - * Test getting a 404 from invalid ID. - * - * @since 3.5.0 - */ - public function test_get_invalid_note() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/999' ) ); - $note = $response->get_data(); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single note without permission. It should fail. - * - * @since 3.5.0 - */ - public function test_get_note_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single note. - */ - public function test_update_note() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) ); - $note = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'unactioned', $note['status'] ); - - $request = new WP_REST_Request( 'PUT', $this->endpoint . '/1' ); - $request->set_body_params( - array( - 'status' => 'actioned', - ) - ); - - $response = $this->server->dispatch( $request ); - $note = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'actioned', $note['status'] ); - } - - /** - * Test updating a single note without permission. It should fail. - */ - public function test_update_note_without_permission() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'PUT', $this->endpoint . '/1' ); - $request->set_body_params( - array( - 'status' => 'actioned', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting lots of notes. - * - * @since 3.5.0 - */ - public function test_get_notes() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $notes = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 3, count( $notes ) ); - } - - /** - * Test getting notes of a certain type. - * - * @since 3.5.0 - */ - public function test_get_warning_notes() { - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'type' => 'warning' ) ); - $response = $this->server->dispatch( $request ); - $notes = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $notes ) ); - $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' ); - } - - - /** - * Test getting notes of a certain status. - */ - public function test_get_actioned_notes() { - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'status' => 'actioned' ) ); - $response = $this->server->dispatch( $request ); - $notes = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $notes ) ); - $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'status' => 'invalid' ) ); - $response = $this->server->dispatch( $request ); - $notes = $response->get_data(); - - // get_notes returns all results since 'status' is not one of actioned or unactioned. - $this->assertEquals( 3, count( $notes ) ); - } - - /** - * Test note "unsnoozing". - */ - public function test_note_unsnoozing() { - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'status' => 'snoozed' ) ); - $response = $this->server->dispatch( $request ); - $notes = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $notes ) ); - $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_3_TITLE' ); - - // The test snoozed note's reminder date is an hour ago. - \WC_Admin_Notes::unsnooze_notes(); - - $response = $this->server->dispatch( $request ); - $notes = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEmpty( $notes ); - } - - /** - * Test ordering of notes. - */ - public function test_order_notes() { - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'orderby' => 'title', - 'order' => 'asc', - ) - ); - $response = $this->server->dispatch( $request ); - $notes = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 3, count( $notes ) ); - $this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_1_TITLE' ); - $this->assertEquals( $notes[1]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' ); - $this->assertEquals( $notes[2]['title'], 'PHPUNIT_TEST_NOTE_3_TITLE' ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'orderby' => 'status', - 'order' => 'desc', - ) - ); - $response = $this->server->dispatch( $request ); - $notes = $response->get_data(); - - $this->assertEquals( 3, count( $notes ) ); - $this->assertEquals( $notes[0]['status'], \WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED ); - $this->assertEquals( $notes[1]['status'], \WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED ); - $this->assertEquals( $notes[2]['status'], \WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED ); - } - - /** - * Test getting lots of notes without permission. It should fail. - * - * @since 3.5.0 - */ - public function test_get_notes_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting the notes schema. - * - * @since 3.5.0 - */ - public function test_get_notes_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 16, count( $properties ) ); - - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'type', $properties ); - $this->assertArrayHasKey( 'locale', $properties ); - $this->assertArrayHasKey( 'title', $properties ); - - $this->assertArrayHasKey( 'content', $properties ); - $this->assertArrayHasKey( 'icon', $properties ); - $this->assertArrayHasKey( 'content_data', $properties ); - $this->assertArrayHasKey( 'status', $properties ); - $this->assertArrayHasKey( 'source', $properties ); - - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_created_gmt', $properties ); - $this->assertArrayHasKey( 'date_reminder', $properties ); - $this->assertArrayHasKey( 'date_reminder_gmt', $properties ); - $this->assertArrayHasKey( 'actions', $properties ); - $this->assertArrayHasKey( 'is_snoozable', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Leaderboards.php b/unit-tests/Tests/Version4/Leaderboards.php deleted file mode 100644 index af90d308365..00000000000 --- a/unit-tests/Tests/Version4/Leaderboards.php +++ /dev/null @@ -1,175 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server, endpoints, and user info. - */ - public function setUp() { - if ( ! class_exists( '\WC_Admin_Reports_Sync' ) ) { - $this->markTestSkipped( 'Skipping reports tests - WC_Admin_Reports_Sync class not found.' ); - return; - } - parent::setUp(); - wp_set_current_user( self::$user ); - } - - /** - * Test that leaderboards are returned by the endpoint. - */ - public function test_get_leaderboards() { - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'customers', $data[0]['id'] ); - $this->assertEquals( 'coupons', $data[1]['id'] ); - $this->assertEquals( 'categories', $data[2]['id'] ); - $this->assertEquals( 'products', $data[3]['id'] ); - } - - /** - * Test reports schema. - */ - public function test_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertCount( 4, $properties ); - $this->assert_item_schema( $properties ); - - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint . '/allowed' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertCount( 3, $properties ); - $this->assert_allowed_item_schema( $properties ); - } - - /** - * Asserts the item schema is correct. - * - * @param array $schema Item to check schema. - */ - public function assert_item_schema( $schema ) { - $this->assertArrayHasKey( 'id', $schema ); - $this->assertArrayHasKey( 'label', $schema ); - $this->assertArrayHasKey( 'headers', $schema ); - $this->assertArrayHasKey( 'rows', $schema ); - - $header_properties = $schema['headers']['items']['properties']; - $this->assertCount( 1, $header_properties ); - $this->assertArrayHasKey( 'label', $header_properties ); - - $row_properties = $schema['rows']['items']['properties']; - $this->assertCount( 2, $row_properties ); - $this->assertArrayHasKey( 'display', $row_properties ); - $this->assertArrayHasKey( 'value', $row_properties ); - } - - /** - * Asserts the allowed item schema is correct. - * - * @param array $schema Item to check schema. - */ - public function assert_allowed_item_schema( $schema ) { - $this->assertArrayHasKey( 'id', $schema ); - $this->assertArrayHasKey( 'label', $schema ); - $this->assertArrayHasKey( 'headers', $schema ); - - $header_properties = $schema['headers']['items']['properties']; - $this->assertCount( 1, $header_properties ); - $this->assertArrayHasKey( 'label', $header_properties ); - } - - /** - * Test that leaderboards response changes based on applied filters. - */ - public function test_filter_leaderboards() { - add_filter( - 'woocommerce_leaderboards', - function( $leaderboards, $per_page, $after, $before, $persisted_query ) { - $leaderboards[] = array( - 'id' => 'top_widgets', - 'label' => 'Top Widgets', - 'headers' => array( - array( - 'label' => 'Widget Link', - ), - ), - 'rows' => array( - array( - 'display' => wc_admin_url( 'test/path', $persisted_query ), - 'value' => null, - ), - ), - ); - return $leaderboards; - }, - 10, - 5 - ); - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'persisted_query' => '{ "persisted_param": 1 }' ) ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $widgets_leaderboard = end( $data ); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'top_widgets', $widgets_leaderboard['id'] ); - $this->assertEquals( admin_url( 'admin.php?page=wc-admin#test/path?persisted_param=1' ), $widgets_leaderboard['rows'][0]['display'] ); - - $request = new WP_REST_Request( 'GET', $this->endpoint . '/allowed' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $widgets_leaderboard = end( $data ); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'top_widgets', $widgets_leaderboard['id'] ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Categories.php b/unit-tests/Tests/Version4/Reports/Categories.php deleted file mode 100644 index 11f06d3c686..00000000000 --- a/unit-tests/Tests/Version4/Reports/Categories.php +++ /dev/null @@ -1,169 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - QueueHelper::run_all_pending(); - - $uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - - $category_report = reset( $reports ); - - $this->assertEquals( $uncategorized_term->term_id, $category_report['category_id'] ); - $this->assertEquals( 4, $category_report['items_sold'] ); - $this->assertEquals( 1, $category_report['orders_count'] ); - $this->assertEquals( 1, $category_report['products_count'] ); - $this->assertArrayHasKey( '_links', $category_report ); - $this->assertArrayHasKey( 'category', $category_report['_links'] ); - } - - /** - * Test getting reports with the `categories` param. - * - * @since 3.5.0 - */ - public function test_get_reports_categories_param() { - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product 2' ); - $product->set_regular_price( 100 ); - $second_category_id = wp_create_category( 'Second Category' ); - $product->set_category_ids( array( $second_category_id ) ); - $product->save(); - - QueueHelper::run_all_pending(); - - $uncategorized_term = get_term_by( 'slug', 'uncategorized', 'product_cat' ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'categories' => $uncategorized_term->term_id . ',' . $second_category_id, - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $category_report = reset( $reports ); - - $this->assertEquals( $second_category_id, $category_report['category_id'] ); - $this->assertEquals( 0, $category_report['items_sold'] ); - $this->assertEquals( 0, $category_report['orders_count'] ); - $this->assertEquals( 0, $category_report['products_count'] ); - $this->assertArrayHasKey( '_links', $category_report ); - $this->assertArrayHasKey( 'category', $category_report['_links'] ); - - $category_report = next( $reports ); - - $this->assertEquals( $uncategorized_term->term_id, $category_report['category_id'] ); - $this->assertEquals( 4, $category_report['items_sold'] ); - $this->assertEquals( 1, $category_report['orders_count'] ); - $this->assertEquals( 1, $category_report['products_count'] ); - $this->assertArrayHasKey( '_links', $category_report ); - $this->assertArrayHasKey( 'category', $category_report['_links'] ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 6, count( $properties ) ); - $this->assertArrayHasKey( 'category_id', $properties ); - $this->assertArrayHasKey( 'items_sold', $properties ); - $this->assertArrayHasKey( 'net_revenue', $properties ); - $this->assertArrayHasKey( 'orders_count', $properties ); - $this->assertArrayHasKey( 'products_count', $properties ); - $this->assertArrayHasKey( 'extended_info', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Coupons.php b/unit-tests/Tests/Version4/Reports/Coupons.php deleted file mode 100644 index e046ca63488..00000000000 --- a/unit-tests/Tests/Version4/Reports/Coupons.php +++ /dev/null @@ -1,178 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting basic reports. - */ - public function test_get_reports() { - // Simple product. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - // Coupons. - $coupon_1_amount = 1; // by default in create_coupon. - $coupon_1 = CouponHelper::create_coupon( 'coupon_1' ); - - $coupon_2_amount = 2; - $coupon_2 = CouponHelper::create_coupon( 'coupon_2' ); - $coupon_2->set_amount( $coupon_2_amount ); - $coupon_2->save(); - - // Order without coupon. - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - // Order with 1 coupon. - $order_1c = OrderHelper::create_order( 1, $product ); - $order_1c->set_status( 'completed' ); - $order_1c->apply_coupon( $coupon_1 ); - $order_1c->calculate_totals(); - $order_1c->save(); - - // Order with 2 coupons. - $order_2c = OrderHelper::create_order( 1, $product ); - $order_2c->set_status( 'completed' ); - $order_2c->apply_coupon( $coupon_1 ); - $order_2c->apply_coupon( $coupon_2 ); - $order_2c->calculate_totals(); - $order_2c->save(); - - QueueHelper::run_all_pending(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $coupon_reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $coupon_reports ) ); - - $this->assertEquals( $coupon_2->get_id(), $coupon_reports[0]['coupon_id'] ); - $this->assertEquals( 1 * $coupon_2_amount, $coupon_reports[0]['amount'] ); - $this->assertEquals( 1, $coupon_reports[0]['orders_count'] ); - $this->assertArrayHasKey( '_links', $coupon_reports[0] ); - $this->assertArrayHasKey( 'coupon', $coupon_reports[0]['_links'] ); - - $this->assertEquals( $coupon_1->get_id(), $coupon_reports[1]['coupon_id'] ); - $this->assertEquals( 2 * $coupon_1_amount, $coupon_reports[1]['amount'] ); - $this->assertEquals( 2, $coupon_reports[1]['orders_count'] ); - $this->assertArrayHasKey( '_links', $coupon_reports[1] ); - $this->assertArrayHasKey( 'coupon', $coupon_reports[1]['_links'] ); - } - - /** - * Test getting basic reports with the `coupons` param. - */ - public function test_get_reports_coupons_param() { - // Simple product. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - // Coupons. - $coupon_1_amount = 1; // by default in create_coupon. - $coupon_1 = CouponHelper::create_coupon( 'coupon_1' ); - - $coupon_2_amount = 2; - $coupon_2 = CouponHelper::create_coupon( 'coupon_2' ); - $coupon_2->set_amount( $coupon_2_amount ); - $coupon_2->save(); - - // Order with 1 coupon. - $order_1c = OrderHelper::create_order( 1, $product ); - $order_1c->set_status( 'completed' ); - $order_1c->apply_coupon( $coupon_1 ); - $order_1c->calculate_totals(); - $order_1c->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'coupons' => $coupon_1->get_id() . ',' . $coupon_2->get_id(), - ) - ); - $response = $this->server->dispatch( $request ); - $coupon_reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $coupon_reports ) ); - - $this->assertEquals( $coupon_2->get_id(), $coupon_reports[0]['coupon_id'] ); - $this->assertEquals( 0, $coupon_reports[0]['amount'] ); - $this->assertEquals( 0, $coupon_reports[0]['orders_count'] ); - $this->assertArrayHasKey( '_links', $coupon_reports[0] ); - $this->assertArrayHasKey( 'coupon', $coupon_reports[0]['_links'] ); - - $this->assertEquals( $coupon_1->get_id(), $coupon_reports[1]['coupon_id'] ); - $this->assertEquals( $coupon_1_amount, $coupon_reports[1]['amount'] ); - $this->assertEquals( 1, $coupon_reports[1]['orders_count'] ); - $this->assertArrayHasKey( '_links', $coupon_reports[1] ); - $this->assertArrayHasKey( 'coupon', $coupon_reports[1]['_links'] ); - } - - /** - * Test getting reports without valid permissions. - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 4, count( $properties ) ); - $this->assertArrayHasKey( 'coupon_id', $properties ); - $this->assertArrayHasKey( 'amount', $properties ); - $this->assertArrayHasKey( 'orders_count', $properties ); - $this->assertArrayHasKey( 'extended_info', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/CouponsStats.php b/unit-tests/Tests/Version4/Reports/CouponsStats.php deleted file mode 100644 index 22bbfd0cf97..00000000000 --- a/unit-tests/Tests/Version4/Reports/CouponsStats.php +++ /dev/null @@ -1,173 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - */ - public function test_get_reports() { - // Populate all of the data. - // Simple product. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - // Coupons. - $coupon_1_amount = 1; // by default in create_coupon. - $coupon_1 = CouponHelper::create_coupon( 'coupon_1' ); - - $coupon_2_amount = 2; - $coupon_2 = CouponHelper::create_coupon( 'coupon_2' ); - $coupon_2->set_amount( $coupon_2_amount ); - $coupon_2->save(); - - // Order without coupon. - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - $time = time(); - - // Order with 1 coupon. - $order_1c = OrderHelper::create_order( 1, $product ); - $order_1c->set_status( 'completed' ); - $order_1c->apply_coupon( $coupon_1 ); - $order_1c->calculate_totals(); - $order_1c->set_date_created( $time ); - $order_1c->save(); - - // Order with 2 coupons. - $order_2c = OrderHelper::create_order( 1, $product ); - $order_2c->set_status( 'completed' ); - $order_2c->apply_coupon( $coupon_1 ); - $order_2c->apply_coupon( $coupon_2 ); - $order_2c->calculate_totals(); - $order_2c->set_date_created( $time ); - $order_2c->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d 23:59:59', $time ), - 'after' => date( 'Y-m-d 00:00:00', $time ), - 'interval' => 'day', - ) - ); - - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $expected_reports = array( - 'totals' => array( - 'amount' => 4.0, - 'coupons_count' => 2, - 'orders_count' => 2, - 'segments' => array(), - ), - 'intervals' => array( - array( - 'interval' => date( 'Y-m-d', $time ), - 'date_start' => date( 'Y-m-d 00:00:00', $time ), - 'date_start_gmt' => date( 'Y-m-d 00:00:00', $time ), - 'date_end' => date( 'Y-m-d 23:59:59', $time ), - 'date_end_gmt' => date( 'Y-m-d 23:59:59', $time ), - 'subtotals' => (object) array( - 'amount' => 4.0, - 'coupons_count' => 2, - 'orders_count' => 2, - 'segments' => array(), - ), - ), - ), - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $expected_reports, $reports ); - } - - /** - * Test getting reports without valid permissions. - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 2, count( $properties ) ); - $this->assertArrayHasKey( 'totals', $properties ); - $this->assertArrayHasKey( 'intervals', $properties ); - - $totals = $properties['totals']['properties']; - $this->assertEquals( 4, count( $totals ) ); - $this->assertArrayHasKey( 'amount', $totals ); - $this->assertArrayHasKey( 'coupons_count', $totals ); - $this->assertArrayHasKey( 'orders_count', $totals ); - $this->assertArrayHasKey( 'segments', $totals ); - - $intervals = $properties['intervals']['items']['properties']; - $this->assertEquals( 6, count( $intervals ) ); - $this->assertArrayHasKey( 'interval', $intervals ); - $this->assertArrayHasKey( 'date_start', $intervals ); - $this->assertArrayHasKey( 'date_start_gmt', $intervals ); - $this->assertArrayHasKey( 'date_end', $intervals ); - $this->assertArrayHasKey( 'date_end_gmt', $intervals ); - $this->assertArrayHasKey( 'subtotals', $intervals ); - - $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; - $this->assertEquals( 4, count( $subtotals ) ); - $this->assertArrayHasKey( 'amount', $subtotals ); - $this->assertArrayHasKey( 'coupons_count', $subtotals ); - $this->assertArrayHasKey( 'orders_count', $subtotals ); - $this->assertArrayHasKey( 'segments', $subtotals ); - - } -} diff --git a/unit-tests/Tests/Version4/Reports/CustomerStats.php b/unit-tests/Tests/Version4/Reports/CustomerStats.php deleted file mode 100644 index 447e17380e7..00000000000 --- a/unit-tests/Tests/Version4/Reports/CustomerStats.php +++ /dev/null @@ -1,162 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertCount( 1, $properties ); - $this->assertArrayHasKey( 'totals', $properties ); - $this->assertCount( 4, $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'customers_count', $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'avg_orders_count', $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'avg_total_spend', $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'avg_avg_order_value', $properties['totals']['properties'] ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - $test_customers = array(); - - // Create 10 test customers. - for ( $i = 1; $i <= 10; $i++ ) { - $test_customers[] = CustomerHelper::create_customer( "customer{$i}", 'password', "customer{$i}@example.com" ); - } - // One differing name. - $test_customers[2]->set_first_name( 'Jeff' ); - $test_customers[2]->save(); - - // Create a test product for use in an order. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - // Place some test orders. - $order = OrderHelper::create_order( $test_customers[0]->get_id(), $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); - $order->save(); - - $order = OrderHelper::create_order( $test_customers[0]->get_id(), $product ); - $order->set_status( 'completed' ); - $order->set_total( 234 ); - $order->save(); - - $order = OrderHelper::create_order( $test_customers[1]->get_id(), $product ); - $order->set_status( 'completed' ); - $order->set_total( 55 ); - $order->save(); - - $order = OrderHelper::create_order( $test_customers[2]->get_id(), $product ); - $order->set_status( 'completed' ); - $order->set_total( 9.12 ); - $order->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $headers = $response->get_headers(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 10, $reports['totals']->customers_count ); - $this->assertEquals( 1.333, round( $reports['totals']->avg_orders_count, 3 ) ); - $this->assertEquals( 132.707, round( $reports['totals']->avg_total_spend, 3 ) ); - $this->assertEquals( 77.04, $reports['totals']->avg_avg_order_value ); - - // Test name parameter (case with no matches). - $request->set_query_params( - array( - 'search' => 'Nota Customername', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 0, $reports['totals']->customers_count ); - $this->assertEquals( 0, $reports['totals']->avg_orders_count ); - $this->assertEquals( 0, $reports['totals']->avg_total_spend ); - $this->assertEquals( 0, $reports['totals']->avg_avg_order_value ); - - // Test name and last_order parameters. - $request->set_query_params( - array( - 'search' => 'Jeff', - 'last_order_after' => date( 'Y-m-d' ) . 'T00:00:00Z', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, $reports['totals']->customers_count ); - $this->assertEquals( 1, $reports['totals']->avg_orders_count ); - $this->assertEquals( 9.12, $reports['totals']->avg_total_spend ); - $this->assertEquals( 9.12, $reports['totals']->avg_avg_order_value ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Customers.php b/unit-tests/Tests/Version4/Reports/Customers.php deleted file mode 100644 index 13fea32e14d..00000000000 --- a/unit-tests/Tests/Version4/Reports/Customers.php +++ /dev/null @@ -1,392 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Asserts the report item schema is correct. - * - * @param array $schema Item to check schema. - */ - public function assert_report_item_schema( $schema ) { - $this->assertArrayHasKey( 'id', $schema ); - $this->assertArrayHasKey( 'user_id', $schema ); - $this->assertArrayHasKey( 'name', $schema ); - $this->assertArrayHasKey( 'username', $schema ); - $this->assertArrayHasKey( 'country', $schema ); - $this->assertArrayHasKey( 'city', $schema ); - $this->assertArrayHasKey( 'postcode', $schema ); - $this->assertArrayHasKey( 'date_registered', $schema ); - $this->assertArrayHasKey( 'date_registered_gmt', $schema ); - $this->assertArrayHasKey( 'date_last_active', $schema ); - $this->assertArrayHasKey( 'date_last_active_gmt', $schema ); - $this->assertArrayHasKey( 'orders_count', $schema ); - $this->assertArrayHasKey( 'total_spend', $schema ); - $this->assertArrayHasKey( 'avg_order_value', $schema ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertCount( 14, $properties ); - $this->assert_report_item_schema( $properties ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test calling update_registered_customer() with a bad user id. - * - * @since 3.5.0 - */ - public function test_update_registered_customer_with_bad_user_id() { - $result = \WC_Admin_Reports_Customers_Data_Store::update_registered_customer( 2 ); - $this->assertFalse( $result ); - } - - /** - * Test creation of various user roles - * - * @since 3.5.0 - */ - public function test_user_creation() { - $admin_id = wp_insert_user( - array( - 'user_login' => 'testadmin', - 'user_pass' => null, - 'role' => 'administrator', - ) - ); - - // Admin user without orders should not be shown. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'per_page' => 10 ) ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $headers = $response->get_headers(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 0, $reports ); - - // Creating an order with admin should return the admin. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( $admin_id, $product ); - $order->set_status( 'processing' ); - $order->set_total( 100 ); - $order->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'per_page' => 10 ) ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $headers = $response->get_headers(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - $this->assertEquals( $admin_id, $reports[0]['user_id'] ); - - // Creating a customer should show up regardless of orders. - $customer = CustomerHelper::create_customer( 'customer', 'password', 'customer@example.com' ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'per_page' => 10, - 'order' => 'asc', - 'orderby' => 'username', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $headers = $response->get_headers(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 2, $reports ); - $this->assertEquals( $customer->get_id(), $reports[0]['user_id'] ); - $this->assertEquals( $admin_id, $reports[1]['user_id'] ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - global $wpdb; - - $test_customers = array(); - - $customer_names = array( 'Alice', 'Betty', 'Catherine', 'Dan', 'Eric', 'Fred', 'Greg', 'Henry', 'Ivan', 'Justin' ); - - // Create 10 test customers. - for ( $i = 1; $i <= 10; $i++ ) { - $name = $customer_names[ $i - 1 ]; - $email = 'customer+' . strtolower( $name ) . '@example.com'; - $customer = CustomerHelper::create_customer( "customer{$i}", 'password', $email ); - $customer->set_first_name( $name ); - $customer->save(); - $test_customers[] = $customer; - } - - // Create a test product for use in an order. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - // Place an order for the first test customer. - $order = OrderHelper::create_order( $test_customers[0]->get_id(), $product ); - $order->set_status( 'processing' ); - $order->set_total( 100 ); - $order->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'per_page' => 5, - 'order' => 'asc', - 'orderby' => 'username', - ) - ); - - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $headers = $response->get_headers(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 5, $reports ); - $this->assertArrayHasKey( 'X-WP-Total', $headers ); - $this->assertEquals( 10, $headers['X-WP-Total'] ); - $this->assertArrayHasKey( 'X-WP-TotalPages', $headers ); - $this->assertEquals( 2, $headers['X-WP-TotalPages'] ); - $this->assertEquals( $test_customers[0]->get_id(), $reports[0]['user_id'] ); - $this->assertEquals( 1, $reports[0]['orders_count'] ); - $this->assertEquals( 100, $reports[0]['total_spend'] ); - $this->assert_report_item_schema( $reports[0] ); - - // Test name parameter (case with no matches). - $request->set_query_params( - array( - 'search' => 'Nota Customername', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 0, $reports ); - - // Test name parameter (partial match). - $request->set_query_params( - array( - 'search' => 're', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 2, $reports ); - - // Test email search. - $request->set_query_params( - array( - 'search' => 'customer+justin', - 'searchby' => 'email', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - - // Test username search. - $request->set_query_params( - array( - 'search' => 'customer1', - 'searchby' => 'username', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - // customer1 and customer10. - $this->assertCount( 2, $reports ); - - // Test name and last_order parameters. - $request->set_query_params( - array( - 'search' => 'Alice', - 'last_order_after' => date( 'Y-m-d' ) . 'T00:00:00Z', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - - $this->assertEquals( $test_customers[0]->get_id(), $reports[0]['user_id'] ); - $this->assertEquals( 1, $reports[0]['orders_count'] ); - $this->assertEquals( 100, $reports[0]['total_spend'] ); - - $customer_id = $wpdb->get_col( - $wpdb->prepare( - "SELECT customer_id FROM {$wpdb->prefix}wc_customer_lookup WHERE user_id = %d", - $reports[0]['user_id'] - ) - ); - - // Test customers param. - $request->set_query_params( - array( - 'customers' => $customer_id, - ) - ); - - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - $this->assertEquals( $test_customers[0]->get_id(), $reports[0]['user_id'] ); - } - - /** - * Test customer first and last name. - */ - public function test_customer_name() { - $customer = wp_insert_user( - array( - 'user_login' => 'daenerys', - 'user_pass' => null, - 'role' => 'customer', - ) - ); - - // Test shipping name and empty billing name. - $order = OrderHelper::create_order( $customer ); - $order->set_billing_first_name( '' ); - $order->set_billing_last_name( '' ); - $order->set_shipping_first_name( 'Daenerys' ); - $order->set_shipping_last_name( 'Targaryen' ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); - $order->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $headers = $response->get_headers(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - $this->assertEquals( 'Daenerys Targaryen', $reports[0]['name'] ); - - // Test billing name. - $order->set_billing_first_name( 'Jon' ); - $order->set_billing_last_name( 'Snow' ); - $order->save(); - do_action( 'woocommerce_update_customer', $customer ); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'orderby' => 'username' ) ); // Cache busting. - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $headers = $response->get_headers(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - $this->assertEquals( 'Jon Snow', $reports[0]['name'] ); - - // Test user profile name. - wp_update_user( - array( - 'ID' => $customer, - 'first_name' => 'Tyrion', - 'last_name' => 'Lanister', - ) - ); - do_action( 'woocommerce_update_customer', $customer ); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( array( 'orderby' => 'name' ) ); // Cache busting. - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $headers = $response->get_headers(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - $this->assertEquals( 'Tyrion Lanister', $reports[0]['name'] ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/DownloadStats.php b/unit-tests/Tests/Version4/Reports/DownloadStats.php deleted file mode 100644 index 92b7d433ba6..00000000000 --- a/unit-tests/Tests/Version4/Reports/DownloadStats.php +++ /dev/null @@ -1,358 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting report. - */ - public function test_get_report() { - global $wpdb; - - // Populate all of the data. - $prod_download = new \WC_Product_Download(); - $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); - $prod_download->set_id( 1 ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_downloadable( 'yes' ); - $product->set_downloads( array( $prod_download ) ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); - $order->save(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( $this->user ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $id = $object->save(); - - $time = time(); - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d 23:59:59', $time ), - 'after' => date( 'Y-m-d H:00:00', $time - ( 7 * DAY_IN_SECONDS ) ), - 'interval' => 'day', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $totals = array( - 'download_count' => 1, - ); - $this->assertEquals( $totals, $reports['totals'] ); - - $today_interval = array( - 'interval' => date( 'Y-m-d', $time ), - 'date_start' => date( 'Y-m-d 00:00:00', $time ), - 'date_start_gmt' => date( 'Y-m-d 00:00:00', $time ), - 'date_end' => date( 'Y-m-d 23:59:59', $time ), - 'date_end_gmt' => date( 'Y-m-d 23:59:59', $time ), - 'subtotals' => (object) array( - 'download_count' => 1, - ), - ); - $this->assertEquals( $today_interval, $reports['intervals'][0] ); - - $this->assertEquals( 8, count( $reports['intervals'] ) ); - $this->assertEquals( 0, $reports['intervals'][1]['subtotals']->download_count ); - - // Test sorting by download_count. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d 23:59:59', $time ), - 'after' => date( 'Y-m-d H:00:00', $time - ( 7 * DAY_IN_SECONDS ) ), - 'interval' => 'day', - 'orderby' => 'download_count', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - } - - /** - * Test getting report with user filter. - */ - public function test_get_report_with_user_filter() { - global $wpdb; - - $time = time(); - - // First set of data. - $prod_download = new \WC_Product_Download(); - $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); - $prod_download->set_id( 1 ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_downloadable( 'yes' ); - $product->set_downloads( array( $prod_download ) ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 25 ); - $order->save(); - $order_1 = $order->get_id(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( 1 ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - for ( $i = 1; $i < 3; $i++ ) { - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( 1 ); - $object->set_user_ip_address( '1.2.3.4' ); - $id = $object->save(); - } - - $order = OrderHelper::create_order( 2, $product ); - $order->set_status( 'completed' ); - $order->set_total( 10 ); - $order->save(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( 2 ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( 2 ); - $object->set_user_ip_address( '5.4.3.2.1' ); - $object->save(); - - $customer_id = $wpdb->get_col( - $wpdb->prepare( - "SELECT customer_id FROM {$wpdb->prefix}wc_customer_lookup WHERE user_id = %d", - 1 - ) - ); - - // Test includes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'customer_includes' => $customer_id, - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, $reports['totals']['download_count'] ); - - // Test excludes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'customer_excludes' => $customer_id, - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, $reports['totals']['download_count'] ); - } - - /** - * Test getting report ordering. - */ - public function test_get_report_orderby() { - global $wpdb; - - // Populate all of the data. - $prod_download = new \WC_Product_Download(); - $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); - $prod_download->set_id( 1 ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_downloadable( 'yes' ); - $product->set_downloads( array( $prod_download ) ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); - $order->save(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( $this->user ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $object->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $object->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $object->save(); - - $three_days_from_now = current_time( 'timestamp', true ) - ( 3 * DAY_IN_SECONDS ); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $object->set_timestamp( $three_days_from_now ); - $object->save(); - - $time = time(); - $seven_days_ago = $time - ( 7 * DAY_IN_SECONDS ); - - // Test sorting by download_count. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d 23:59:59', $time ), - 'after' => date( 'Y-m-d H:00:00', $seven_days_ago ), - 'interval' => 'day', - 'orderby' => 'download_count', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 3, $reports['intervals'][0]['subtotals']->download_count ); - $this->assertEquals( date( 'Y-m-d', $time ), $reports['intervals'][0]['interval'] ); - - $this->assertEquals( 1, $reports['intervals'][1]['subtotals']->download_count ); - $this->assertEquals( date( 'Y-m-d', $three_days_from_now ), $reports['intervals'][1]['interval'] ); - - // Test sorting by date. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d 23:59:59', $time ), - 'after' => date( 'Y-m-d H:00:00', $seven_days_ago ), - 'interval' => 'day', - 'orderby' => 'date', - 'order' => 'asc', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 0, $reports['intervals'][0]['subtotals']->download_count ); - $this->assertEquals( date( 'Y-m-d', $seven_days_ago ), $reports['intervals'][0]['interval'] ); - - $this->assertEquals( 3, $reports['intervals'][7]['subtotals']->download_count ); - $this->assertEquals( date( 'Y-m-d', $time ), $reports['intervals'][7]['interval'] ); - } - - /** - * Test getting reports without valid permissions. - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 2, count( $properties ) ); - $this->assertArrayHasKey( 'totals', $properties ); - $this->assertArrayHasKey( 'intervals', $properties ); - - $totals = $properties['totals']['properties']; - $this->assertEquals( 1, count( $totals ) ); - $this->assertArrayHasKey( 'download_count', $totals ); - - $intervals = $properties['intervals']['items']['properties']; - $this->assertEquals( 6, count( $intervals ) ); - $this->assertArrayHasKey( 'interval', $intervals ); - $this->assertArrayHasKey( 'date_start', $intervals ); - $this->assertArrayHasKey( 'date_start_gmt', $intervals ); - $this->assertArrayHasKey( 'date_end', $intervals ); - $this->assertArrayHasKey( 'date_end_gmt', $intervals ); - $this->assertArrayHasKey( 'subtotals', $intervals ); - - $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; - $this->assertEquals( 1, count( $subtotals ) ); - $this->assertArrayHasKey( 'download_count', $subtotals ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Downloads.php b/unit-tests/Tests/Version4/Reports/Downloads.php deleted file mode 100644 index fbc4cecd4cc..00000000000 --- a/unit-tests/Tests/Version4/Reports/Downloads.php +++ /dev/null @@ -1,409 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting report. - */ - public function test_get_report() { - global $wpdb; - - // Populate all of the data. - $prod_download = new \WC_Product_Download(); - $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); - $prod_download->set_id( 1 ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_downloadable( 'yes' ); - $product->set_downloads( array( $prod_download ) ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); - $order->save(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( $this->user ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $id = $object->save(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - - $download_report = reset( $reports ); - - $this->assertEquals( 1, $download_report['download_id'] ); - $this->assertEquals( $product->get_id(), $download_report['product_id'] ); - $this->assertEquals( $order->get_id(), $download_report['order_id'] ); - $this->assertEquals( $order->get_order_number(), $download_report['order_number'] ); - $this->assertEquals( $this->user, $download_report['user_id'] ); - $this->assertEquals( '1.2.3.4', $download_report['ip_address'] ); - $this->assertEquals( 'help.png', $download_report['file_name'] ); - $this->assertEquals( plugin_dir_url( __FILE__ ) . '/assets/images/help.png', $download_report['file_path'] ); - } - - /** - * Does some test setup so we can filter with different options in later tests. - */ - public function filter_setup() { - global $wpdb; - - $time = time(); - - // First set of data. - $prod_download = new \WC_Product_Download(); - $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); - $prod_download->set_id( 1 ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_downloadable( 'yes' ); - $product->set_downloads( array( $prod_download ) ); - $product->set_regular_price( 25 ); - $product->save(); - $product_1 = $product->get_id(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 25 ); - $order->save(); - $order_1 = $order->get_id(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( 1 ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( 1 ); - $object->set_user_ip_address( '1.2.3.4' ); - $id = $object->save(); - - // Second set of data. - $prod_download = new \WC_Product_Download(); - $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/test.png' ); - $prod_download->set_id( 2 ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product 2' ); - $product->set_downloadable( 'yes' ); - $product->set_downloads( array( $prod_download ) ); - $product->set_regular_price( 10 ); - $product->save(); - $product_2 = $product->get_id(); - - $order = OrderHelper::create_order( 2, $product ); - $order->set_status( 'completed' ); - $order->set_total( 10 ); - $order->save(); - $order_2 = $order->get_id(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( 2 ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( 2 ); - $object->set_user_ip_address( '5.4.3.2.1' ); - $object->set_timestamp( date( 'Y-m-d H:00:00', $time - ( 2 * DAY_IN_SECONDS ) ) ); - $id = $object->save(); - - return array( - 'time' => $time, - 'product_1' => $product_1, - 'product_2' => $product_2, - 'order_1' => $order_1, - 'order_2' => $order_2, - ); - } - - /** - * Test getting report with date filter. - */ - public function test_get_report_with_date_filter() { - $test_info = $this->filter_setup(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - // Test date filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d H:00:00', $test_info['time'] + DAY_IN_SECONDS ), - 'after' => date( 'Y-m-d H:00:00', $test_info['time'] - DAY_IN_SECONDS ), - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'help.png', $download_report['file_name'] ); - } - - /** - * Test getting report with product filter. - */ - public function test_get_report_with_product_filter() { - $test_info = $this->filter_setup(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - // Test includes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'product_includes' => $test_info['product_1'], - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'help.png', $download_report['file_name'] ); - - // Test excludes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'product_excludes' => $test_info['product_1'], - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'test.png', $download_report['file_name'] ); - } - - /** - * Test getting report with order filter. - */ - public function test_get_report_with_order_filter() { - $test_info = $this->filter_setup(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - // Test includes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'order_includes' => $test_info['order_1'], - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'help.png', $download_report['file_name'] ); - - // Test excludes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'order_excludes' => $test_info['order_1'], - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'test.png', $download_report['file_name'] ); - } - - /** - * Test getting report with user filter. - */ - public function test_get_report_with_user_filter() { - $test_info = $this->filter_setup(); - global $wpdb; - - $customer_id = $wpdb->get_col( - $wpdb->prepare( - "SELECT customer_id FROM {$wpdb->prefix}wc_customer_lookup WHERE user_id = %d", - 1 - ) - ); - - // Test includes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'customer_includes' => $customer_id, - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'help.png', $download_report['file_name'] ); - $this->assertEquals( 1, $download_report['user_id'] ); - - // Test excludes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'customer_excludes' => $customer_id, - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'test.png', $download_report['file_name'] ); - $this->assertEquals( 2, $download_report['user_id'] ); - } - - /** - * Test getting report with ip address filter. - */ - public function test_get_report_with_ip_address_filter() { - $test_info = $this->filter_setup(); - - // Test includes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'ip_address_includes' => '1.2.3.4', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'help.png', $download_report['file_name'] ); - - // Test excludes filtering. - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'ip_address_excludes' => '1.2.3.4', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - $download_report = reset( $reports ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - $this->assertEquals( 'test.png', $download_report['file_name'] ); - } - - /** - * Test getting reports without valid permissions. - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 12, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'product_id', $properties ); - $this->assertArrayHasKey( 'date', $properties ); - $this->assertArrayHasKey( 'date_gmt', $properties ); - $this->assertArrayHasKey( 'download_id', $properties ); - $this->assertArrayHasKey( 'file_name', $properties ); - $this->assertArrayHasKey( 'file_path', $properties ); - $this->assertArrayHasKey( 'order_id', $properties ); - $this->assertArrayHasKey( 'order_number', $properties ); - $this->assertArrayHasKey( 'user_id', $properties ); - $this->assertArrayHasKey( 'username', $properties ); - $this->assertArrayHasKey( 'ip_address', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Import.php b/unit-tests/Tests/Version4/Reports/Import.php deleted file mode 100644 index 34ce6ba09b1..00000000000 --- a/unit-tests/Tests/Version4/Reports/Import.php +++ /dev/null @@ -1,393 +0,0 @@ -customer = $this->factory->user->create( - array( - 'first_name' => 'Steve', - 'last_name' => 'User', - 'role' => 'customer', - ) - ); - } - - /** - * Test route registration. - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Asserts the report item schema is correct. - * - * @param array $schema Item to check schema. - */ - public function assert_report_item_schema( $schema ) { - $this->assertArrayHasKey( 'status', $schema ); - $this->assertArrayHasKey( 'message', $schema ); - } - - /** - * Test reports schema. - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertCount( 2, $properties ); - $this->assert_report_item_schema( $properties ); - } - - /** - * Test getting reports without valid permissions. - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'POST', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test the import paramaters. - */ - public function test_import_params() { - global $wpdb; - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $order_1 = OrderHelper::create_order( 1, $product ); - $order_1->set_status( 'completed' ); - $order_1->set_date_created( time() - ( 3 * DAY_IN_SECONDS ) ); - $order_1->save(); - $order_2 = OrderHelper::create_order( 1, $product ); - $order_2->set_total( 100 ); - $order_2->set_status( 'completed' ); - $order_2->save(); - - // Delete order stats so we can test import API. - $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE post_type = 'scheduled-action'" ); - $wpdb->query( "DELETE FROM {$wpdb->prefix}wc_order_stats" ); - - // Use the days param to only process orders in the last day. - $request = new WP_REST_Request( 'POST', $this->endpoint ); - $request->set_query_params( array( 'days' => '1' ) ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'success', $report['status'] ); - - // Run pending thrice to process batch and order. - QueueHelper::run_all_pending(); - QueueHelper::run_all_pending(); - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 2, $reports ); - $this->assertEquals( $this->customer, $reports[0]['user_id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - $this->assertEquals( $order_2->get_id(), $reports[0]['order_id'] ); - - // Use the skip existing params to skip processing customers/orders. - // Compare against order status to make sure previously imported order was skipped. - $order_2->set_status( 'processing' ); - $order_2->save(); - - // Compare against name to make sure previously imported customer was skipped. - wp_update_user( - array( - 'ID' => $this->customer, - 'first_name' => 'Changed', - ) - ); - - // Delete scheduled actions to avoid default order processing. - $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE post_type = 'scheduled-action'" ); - - $request = new WP_REST_Request( 'POST', $this->endpoint ); - $request->set_query_params( array( 'skip_existing' => '1' ) ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'success', $report['status'] ); - - // Run pending thrice to process batch and order. - QueueHelper::run_all_pending(); - QueueHelper::run_all_pending(); - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 2, $reports ); - $this->assertEquals( 'Steve User', $reports[0]['name'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); - $request->set_query_params( array( 'per_page' => 5 ) ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 2, $reports ); - $this->assertEquals( 'completed', $reports[0]['status'] ); - } - - /** - * Test cancelling import actions. - */ - public function test_cancel_import() { - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_date_created( time() - ( 3 * DAY_IN_SECONDS ) ); - $order->save(); - - // Verify there are actions to cancel. - $pending_actions = QueueHelper::get_all_pending(); - $this->assertCount( 1, $pending_actions ); - - // Cancel outstanding actions. - $request = new WP_REST_Request( 'POST', $this->endpoint . '/cancel' ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'success', $report['status'] ); - - // Verify there are no pending actions. - $pending_actions = QueueHelper::get_all_pending(); - $this->assertCount( 0, $pending_actions ); - } - - /** - * Test import deletion. - */ - public function test_delete_stats() { - global $wpdb; - - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - for ( $i = 0; $i < 25; $i++ ) { - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->save(); - } - - // Check that stats exist before deleting. - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); - $request->set_query_params( array( 'per_page' => 25 ) ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 25, $reports ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); - $request->set_query_params( array( 'per_page' => 25 ) ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $reports ); - - // Delete all stats. - $request = new WP_REST_Request( 'POST', $this->endpoint . '/delete' ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'success', $report['status'] ); - - // Run pending three times to process batches and dependent actions. - QueueHelper::run_all_pending(); - QueueHelper::run_all_pending(); - QueueHelper::run_all_pending(); - - // Check that stats have been deleted. - $request = new WP_REST_Request( 'GET', '/wc/v4/reports/orders' ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 0, $reports ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/reports/customers' ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 0, $reports ); - } - - /** - * Test import status and totals query. - */ - public function test_import_status() { - // Delete any pending actions that weren't fully run. - \WC_Admin_Reports_Sync::clear_queued_actions(); - - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - // Create 5 completed orders. - for ( $i = 0; $i < 5; $i++ ) { - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_date_created( time() - ( ( $i + 1 ) * DAY_IN_SECONDS ) ); - $order->save(); - } - - // Trash one test order - excludes it from totals. - $order->set_status( 'trash' ); - $order->save(); - - // Create 1 draft order - to be excluded from totals. - $order = OrderHelper::create_order( 1, $product ); - $order->set_date_created( time() - ( 5 * DAY_IN_SECONDS ) ); - $order->save(); - wp_update_post( - array( - 'ID' => $order->get_id(), - 'post_status' => 'auto-draft', - ) - ); - - // Test totals and total params. - $request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - $user_query = new \WP_User_Query( - array( - 'fields' => 'ID', - 'number' => 1, - ) - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 4, $report['orders'] ); - $this->assertEquals( $user_query->get_total(), $report['customers'] ); - - // Test totals with days param. - $request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' ); - $request->set_query_params( array( 'days' => 2 ) ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, $report['orders'] ); - - // Test import status. - $request = new WP_REST_Request( 'POST', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'success', $report['status'] ); - - $request = new WP_REST_Request( 'GET', $this->endpoint . '/status' ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( true, $report['is_importing'] ); - $this->assertEquals( 0, $report['customers_count'] ); - $this->assertEquals( 3, $report['customers_total'] ); - $this->assertEquals( 0, $report['orders_count'] ); - $this->assertEquals( 4, $report['orders_total'] ); - - // Run pending thrice to process batch and order. - QueueHelper::process_pending(); - QueueHelper::process_pending(); - QueueHelper::process_pending(); - - // Test import status after processing. - $request = new WP_REST_Request( 'GET', $this->endpoint . '/status' ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( false, $report['is_importing'] ); - $this->assertEquals( 1, $report['customers_count'] ); - $this->assertEquals( 3, $report['customers_total'] ); - $this->assertEquals( 4, $report['orders_count'] ); - $this->assertEquals( 4, $report['orders_total'] ); - - // Test totals with skip existing param. - $request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' ); - $request->set_query_params( array( 'skip_existing' => 1 ) ); - $response = $this->server->dispatch( $request ); - $report = $response->get_data(); - - // @todo The following line should be uncommented when https://github.com/woocommerce/woocommerce-admin/issues/2195 is resolved. - // $this->assertEquals( 0, $report['customers'] ); - $this->assertEquals( 0, $report['orders'] ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/OrderStats.php b/unit-tests/Tests/Version4/Reports/OrderStats.php deleted file mode 100644 index 0e20efc5bb4..00000000000 --- a/unit-tests/Tests/Version4/Reports/OrderStats.php +++ /dev/null @@ -1,119 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - // @todo Update after report interface is done. - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); // totals and intervals. - // @todo Update results after implement report interface. - // $this->assertEquals( array(), $reports ); // @codingStandardsIgnoreLine. - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 2, count( $properties ) ); - $this->assertArrayHasKey( 'totals', $properties ); - $this->assertArrayHasKey( 'intervals', $properties ); - - $totals = $properties['totals']['properties']; - $this->assertEquals( 11, count( $totals ) ); - $this->assertArrayHasKey( 'net_revenue', $totals ); - $this->assertArrayHasKey( 'avg_order_value', $totals ); - $this->assertArrayHasKey( 'orders_count', $totals ); - $this->assertArrayHasKey( 'avg_items_per_order', $totals ); - $this->assertArrayHasKey( 'num_items_sold', $totals ); - $this->assertArrayHasKey( 'coupons', $totals ); - $this->assertArrayHasKey( 'coupons_count', $totals ); - $this->assertArrayHasKey( 'num_returning_customers', $totals ); - $this->assertArrayHasKey( 'num_new_customers', $totals ); - $this->assertArrayHasKey( 'products', $totals ); - $this->assertArrayHasKey( 'segments', $totals ); - - $intervals = $properties['intervals']['items']['properties']; - $this->assertEquals( 6, count( $intervals ) ); - $this->assertArrayHasKey( 'interval', $intervals ); - $this->assertArrayHasKey( 'date_start', $intervals ); - $this->assertArrayHasKey( 'date_start_gmt', $intervals ); - $this->assertArrayHasKey( 'date_end', $intervals ); - $this->assertArrayHasKey( 'date_end_gmt', $intervals ); - $this->assertArrayHasKey( 'subtotals', $intervals ); - - $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; - $this->assertEquals( 10, count( $subtotals ) ); - $this->assertArrayHasKey( 'net_revenue', $subtotals ); - $this->assertArrayHasKey( 'avg_order_value', $subtotals ); - $this->assertArrayHasKey( 'orders_count', $subtotals ); - $this->assertArrayHasKey( 'avg_items_per_order', $subtotals ); - $this->assertArrayHasKey( 'num_items_sold', $subtotals ); - $this->assertArrayHasKey( 'coupons', $subtotals ); - $this->assertArrayHasKey( 'coupons_count', $subtotals ); - $this->assertArrayHasKey( 'num_returning_customers', $subtotals ); - $this->assertArrayHasKey( 'num_new_customers', $subtotals ); - $this->assertArrayHasKey( 'segments', $subtotals ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Orders.php b/unit-tests/Tests/Version4/Reports/Orders.php deleted file mode 100644 index 05b5c1c7c49..00000000000 --- a/unit-tests/Tests/Version4/Reports/Orders.php +++ /dev/null @@ -1,118 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - QueueHelper::run_all_pending(); - - $expected_customer_id = \WC_Admin_Reports_Customers_Data_Store::get_customer_id_by_user_id( 1 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - - $order_report = reset( $reports ); - - $this->assertEquals( $order->get_id(), $order_report['order_id'] ); - $this->assertEquals( $order->get_order_number(), $order_report['order_number'] ); - $this->assertEquals( date( 'Y-m-d H:i:s', $order->get_date_created()->getTimestamp() ), $order_report['date_created'] ); - $this->assertEquals( $expected_customer_id, $order_report['customer_id'] ); - $this->assertEquals( 4, $order_report['num_items_sold'] ); - $this->assertEquals( 90.0, $order_report['net_total'] ); // 25 x 4 - 10 (shipping) - $this->assertEquals( 'new', $order_report['customer_type'] ); - $this->assertArrayHasKey( '_links', $order_report ); - $this->assertArrayHasKey( 'order', $order_report['_links'] ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 9, count( $properties ) ); - $this->assertArrayHasKey( 'order_id', $properties ); - $this->assertArrayHasKey( 'order_number', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'status', $properties ); - $this->assertArrayHasKey( 'customer_id', $properties ); - $this->assertArrayHasKey( 'net_total', $properties ); - $this->assertArrayHasKey( 'num_items_sold', $properties ); - $this->assertArrayHasKey( 'customer_type', $properties ); - $this->assertArrayHasKey( 'extended_info', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php b/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php deleted file mode 100644 index cd84cb5c1ff..00000000000 --- a/unit-tests/Tests/Version4/Reports/PerformanceIndicators.php +++ /dev/null @@ -1,172 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - $this->assertArrayHasKey( $this->endpoint . '/allowed', $routes ); - } - - /** - * Test getting indicators. - */ - public function test_get_indicators() { - global $wpdb; - - // Populate all of the data. We'll create an order and a download. - $prod_download = new \WC_Product_Download(); - $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); - $prod_download->set_id( 1 ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_downloadable( 'yes' ); - $product->set_downloads( array( $prod_download ) ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 25 ); - $order->save(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( $this->user ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $object->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $object->save(); - - QueueHelper::run_all_pending(); - - $time = time(); - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d 23:59:59', $time ), - 'after' => date( 'Y-m-d H:00:00', $time - ( 7 * DAY_IN_SECONDS ) ), - 'stats' => 'orders/orders_count,downloads/download_count,test/bogus_stat', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $this->assertEquals( 'orders/orders_count', $reports[0]['stat'] ); - $this->assertEquals( 'Amount of orders', $reports[0]['label'] ); - $this->assertEquals( 1, $reports[0]['value'] ); - $this->assertEquals( 'orders_count', $reports[0]['chart'] ); - $this->assertEquals( '/analytics/orders', $response->data[0]['_links']['report'][0]['href'] ); - - $this->assertEquals( 'downloads/download_count', $reports[1]['stat'] ); - $this->assertEquals( 'Number of downloads', $reports[1]['label'] ); - $this->assertEquals( 2, $reports[1]['value'] ); - $this->assertEquals( 'download_count', $reports[1]['chart'] ); - $this->assertEquals( '/analytics/downloads', $response->data[1]['_links']['report'][0]['href'] ); - } - - /** - * Test getting indicators with an empty request. - */ - public function test_get_indicators_empty_request() { - global $wpdb; - - $time = time(); - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d 23:59:59', $time ), - 'after' => date( 'Y-m-d H:00:00', $time - ( 7 * DAY_IN_SECONDS ) ), - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 500, $response->get_status() ); - } - - /** - * Test getting without valid permissions. - */ - public function test_get_indicators_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test schema. - */ - public function test_indicators_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 5, count( $properties ) ); - $this->assertArrayHasKey( 'stat', $properties ); - $this->assertArrayHasKey( 'chart', $properties ); - $this->assertArrayHasKey( 'label', $properties ); - $this->assertArrayHasKey( 'format', $properties ); - $this->assertArrayHasKey( 'value', $properties ); - } - - /** - * Test schema for /allowed indicators endpoint. - */ - public function test_indicators_schema_allowed() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint . '/allowed' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'stat', $properties ); - $this->assertArrayHasKey( 'chart', $properties ); - $this->assertArrayHasKey( 'label', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/ProductStats.php b/unit-tests/Tests/Version4/Reports/ProductStats.php deleted file mode 100644 index 40f84200765..00000000000 --- a/unit-tests/Tests/Version4/Reports/ProductStats.php +++ /dev/null @@ -1,161 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $time = time(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_shipping_total( 10 ); - $order->set_discount_total( 20 ); - $order->set_discount_tax( 0 ); - $order->set_cart_tax( 5 ); - $order->set_shipping_tax( 2 ); - $order->set_total( 97 ); // $25x4 products + $10 shipping - $20 discount + $7 tax. - $order->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'before' => date( 'Y-m-d 23:59:59', $time ), - 'after' => date( 'Y-m-d 00:00:00', $time ), - 'interval' => 'day', - ) - ); - - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $expected_reports = array( - 'totals' => array( - 'items_sold' => 4, - 'net_revenue' => 100.0, - 'orders_count' => 1, - 'products_count' => 1, - 'variations_count' => 1, - 'segments' => array(), - ), - 'intervals' => array( - array( - 'interval' => date( 'Y-m-d', $time ), - 'date_start' => date( 'Y-m-d 00:00:00', $time ), - 'date_start_gmt' => date( 'Y-m-d 00:00:00', $time ), - 'date_end' => date( 'Y-m-d 23:59:59', $time ), - 'date_end_gmt' => date( 'Y-m-d 23:59:59', $time ), - 'subtotals' => (object) array( - 'items_sold' => 4, - 'net_revenue' => 100.0, - 'orders_count' => 1, - 'products_count' => 1, - 'variations_count' => 1, - 'segments' => array(), - ), - ), - ), - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $expected_reports, $reports ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 2, count( $properties ) ); - $this->assertArrayHasKey( 'totals', $properties ); - $this->assertArrayHasKey( 'intervals', $properties ); - - $totals = $properties['totals']['properties']; - $this->assertEquals( 4, count( $totals ) ); - $this->assertArrayHasKey( 'net_revenue', $totals ); - $this->assertArrayHasKey( 'items_sold', $totals ); - $this->assertArrayHasKey( 'orders_count', $totals ); - $this->assertArrayHasKey( 'segments', $totals ); - - $intervals = $properties['intervals']['items']['properties']; - $this->assertEquals( 6, count( $intervals ) ); - $this->assertArrayHasKey( 'interval', $intervals ); - $this->assertArrayHasKey( 'date_start', $intervals ); - $this->assertArrayHasKey( 'date_start_gmt', $intervals ); - $this->assertArrayHasKey( 'date_end', $intervals ); - $this->assertArrayHasKey( 'date_end_gmt', $intervals ); - $this->assertArrayHasKey( 'subtotals', $intervals ); - - $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; - $this->assertEquals( 4, count( $subtotals ) ); - $this->assertArrayHasKey( 'net_revenue', $subtotals ); - $this->assertArrayHasKey( 'items_sold', $subtotals ); - $this->assertArrayHasKey( 'orders_count', $subtotals ); - $this->assertArrayHasKey( 'segments', $subtotals ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Products.php b/unit-tests/Tests/Version4/Reports/Products.php deleted file mode 100644 index becee6c9073..00000000000 --- a/unit-tests/Tests/Version4/Reports/Products.php +++ /dev/null @@ -1,161 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - QueueHelper::run_all_pending(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - - $product_report = reset( $reports ); - - $this->assertEquals( $product->get_id(), $product_report['product_id'] ); - $this->assertEquals( 4, $product_report['items_sold'] ); - $this->assertEquals( 1, $product_report['orders_count'] ); - $this->assertArrayHasKey( '_links', $product_report ); - $this->assertArrayHasKey( 'product', $product_report['_links'] ); - } - - /** - * Test getting reports with the `products` param. - * - * @since 3.5.0 - */ - public function test_get_reports_products_param() { - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $product_2 = new \WC_Product_Simple(); - $product_2->set_name( 'Test Product 2' ); - $product_2->set_regular_price( 25 ); - $product_2->save(); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'products' => $product->get_id() . ',' . $product_2->get_id(), - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $product_report = reset( $reports ); - - $this->assertEquals( $product->get_id(), $product_report['product_id'] ); - $this->assertEquals( 4, $product_report['items_sold'] ); - $this->assertEquals( 1, $product_report['orders_count'] ); - $this->assertArrayHasKey( '_links', $product_report ); - $this->assertArrayHasKey( 'product', $product_report['_links'] ); - - $product_report = next( $reports ); - - $this->assertEquals( $product_2->get_id(), $product_report['product_id'] ); - $this->assertEquals( null, $product_report['items_sold'] ); - $this->assertEquals( null, $product_report['orders_count'] ); - $this->assertArrayHasKey( '_links', $product_report ); - $this->assertArrayHasKey( 'product', $product_report['_links'] ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 5, count( $properties ) ); - $this->assertArrayHasKey( 'product_id', $properties ); - $this->assertArrayHasKey( 'items_sold', $properties ); - $this->assertArrayHasKey( 'net_revenue', $properties ); - $this->assertArrayHasKey( 'orders_count', $properties ); - $this->assertArrayHasKey( 'extended_info', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/RevenueStats.php b/unit-tests/Tests/Version4/Reports/RevenueStats.php deleted file mode 100644 index c750938ef5a..00000000000 --- a/unit-tests/Tests/Version4/Reports/RevenueStats.php +++ /dev/null @@ -1,126 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - // @todo update after report interface is done. - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $data ) ); // @todo Update results after implement report interface. - // $this->assertEquals( array(), $reports ); // @todo Update results after implement report interface. - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 2, count( $properties ) ); - $this->assertArrayHasKey( 'totals', $properties ); - $this->assertArrayHasKey( 'intervals', $properties ); - - $totals = $properties['totals']['properties']; - $this->assertEquals( 11, count( $totals ) ); - $this->assertArrayHasKey( 'gross_revenue', $totals ); - $this->assertArrayHasKey( 'net_revenue', $totals ); - $this->assertArrayHasKey( 'coupons', $totals ); - $this->assertArrayHasKey( 'coupons_count', $totals ); - $this->assertArrayHasKey( 'shipping', $totals ); - $this->assertArrayHasKey( 'taxes', $totals ); - $this->assertArrayHasKey( 'refunds', $totals ); - $this->assertArrayHasKey( 'orders_count', $totals ); - $this->assertArrayHasKey( 'num_items_sold', $totals ); - $this->assertArrayHasKey( 'products', $totals ); - $this->assertArrayHasKey( 'segments', $totals ); - - $intervals = $properties['intervals']['items']['properties']; - $this->assertEquals( 6, count( $intervals ) ); - $this->assertArrayHasKey( 'interval', $intervals ); - $this->assertArrayHasKey( 'date_start', $intervals ); - $this->assertArrayHasKey( 'date_start_gmt', $intervals ); - $this->assertArrayHasKey( 'date_end', $intervals ); - $this->assertArrayHasKey( 'date_end_gmt', $intervals ); - $this->assertArrayHasKey( 'subtotals', $intervals ); - - $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; - $this->assertEquals( 10, count( $subtotals ) ); - $this->assertArrayHasKey( 'gross_revenue', $subtotals ); - $this->assertArrayHasKey( 'net_revenue', $subtotals ); - $this->assertArrayHasKey( 'coupons', $subtotals ); - $this->assertArrayHasKey( 'coupons_count', $subtotals ); - $this->assertArrayHasKey( 'shipping', $subtotals ); - $this->assertArrayHasKey( 'taxes', $subtotals ); - $this->assertArrayHasKey( 'refunds', $subtotals ); - $this->assertArrayHasKey( 'orders_count', $subtotals ); - $this->assertArrayHasKey( 'num_items_sold', $subtotals ); - $this->assertArrayHasKey( 'segments', $subtotals ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Stock.php b/unit-tests/Tests/Version4/Reports/Stock.php deleted file mode 100644 index 9fc688a173e..00000000000 --- a/unit-tests/Tests/Version4/Reports/Stock.php +++ /dev/null @@ -1,114 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - */ - public function test_get_reports() { - // Populate all of the data. - $low_stock = new \WC_Product_Simple(); - $low_stock->set_name( 'Test low stock' ); - $low_stock->set_regular_price( 5 ); - $low_stock->set_manage_stock( true ); - $low_stock->set_stock_quantity( 1 ); - $low_stock->set_stock_status( 'instock' ); - $low_stock->save(); - - $out_of_stock = new \WC_Product_Simple(); - $out_of_stock->set_name( 'Test out of stock' ); - $out_of_stock->set_regular_price( 5 ); - $out_of_stock->set_stock_status( 'outofstock' ); - $out_of_stock->save(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_param( 'include', implode( ',', array( $low_stock->get_id(), $out_of_stock->get_id() ) ) ); - $request->set_param( 'orderby', 'id' ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $this->assertEquals( $low_stock->get_id(), $reports[0]['id'] ); - $this->assertEquals( 'instock', $reports[0]['stock_status'] ); - $this->assertEquals( 1, $reports[0]['stock_quantity'] ); - $this->assertArrayHasKey( '_links', $reports[0] ); - $this->assertArrayHasKey( 'product', $reports[0]['_links'] ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_param( 'include', implode( ',', array( $low_stock->get_id(), $out_of_stock->get_id() ) ) ); - $request->set_param( 'type', 'lowstock' ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - } - - /** - * Test getting reports without valid permissions. - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 7, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'parent_id', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'sku', $properties ); - $this->assertArrayHasKey( 'stock_status', $properties ); - $this->assertArrayHasKey( 'stock_quantity', $properties ); - $this->assertArrayHasKey( 'manage_stock', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/StockStats.php b/unit-tests/Tests/Version4/Reports/StockStats.php deleted file mode 100644 index 51248a4fb4d..00000000000 --- a/unit-tests/Tests/Version4/Reports/StockStats.php +++ /dev/null @@ -1,131 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - */ - public function test_get_reports() { - $number_of_low_stock = 3; - for ( $i = 1; $i <= $number_of_low_stock; $i++ ) { - $low_stock = new \WC_Product_Simple(); - $low_stock->set_name( "Test low stock {$i}" ); - $low_stock->set_regular_price( 5 ); - $low_stock->set_manage_stock( true ); - $low_stock->set_stock_quantity( 1 ); - $low_stock->set_stock_status( 'instock' ); - $low_stock->save(); - } - - $number_of_out_of_stock = 6; - for ( $i = 1; $i <= $number_of_out_of_stock; $i++ ) { - $out_of_stock = new \WC_Product_Simple(); - $out_of_stock->set_name( "Test out of stock {$i}" ); - $out_of_stock->set_regular_price( 5 ); - $out_of_stock->set_stock_status( 'outofstock' ); - $out_of_stock->save(); - } - - $number_of_in_stock = 10; - for ( $i = 1; $i <= $number_of_in_stock; $i++ ) { - $in_stock = new \WC_Product_Simple(); - $in_stock->set_name( "Test in stock {$i}" ); - $in_stock->set_regular_price( 25 ); - $in_stock->save(); - } - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertArrayHasKey( 'totals', $reports ); - $this->assertEquals( 19, $reports['totals']['products'] ); - $this->assertEquals( 6, $reports['totals']['outofstock'] ); - $this->assertEquals( 0, $reports['totals']['onbackorder'] ); - $this->assertEquals( 3, $reports['totals']['lowstock'] ); - $this->assertEquals( 13, $reports['totals']['instock'] ); - - // Test backorder and cache update. - $backorder_stock = new \WC_Product_Simple(); - $backorder_stock->set_name( 'Test backorder' ); - $backorder_stock->set_regular_price( 5 ); - $backorder_stock->set_stock_status( 'onbackorder' ); - $backorder_stock->save(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 20, $reports['totals']['products'] ); - $this->assertEquals( 6, $reports['totals']['outofstock'] ); - $this->assertEquals( 1, $reports['totals']['onbackorder'] ); - $this->assertEquals( 3, $reports['totals']['lowstock'] ); - $this->assertEquals( 13, $reports['totals']['instock'] ); - } - - /** - * Test getting reports without valid permissions. - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertCount( 1, $properties ); - $this->assertArrayHasKey( 'totals', $properties ); - $this->assertCount( 5, $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'products', $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'outofstock', $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'onbackorder', $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'lowstock', $properties['totals']['properties'] ); - $this->assertArrayHasKey( 'instock', $properties['totals']['properties'] ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/TaxStats.php b/unit-tests/Tests/Version4/Reports/TaxStats.php deleted file mode 100644 index 0c8eebd9f92..00000000000 --- a/unit-tests/Tests/Version4/Reports/TaxStats.php +++ /dev/null @@ -1,163 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - global $wpdb; - - // Populate all of the data. - $tax = \WC_Tax::_insert_tax_rate( - array( - 'tax_rate_country' => 'US', - 'tax_rate_state' => '', - 'tax_rate' => '7', - 'tax_rate_name' => 'TestTax', - 'tax_rate_priority' => '1', - 'tax_rate_compound' => '0', - 'tax_rate_shipping' => '1', - 'tax_rate_order' => '1', - 'tax_rate_class' => '', - ) - ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->set_tax_class( 'TestTax' ); - $product->save(); - - update_option( 'woocommerce_calc_taxes', 'yes' ); - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->calculate_taxes(); - $order->save(); - - // Add refunds to line items. - foreach ( $order->get_items() as $item_id => $item ) { - $refund = array( - 'amount' => 1, - 'reason' => 'Testing line item refund', - 'order_id' => $order->get_id(), - 'line_items' => array( - $item_id => array( - 'qty' => 1, - 'refund_total' => 1, - 'refund_tax' => array( $tax => 1 ), - ), - ), - ); - $wc_refund = wc_create_refund( $refund ); - } - - QueueHelper::run_all_pending(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $tax_report = reset( $reports ); - - $this->assertEquals( 1, $tax_report['tax_codes'] ); - $this->assertEquals( 6.7, $tax_report['total_tax'] ); // 110 * 0.07 (tax rate) - 1 (refund) - $this->assertEquals( 6, $tax_report['order_tax'] ); // 100 * 0.07 (tax rate) - 1 (refund) - $this->assertEquals( 0.7, $tax_report['shipping_tax'] ); - $this->assertEquals( 1, $tax_report['orders_count'] ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $totals = $properties['totals']['properties']; - - $this->assertEquals( 6, count( $totals ) ); - $this->assertArrayHasKey( 'order_tax', $totals ); - $this->assertArrayHasKey( 'orders_count', $totals ); - $this->assertArrayHasKey( 'shipping_tax', $totals ); - $this->assertArrayHasKey( 'tax_codes', $totals ); - $this->assertArrayHasKey( 'total_tax', $totals ); - $this->assertArrayHasKey( 'segments', $totals ); - - $intervals = $properties['intervals']['items']['properties']; - $this->assertEquals( 6, count( $intervals ) ); - $this->assertArrayHasKey( 'interval', $intervals ); - $this->assertArrayHasKey( 'date_start', $intervals ); - $this->assertArrayHasKey( 'date_start_gmt', $intervals ); - $this->assertArrayHasKey( 'date_end', $intervals ); - $this->assertArrayHasKey( 'date_end_gmt', $intervals ); - $this->assertArrayHasKey( 'subtotals', $intervals ); - - $subtotals = $properties['intervals']['items']['properties']['subtotals']['properties']; - $this->assertEquals( 6, count( $subtotals ) ); - $this->assertArrayHasKey( 'order_tax', $subtotals ); - $this->assertArrayHasKey( 'orders_count', $subtotals ); - $this->assertArrayHasKey( 'shipping_tax', $subtotals ); - $this->assertArrayHasKey( 'tax_codes', $subtotals ); - $this->assertArrayHasKey( 'total_tax', $subtotals ); - $this->assertArrayHasKey( 'segments', $subtotals ); - - } -} diff --git a/unit-tests/Tests/Version4/Reports/Taxes.php b/unit-tests/Tests/Version4/Reports/Taxes.php deleted file mode 100644 index d5f134d59a3..00000000000 --- a/unit-tests/Tests/Version4/Reports/Taxes.php +++ /dev/null @@ -1,351 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - global $wpdb; - - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $wpdb->insert( - $wpdb->prefix . 'woocommerce_tax_rates', - array( - 'tax_rate_id' => 1, - 'tax_rate' => '7', - 'tax_rate_country' => 'US', - 'tax_rate_state' => 'GA', - 'tax_rate_name' => 'TestTax', - 'tax_rate_priority' => 1, - 'tax_rate_order' => 1, - ) - ); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - // @todo Remove this once order data is synced to wc_order_tax_lookup - $wpdb->insert( - $wpdb->prefix . 'wc_order_tax_lookup', - array( - 'order_id' => $order->get_id(), - 'tax_rate_id' => 1, - 'date_created' => date( 'Y-m-d H:i:s' ), - 'shipping_tax' => 2, - 'order_tax' => 5, - 'total_tax' => 7, - ) - ); - - QueueHelper::run_all_pending(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - - $tax_report = reset( $reports ); - - $this->assertEquals( 1, $tax_report['tax_rate_id'] ); - $this->assertEquals( 'TestTax', $tax_report['name'] ); - $this->assertEquals( 7, $tax_report['tax_rate'] ); - $this->assertEquals( 'US', $tax_report['country'] ); - $this->assertEquals( 'GA', $tax_report['state'] ); - $this->assertEquals( 7, $tax_report['total_tax'] ); - $this->assertEquals( 5, $tax_report['order_tax'] ); - $this->assertEquals( 2, $tax_report['shipping_tax'] ); - $this->assertEquals( 1, $tax_report['orders_count'] ); - } - - /** - * Test getting reports with the `taxes` report. - * - * @since 3.5.0 - */ - public function test_get_reports_taxes_param() { - global $wpdb; - - // Populate all of the data. - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_regular_price( 25 ); - $product->save(); - - $wpdb->insert( - $wpdb->prefix . 'woocommerce_tax_rates', - array( - 'tax_rate_id' => 1, - 'tax_rate' => '7', - 'tax_rate_country' => 'US', - 'tax_rate_state' => 'GA', - 'tax_rate_name' => 'TestTax', - 'tax_rate_priority' => 1, - 'tax_rate_order' => 1, - ) - ); - - $wpdb->insert( - $wpdb->prefix . 'woocommerce_tax_rates', - array( - 'tax_rate_id' => 2, - 'tax_rate' => '8', - 'tax_rate_country' => 'CA', - 'tax_rate_state' => 'ON', - 'tax_rate_name' => 'TestTax 2', - 'tax_rate_priority' => 1, - 'tax_rate_order' => 1, - ) - ); - - $order = OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - // @todo Remove this once order data is synced to wc_order_tax_lookup - $wpdb->insert( - $wpdb->prefix . 'wc_order_tax_lookup', - array( - 'order_id' => $order->get_id(), - 'tax_rate_id' => 1, - 'date_created' => date( 'Y-m-d H:i:s' ), - 'shipping_tax' => 2, - 'order_tax' => 5, - 'total_tax' => 7, - ) - ); - - QueueHelper::run_all_pending(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'taxes' => '1,2', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $tax_report = reset( $reports ); - - $this->assertEquals( 2, $tax_report['tax_rate_id'] ); - $this->assertEquals( 'TestTax 2', $tax_report['name'] ); - $this->assertEquals( 8, $tax_report['tax_rate'] ); - $this->assertEquals( 'CA', $tax_report['country'] ); - $this->assertEquals( 'ON', $tax_report['state'] ); - $this->assertEquals( 0, $tax_report['total_tax'] ); - $this->assertEquals( 0, $tax_report['order_tax'] ); - $this->assertEquals( 0, $tax_report['shipping_tax'] ); - $this->assertEquals( 0, $tax_report['orders_count'] ); - - $tax_report = next( $reports ); - - $this->assertEquals( 1, $tax_report['tax_rate_id'] ); - $this->assertEquals( 'TestTax', $tax_report['name'] ); - $this->assertEquals( 7, $tax_report['tax_rate'] ); - $this->assertEquals( 'US', $tax_report['country'] ); - $this->assertEquals( 'GA', $tax_report['state'] ); - $this->assertEquals( 7, $tax_report['total_tax'] ); - $this->assertEquals( 5, $tax_report['order_tax'] ); - $this->assertEquals( 2, $tax_report['shipping_tax'] ); - $this->assertEquals( 1, $tax_report['orders_count'] ); - } - - /** - * Test getting reports with param `orderby=rate`. - * - * @since 3.5.0 - */ - public function test_get_reports_orderby_tax_rate() { - global $wpdb; - - $wpdb->insert( - $wpdb->prefix . 'woocommerce_tax_rates', - array( - 'tax_rate_id' => 1, - 'tax_rate' => '7', - 'tax_rate_country' => 'US', - 'tax_rate_state' => 'GA', - 'tax_rate_name' => 'TestTax', - 'tax_rate_priority' => 1, - 'tax_rate_order' => 1, - ) - ); - - $wpdb->insert( - $wpdb->prefix . 'woocommerce_tax_rates', - array( - 'tax_rate_id' => 2, - 'tax_rate' => '10', - 'tax_rate_country' => 'CA', - 'tax_rate_state' => 'ON', - 'tax_rate_name' => 'TestTax 2', - 'tax_rate_priority' => 1, - 'tax_rate_order' => 1, - ) - ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'order' => 'asc', - 'orderby' => 'rate', - 'taxes' => '1,2', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $this->assertEquals( 1, $reports[0]['tax_rate_id'] ); - $this->assertEquals( 7, $reports[0]['tax_rate'] ); - - $this->assertEquals( 2, $reports[1]['tax_rate_id'] ); - $this->assertEquals( 10, $reports[1]['tax_rate'] ); - } - - /** - * Test getting reports with param `orderby=tax_code`. - * - * @since 3.5.0 - */ - public function test_get_reports_orderby_tax_code() { - global $wpdb; - - $wpdb->insert( - $wpdb->prefix . 'woocommerce_tax_rates', - array( - 'tax_rate_id' => 1, - 'tax_rate' => '7', - 'tax_rate_country' => 'US', - 'tax_rate_state' => 'GA', - 'tax_rate_name' => 'TestTax', - 'tax_rate_priority' => 1, - 'tax_rate_order' => 1, - ) - ); - - $wpdb->insert( - $wpdb->prefix . 'woocommerce_tax_rates', - array( - 'tax_rate_id' => 2, - 'tax_rate' => '10', - 'tax_rate_country' => 'CA', - 'tax_rate_state' => 'ON', - 'tax_rate_name' => 'TestTax 2', - 'tax_rate_priority' => 1, - 'tax_rate_order' => 1, - ) - ); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'order' => 'asc', - 'orderby' => 'tax_code', - 'taxes' => '1,2', - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $this->assertEquals( 2, $reports[0]['tax_rate_id'] ); - - $this->assertEquals( 1, $reports[1]['tax_rate_id'] ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 10, count( $properties ) ); - $this->assertArrayHasKey( 'tax_rate_id', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'tax_rate', $properties ); - $this->assertArrayHasKey( 'country', $properties ); - $this->assertArrayHasKey( 'state', $properties ); - $this->assertArrayHasKey( 'priority', $properties ); - $this->assertArrayHasKey( 'total_tax', $properties ); - $this->assertArrayHasKey( 'order_tax', $properties ); - $this->assertArrayHasKey( 'shipping_tax', $properties ); - $this->assertArrayHasKey( 'orders_count', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/Reports/Variations.php b/unit-tests/Tests/Version4/Reports/Variations.php deleted file mode 100644 index 48312f0be30..00000000000 --- a/unit-tests/Tests/Version4/Reports/Variations.php +++ /dev/null @@ -1,173 +0,0 @@ -server->get_routes(); - - $this->assertArrayHasKey( $this->endpoint, $routes ); - } - - /** - * Test getting reports. - * - * @since 3.5.0 - */ - public function test_get_reports() { - // Populate all of the data. - $variation = new \WC_Product_Variation(); - $variation->set_name( 'Test Variation' ); - $variation->set_regular_price( 25 ); - $variation->set_attributes( array( 'color' => 'green' ) ); - $variation->save(); - - $order = OrderHelper::create_order( 1, $variation ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - QueueHelper::run_all_pending(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $reports ) ); - - $variation_report = reset( $reports ); - - $this->assertEquals( $variation->get_id(), $variation_report['variation_id'] ); - $this->assertEquals( 4, $variation_report['items_sold'] ); - $this->assertEquals( 1, $variation_report['orders_count'] ); - $this->assertArrayHasKey( '_links', $variation_report ); - $this->assertArrayHasKey( 'extended_info', $variation_report ); - $this->assertArrayHasKey( 'product', $variation_report['_links'] ); - $this->assertArrayHasKey( 'variation', $variation_report['_links'] ); - } - - /** - * Test getting reports with the `variations` param. - * - * @since 3.5.0 - */ - public function test_get_reports_variations_param() { - // Populate all of the data. - $variation = new \WC_Product_Variation(); - $variation->set_name( 'Test Variation' ); - $variation->set_regular_price( 25 ); - $variation->set_attributes( array( 'color' => 'green' ) ); - $variation->save(); - - $variation_2 = new \WC_Product_Variation(); - $variation_2->set_name( 'Test Variation 2' ); - $variation_2->set_regular_price( 100 ); - $variation_2->set_attributes( array( 'color' => 'red' ) ); - $variation_2->save(); - - $order = OrderHelper::create_order( 1, $variation ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); // $25 x 4. - $order->save(); - - QueueHelper::run_all_pending(); - - $request = new WP_REST_Request( 'GET', $this->endpoint ); - $request->set_query_params( - array( - 'product_includes' => $variation->get_parent_id(), - 'products' => $variation->get_parent_id(), - 'variations' => $variation->get_id() . ',' . $variation_2->get_id(), - ) - ); - $response = $this->server->dispatch( $request ); - $reports = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $reports ) ); - - $variation_report = reset( $reports ); - - $this->assertEquals( $variation->get_id(), $variation_report['variation_id'] ); - $this->assertEquals( 4, $variation_report['items_sold'] ); - $this->assertEquals( 1, $variation_report['orders_count'] ); - $this->assertArrayHasKey( '_links', $variation_report ); - $this->assertArrayHasKey( 'extended_info', $variation_report ); - $this->assertArrayHasKey( 'product', $variation_report['_links'] ); - $this->assertArrayHasKey( 'variation', $variation_report['_links'] ); - - $variation_report = next( $reports ); - - $this->assertEquals( $variation_2->get_id(), $variation_report['variation_id'] ); - $this->assertEquals( 0, $variation_report['items_sold'] ); - $this->assertEquals( 0, $variation_report['orders_count'] ); - $this->assertArrayHasKey( '_links', $variation_report ); - $this->assertArrayHasKey( 'extended_info', $variation_report ); - $this->assertArrayHasKey( 'product', $variation_report['_links'] ); - $this->assertArrayHasKey( 'variation', $variation_report['_links'] ); - } - - /** - * Test getting reports without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test reports schema. - * - * @since 3.5.0 - */ - public function test_reports_schema() { - $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 6, count( $properties ) ); - $this->assertArrayHasKey( 'product_id', $properties ); - $this->assertArrayHasKey( 'variation_id', $properties ); - $this->assertArrayHasKey( 'items_sold', $properties ); - $this->assertArrayHasKey( 'net_revenue', $properties ); - $this->assertArrayHasKey( 'orders_count', $properties ); - $this->assertArrayHasKey( 'extended_info', $properties ); - } -} From dd012b28567777e2b00aa16182b568255aa2b1f2 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 11:37:56 +0100 Subject: [PATCH 110/440] Update composer script --- classmap.php.bak | 104 ++++++++++ composer.json | 3 +- src/Controllers/Version4/Reports.php | 295 --------------------------- unit-tests/AbstractReportsTest.php | 57 ------ unit-tests/Tests/Version4/Data.php | 2 +- 5 files changed, 106 insertions(+), 355 deletions(-) create mode 100644 classmap.php.bak delete mode 100644 src/Controllers/Version4/Reports.php delete mode 100644 unit-tests/AbstractReportsTest.php diff --git a/classmap.php.bak b/classmap.php.bak new file mode 100644 index 00000000000..742c3168c7b --- /dev/null +++ b/classmap.php.bak @@ -0,0 +1,104 @@ + $baseDir . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', +); diff --git a/composer.json b/composer.json index 714453b2d35..24043ef69b1 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,6 @@ "name": "woocommerce/woocommerce-rest-api", "description": "The WooCommerce core REST API.", "homepage": "https://github.com/woocommerce/woocommerce-rest-api", - "type": "project", "license": "GPL-3.0-or-later", "type": "wordpress-plugin", "prefer-stable": true, @@ -22,7 +21,7 @@ "pre-autoload-dump": [ "composer dump-autoload --no-dev --no-scripts", "SlowProg\\CopyFile\\ScriptHandler::copy", - "sed -i '' 's/\\$baseDir = dirname(\\$vendorDir)/\\$baseDir = __DIR__/g' classmap.php" + "sed -i.bak -e 's/\\$baseDir = dirname(\\$vendorDir)/\\$baseDir = __DIR__/g' classmap.php" ] }, "autoload": { diff --git a/src/Controllers/Version4/Reports.php b/src/Controllers/Version4/Reports.php deleted file mode 100644 index b989bb17dde..00000000000 --- a/src/Controllers/Version4/Reports.php +++ /dev/null @@ -1,295 +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 - ); - } - - /** - * Check whether a given request has permission to read reports. - * - * @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( 'reports', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - - /** - * Get all reports. - * - * @param \WP_REST_Request $request Request data. - * @return array|\WP_Error - */ - public function get_items( $request ) { - $data = []; - $reports = []; - if ( class_exists( 'WC_Admin_Reports_Sync' ) ) { - $reports = array( - array( - 'slug' => 'performance-indicators', - 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'woocommerce' ), - ), - array( - 'slug' => 'revenue/stats', - 'description' => __( 'Stats about revenue.', 'woocommerce' ), - ), - array( - 'slug' => 'orders/stats', - 'description' => __( 'Stats about orders.', 'woocommerce' ), - ), - array( - 'slug' => 'products', - 'description' => __( 'Products detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'products/stats', - 'description' => __( 'Stats about products.', 'woocommerce' ), - ), - array( - 'slug' => 'categories', - 'description' => __( 'Product categories detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'categories/stats', - 'description' => __( 'Stats about product categories.', 'woocommerce' ), - ), - array( - 'slug' => 'coupons', - 'description' => __( 'Coupons detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'coupons/stats', - 'description' => __( 'Stats about coupons.', 'woocommerce' ), - ), - array( - 'slug' => 'taxes', - 'description' => __( 'Taxes detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'taxes/stats', - 'description' => __( 'Stats about taxes.', 'woocommerce' ), - ), - array( - 'slug' => 'downloads', - 'description' => __( 'Product downloads detailed reports.', 'woocommerce' ), - ), - array( - 'slug' => 'downloads/stats', - 'description' => __( 'Stats about product downloads.', 'woocommerce' ), - ), - array( - 'slug' => 'customers', - 'description' => __( 'Customers detailed reports.', 'woocommerce' ), - ), - ); - } - - /** - * Filter the list of allowed reports, so that data can be loaded from third party extensions in addition to WooCommerce core. - * Array items should be in format of array( 'slug' => 'downloads/stats', 'description' => '', - * 'url' => '', and 'path' => '/wc-ext/v1/...'. - * - * @param array $endpoints The list of allowed reports.. - */ - $reports = apply_filters( 'woocommerce_admin_reports', $reports ); - - foreach ( $reports as $report ) { - if ( empty( $report['slug'] ) ) { - continue; - } - - if ( empty( $report['path'] ) ) { - $report['path'] = '/' . $this->namespace . '/reports/' . $report['slug']; - } - - // Allows a different admin page to be loaded here, - // or allows an empty url if no report exists for a set of performance indicators. - if ( ! isset( $report['url'] ) ) { - if ( '/stats' === substr( $report['slug'], -6 ) ) { - $url_slug = substr( $report['slug'], 0, -6 ); - } else { - $url_slug = $report['slug']; - } - - $report['url'] = '/analytics/' . $url_slug; - } - - $item = $this->prepare_item_for_response( (object) $report, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - return rest_ensure_response( $data ); - } - - /** - * Get the order number for an order. If no filter is present for `woocommerce_order_number`, we can just return the ID. - * Returns the parent order number if the order is actually a refund. - * - * @param int $order_id Order ID. - * @return string - */ - public function get_order_number( $order_id ) { - $order = wc_get_order( $order_id ); - - if ( 'shop_order_refund' === $order->get_type() ) { - $order = wc_get_order( $order->get_parent_id() ); - } - - if ( ! has_filter( 'woocommerce_order_number' ) ) { - return $order->get_id(); - } - - return $order->get_order_number(); - } - - /** - * 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 = array( - 'slug' => $report->slug, - 'description' => $report->description, - 'path' => $report->path, - ); - - $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( - array( - 'self' => array( - 'href' => rest_url( $report->path ), - ), - 'report' => array( - 'href' => $report->url, - ), - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - ) - ); - - /** - * 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', $response, $report, $request ); - } - - /** - * 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', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'path' => array( - 'description' => __( 'API path.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } - - /** - * Get order statuses without prefixes. - * - * @return array - */ - public function get_order_statuses() { - $order_statuses = array(); - - foreach ( array_keys( wc_get_order_statuses() ) as $status ) { - $order_statuses[] = str_replace( 'wc-', '', $status ); - } - - return $order_statuses; - } -} diff --git a/unit-tests/AbstractReportsTest.php b/unit-tests/AbstractReportsTest.php deleted file mode 100644 index c5617c8b355..00000000000 --- a/unit-tests/AbstractReportsTest.php +++ /dev/null @@ -1,57 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup test reports categories data. - */ - public function setUp() { - if ( ! class_exists( '\WC_Admin_Reports_Sync' ) ) { - $this->markTestSkipped( 'Skipping reports tests - WC_Admin_Reports_Sync class not found.' ); - return; - } - - parent::setUp(); - wp_set_current_user( self::$user ); - - global $wpdb; - $wpdb->query( "DELETE FROM $wpdb->prefix" . \WC_Admin_Reports_Orders_Stats_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . \WC_Admin_Reports_Products_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . \WC_Admin_Reports_Coupons_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - $wpdb->query( "DELETE FROM $wpdb->prefix" . \WC_Admin_Reports_Customers_Data_Store::TABLE_NAME ); // @codingStandardsIgnoreLine. - } - -} diff --git a/unit-tests/Tests/Version4/Data.php b/unit-tests/Tests/Version4/Data.php index 9916da2ecc2..dd19a5eeb64 100644 --- a/unit-tests/Tests/Version4/Data.php +++ b/unit-tests/Tests/Version4/Data.php @@ -14,7 +14,7 @@ use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; /** * WC Tests API Data */ -class Data extends AbstractReportsTest { +class Data { /** * Endpoints. From 4dff2b8c01fce485eb26c203e438339019e199e0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 11:38:41 +0100 Subject: [PATCH 111/440] remove reports test --- unit-tests/Bootstrap.php | 1 - unit-tests/Tests/Version4/Data.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index 747afe884eb..11290cb1797 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -128,7 +128,6 @@ class Bootstrap { require_once $this->tests_dir . '/Helpers/SettingsHelper.php'; require_once $this->tests_dir . '/Helpers/QueueHelper.php'; require_once $this->tests_dir . '/AbstractRestApiTest.php'; - require_once $this->tests_dir . '/AbstractReportsTest.php'; } } diff --git a/unit-tests/Tests/Version4/Data.php b/unit-tests/Tests/Version4/Data.php index dd19a5eeb64..f57849732a3 100644 --- a/unit-tests/Tests/Version4/Data.php +++ b/unit-tests/Tests/Version4/Data.php @@ -9,8 +9,6 @@ namespace WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\UnitTests\AbstractReportsTest; - /** * WC Tests API Data */ From ca07a6d7f6d1e0e09a94ca47c2d65b506e45a95c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 11:43:20 +0100 Subject: [PATCH 112/440] Remove -> public --- src/Controllers/Version4/AbstractObjectsController.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 1c593393341..13aea649344 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -182,10 +182,6 @@ abstract class AbstractObjectsController extends AbstractController { $data = $this->prepare_object_for_response( $object, $request ); $response = rest_ensure_response( $data ); - if ( $this->public ) { - $response->link_header( 'alternate', $this->get_permalink( $object ), array( 'type' => 'text/html' ) ); - } - return $response; } From d47e7a3473f8d0acc9d37efd60b1356748b4d840 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 11:53:24 +0100 Subject: [PATCH 113/440] config --- .scrutinizer.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 123a68901cd..d5c1c1251f8 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -22,6 +22,8 @@ checks: verify_argument_usable_as_reference: false verify_property_names: false filter: + dependency_paths: + - wordpress/ excluded_paths: - src/Controllers/Version1/ - src/Controllers/Version2/ @@ -29,3 +31,9 @@ filter: - unit-tests/ - vendor/ - classmap.php +build: + nodes: + analysis: + dependencies: + before: + - composer require --dev johnpbloch/wordpress From a83d6ff90292a2a6923b8e4ee7bd3a59fd32c7a4 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 11:57:40 +0100 Subject: [PATCH 114/440] disable tests --- .scrutinizer.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index d5c1c1251f8..001b4db133c 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -32,6 +32,9 @@ filter: - vendor/ - classmap.php build: + tests: + override: + command: "php -v" nodes: analysis: dependencies: From a2f4f15559b3c2014627da991ca60ecc658958a3 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 12:08:46 +0100 Subject: [PATCH 115/440] config --- .scrutinizer.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 001b4db133c..7005aacb60b 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -33,10 +33,10 @@ filter: - classmap.php build: tests: - override: - command: "php -v" - nodes: - analysis: - dependencies: - before: - - composer require --dev johnpbloch/wordpress + override: + command: "php -v" + nodes: + analysis: + dependencies: + before: + - composer require --dev johnpbloch/wordpress From 76ee42ff6b77019860644b329352591f8f803f92 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 12:34:54 +0100 Subject: [PATCH 116/440] Date queries --- .../Version4/AbstractObjectsController.php | 31 +++++++++++++++++-- src/Controllers/Version4/_changelog.md | 2 ++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 13aea649344..0e85ba5af4a 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -325,6 +325,7 @@ abstract class AbstractObjectsController extends AbstractController { } $args['date_query'] = array(); + // Set before into date query. Date query must be specified as an array of an array. if ( isset( $request['before'] ) ) { $args['date_query'][0]['before'] = $request['before']; @@ -335,6 +336,11 @@ abstract class AbstractObjectsController extends AbstractController { $args['date_query'][0]['after'] = $request['after']; } + // Set date query colummn. Defaults to post_date. + if ( isset( $request['date_column'] ) && ! empty( $args['date_query'][0] ) ) { + $args['date_query'][0]['column'] = 'post_' . $request['date_column']; + } + // Force the post_type argument, since it's not a user input variable. $args['post_type'] = $this->post_type; @@ -587,14 +593,34 @@ abstract class AbstractObjectsController extends AbstractController { ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources created 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' ), + 'description' => __( 'Limit response to resources created before a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['date_column'] = array( + 'description' => __( 'When limiting response using after/before, which date column to compare against.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( + 'date', + 'date_gmt', + 'modified', + 'modified_gmt', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['modified_before'] = array( + 'description' => __( 'Limit response to resources modified before a given ISO8601 compliant date.', 'woocommerce' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', @@ -641,6 +667,7 @@ abstract class AbstractObjectsController extends AbstractController { 'default' => 'date', 'enum' => array( 'date', + 'modified', 'id', 'include', 'title', diff --git a/src/Controllers/Version4/_changelog.md b/src/Controllers/Version4/_changelog.md index c66a8effa6e..3c98ab73b96 100644 --- a/src/Controllers/Version4/_changelog.md +++ b/src/Controllers/Version4/_changelog.md @@ -13,6 +13,8 @@ - Product Variations - Added `name`, `type`, `parent_id` to schema. - Reports - Updated with updated list of available reports. - Taxes - Added `code` and `include` params. +- Coupons/Orders/Products - Allow to sort by `modified` date. +- Coupons/Orders/Products - Added `date_column` property to use date, date_gmt, modified, modified_gmt in conjunction with before/after. ## New endpoints From cd04f71cd08bb62d119651255135f689e504ecc6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 13:17:41 +0100 Subject: [PATCH 117/440] external_code_coverage --- .scrutinizer.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 7005aacb60b..e0846d6aed4 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -3,8 +3,6 @@ tools: config: standard: WordPress sensiolabs_security_checker: true - external_code_coverage: - timeout: 2500 checks: php: avoid_closing_tag: false From 8ebd9d01444e7269c836cec91acb843b880b4a94 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 13:28:08 +0100 Subject: [PATCH 118/440] config --- .scrutinizer.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index e0846d6aed4..f3649438a19 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -22,6 +22,7 @@ checks: filter: dependency_paths: - wordpress/ + - woocommerce/ excluded_paths: - src/Controllers/Version1/ - src/Controllers/Version2/ @@ -37,4 +38,5 @@ build: analysis: dependencies: before: - - composer require --dev johnpbloch/wordpress + - composer require --dev johnpbloch/wordpress-core + - composer require --dev woocommerce/woocommerce From d9ef295d7433eb0967da77918db3dd3a24e62169 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 13:38:12 +0100 Subject: [PATCH 119/440] CS --- src/Controllers/Version4/OrderRefunds.php | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Controllers/Version4/OrderRefunds.php b/src/Controllers/Version4/OrderRefunds.php index a8ed226b12b..0a100717fb0 100644 --- a/src/Controllers/Version4/OrderRefunds.php +++ b/src/Controllers/Version4/OrderRefunds.php @@ -120,7 +120,7 @@ class OrderRefunds extends Orders { * * @since 3.0.0 * @param int $id Object ID. - * @return WC_Data + * @return \WC_Data */ protected function get_object( $id ) { return wc_get_order( $id ); @@ -130,7 +130,7 @@ class OrderRefunds extends Orders { * Get formatted item data. * * @since 3.0.0 - * @param WC_Data $object WC_Data instance. + * @param \WC_Data $object WC_Data instance. * @return array */ protected function get_formatted_item_data( $object ) { @@ -174,10 +174,10 @@ class OrderRefunds extends Orders { * * @since 3.0.0 * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { $this->request = $request; @@ -209,7 +209,7 @@ class OrderRefunds extends Orders { * refers to object type being prepared for the response. * * @param \WP_REST_Response $response The response object. - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); @@ -218,10 +218,10 @@ class OrderRefunds extends Orders { /** * Prepare a single order refund output for response. * - * @param WP_Post $post Post object. + * @param \WP_Post $post Post object. * @param \WP_REST_Request $request Request object. * - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function prepare_item_for_response( $post, $request ) { $order = wc_get_order( (int) $request['order_id'] ); @@ -248,7 +248,7 @@ class OrderRefunds extends Orders { // Add line items. foreach ( $refund->get_items() as $item_id => $item ) { - $product = $refund->get_product_from_item( $item ); + $product = $item->get_product(); $product_id = 0; $variation_id = 0; $product_sku = null; @@ -327,7 +327,7 @@ class OrderRefunds extends Orders { * prepared for the response. * * @param \WP_REST_Response $response The response object. - * @param WP_Post $post Post object. + * @param \WP_Post $post Post object. * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); @@ -336,7 +336,7 @@ class OrderRefunds extends Orders { /** * Prepare links for the request. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ @@ -377,7 +377,7 @@ class OrderRefunds extends Orders { * Create a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -420,7 +420,7 @@ class OrderRefunds extends Orders { /** * Fires after a single item is created or updated via the REST API. * - * @param WP_Post $post Post object. + * @param \WP_Post $post Post object. * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ @@ -440,8 +440,8 @@ class OrderRefunds extends Orders { * * @since 3.0.0 * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WP_Error|WC_Data The prepared item, or \WP_Error object on failure. + * @param bool $creating If is creating a new object. + * @return \WP_Error|\WC_Data The prepared item, or \WP_Error object on failure. */ protected function prepare_object_for_database( $request, $creating = false ) { $order = wc_get_order( (int) $request['order_id'] ); @@ -487,7 +487,7 @@ class OrderRefunds extends Orders { * The dynamic portion of the hook name, `$this->post_type`, * refers to the object type slug. * - * @param WC_Data $coupon Object object. + * @param \WC_Data $coupon Object object. * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ @@ -499,7 +499,7 @@ class OrderRefunds extends Orders { * * @since 3.0.0 * @param \WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. + * @param bool $creating If is creating a new object. * @return \WC_Data|\WP_Error */ protected function save_object( $request, $creating = false ) { From c0e2d73467bbd2c97453910bdbca02746c1f2a10 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 13:46:33 +0100 Subject: [PATCH 120/440] cs --- .../Version4/AbstractTermsContoller.php | 18 ++++++++++++-- src/Controllers/Version4/Coupons.php | 2 +- .../Version4/CustomerDownloads.php | 6 ++--- src/Controllers/Version4/Customers.php | 10 ++++---- src/Controllers/Version4/Data.php | 4 ++-- src/Controllers/Version4/Data/Continents.php | 2 +- src/Controllers/Version4/Data/Countries.php | 4 ++-- src/Controllers/Version4/Data/Currencies.php | 6 ++--- src/Controllers/Version4/Data/DownloadIPs.php | 2 +- src/Controllers/Version4/OrderNotes.php | 6 ++--- src/Controllers/Version4/PaymentGateways.php | 2 +- .../Version4/ProductVariations.php | 2 +- src/Controllers/Version4/Products.php | 2 +- src/Controllers/Version4/Settings.php | 4 ++-- src/Controllers/Version4/SettingsOptions.php | 8 +++---- src/Controllers/Version4/ShippingMethods.php | 2 +- src/Controllers/Version4/SystemStatus.php | 9 ++++++- .../Version4/SystemStatusTools.php | 8 +++---- src/Controllers/Version4/TaxClasses.php | 10 ++++---- src/Controllers/Version4/Taxes.php | 24 +++++++++---------- src/Controllers/Version4/Webhooks.php | 12 +++++----- 21 files changed, 82 insertions(+), 61 deletions(-) diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index 3508b79a5d2..fa2596d46b1 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -28,6 +28,20 @@ abstract class AbstractTermsContoller extends AbstractController { */ protected $taxonomy = ''; + /** + * Store total terms. + * + * @var integer + */ + protected $total_terms = 0; + + /** + * Store sort column. + * + * @var string + */ + protected $sort_column = ''; + /** * Register the routes for terms. */ @@ -669,8 +683,8 @@ abstract class AbstractTermsContoller extends AbstractController { * * Uses `$this->sort_column` to determine field to sort by. * - * @param stdClass $left Term object. - * @param stdClass $right Term object. + * @param \stdClass $left Term object. + * @param \stdClass $right Term object. * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left. */ protected function compare_terms( $left, $right ) { diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index a10208c0543..6ba8c0c7118 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -553,7 +553,7 @@ class Coupons extends AbstractObjectsController { * Get a collection of posts and add the code search option to \WP_Query. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( $this, 'add_wp_query_search_code_filter' ), 10, 2 ); diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index 25e94097b04..7e191b957b6 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -91,7 +91,7 @@ class CustomerDownloads extends AbstractController { /** * Prepare a single download output for response. * - * @param stdClass $download Download object. + * @param \stdClass $download Download object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ @@ -123,7 +123,7 @@ class CustomerDownloads extends AbstractController { * Filter customer download data returned from the REST API. * * @param \WP_REST_Response $response The response object. - * @param stdClass $download Download object used to create response. + * @param \stdClass $download Download object used to create response. * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); @@ -132,7 +132,7 @@ class CustomerDownloads extends AbstractController { /** * Prepare links for the request. * - * @param stdClass $download Download object. + * @param \stdClass $download Download object. * @param \WP_REST_Request $request Request object. * @return array Links for the given customer download. */ diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 018c5a6b0ef..f5fbe968727 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -268,7 +268,7 @@ class Customers extends AbstractController { * Get all customers. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $prepared_args = array(); @@ -366,7 +366,7 @@ class Customers extends AbstractController { * * @throws \WC_REST_Exception On invalid params. * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function create_item( $request ) { try { @@ -420,7 +420,7 @@ class Customers extends AbstractController { * Get a single customer. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; @@ -442,7 +442,7 @@ class Customers extends AbstractController { * @throws \WC_REST_Exception On invalid params. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function update_item( $request ) { try { @@ -503,7 +503,7 @@ class Customers extends AbstractController { * Delete a single customer. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function delete_item( $request ) { $id = (int) $request['id']; diff --git a/src/Controllers/Version4/Data.php b/src/Controllers/Version4/Data.php index b5e654badbf..563987e48f5 100644 --- a/src/Controllers/Version4/Data.php +++ b/src/Controllers/Version4/Data.php @@ -77,7 +77,7 @@ class Data extends AbstractController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $data = array(); @@ -111,7 +111,7 @@ class Data extends AbstractController { /** * Prepare a data resource object for serialization. * - * @param stdClass $resource Resource data. + * @param \stdClass $resource Resource data. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ diff --git a/src/Controllers/Version4/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php index 557f9023448..8b96e9ea720 100644 --- a/src/Controllers/Version4/Data/Continents.php +++ b/src/Controllers/Version4/Data/Continents.php @@ -155,7 +155,7 @@ class Continents extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $continents = WC()->countries->get_continents(); diff --git a/src/Controllers/Version4/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php index 60c78e97d73..a135fad36e2 100644 --- a/src/Controllers/Version4/Data/Countries.php +++ b/src/Controllers/Version4/Data/Countries.php @@ -102,7 +102,7 @@ class Countries extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $countries = WC()->countries->get_countries(); @@ -122,7 +122,7 @@ class Countries extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $data = $this->get_country( strtoupper( $request['location'] ), $request ); diff --git a/src/Controllers/Version4/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php index 169767cc29c..428987b9f80 100644 --- a/src/Controllers/Version4/Data/Currencies.php +++ b/src/Controllers/Version4/Data/Currencies.php @@ -101,7 +101,7 @@ class Currencies extends DataController { * Return the list of currencies. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $currencies = get_woocommerce_currencies(); @@ -118,7 +118,7 @@ class Currencies extends DataController { * Return information for a specific currency. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); @@ -132,7 +132,7 @@ class Currencies extends DataController { * Return information for the current site currency. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_current_item( $request ) { $currency = get_option( 'woocommerce_currency' ); diff --git a/src/Controllers/Version4/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php index 07d737792b7..08d340732d2 100644 --- a/src/Controllers/Version4/Data/DownloadIPs.php +++ b/src/Controllers/Version4/Data/DownloadIPs.php @@ -50,7 +50,7 @@ class DownloadIPs extends DataController { * * @since 3.5.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { global $wpdb; diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index ef4bc0c2dae..9b9d17d21c9 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -207,7 +207,7 @@ class OrderNotes extends AbstractController { ); } - remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10 ); $notes = get_comments( $args ); @@ -227,7 +227,7 @@ class OrderNotes extends AbstractController { * Create a single order note. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -273,7 +273,7 @@ class OrderNotes extends AbstractController { * Get a single order note. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; diff --git a/src/Controllers/Version4/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php index 74d80d330f4..ee073b1ea1a 100644 --- a/src/Controllers/Version4/PaymentGateways.php +++ b/src/Controllers/Version4/PaymentGateways.php @@ -114,7 +114,7 @@ class PaymentGateways extends AbstractController { * Get payment gateways. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $payment_gateways = WC()->payment_gateways->payment_gateways(); diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index ab0e9e143af..57b2de3b17b 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -1213,7 +1213,7 @@ class ProductVariations extends Products { * Get a collection of posts and add the post title filter option to \WP_Query. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index bd27277997a..aa77240f159 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -597,7 +597,7 @@ class Products extends AbstractObjectsController { * Get a collection of posts and add the post title filter option to \WP_Query. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index 959437f9f2b..9c57617c938 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -75,7 +75,7 @@ class Settings extends AbstractController { * Update a setting. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function update_item( $request ) { $options_controller = new \WC_REST_Setting_Options_Controller(); @@ -89,7 +89,7 @@ class Settings extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index dbe2c599acf..092ce3eda30 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -106,7 +106,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $setting = $this->get_setting( $request['group_id'], $request['id'] ); @@ -125,7 +125,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $settings = $this->get_group_settings( $request['group_id'] ); @@ -214,7 +214,7 @@ class SettingsOptions extends AbstractController { */ private function get_countries_and_states() { $countries = WC()->countries->get_countries(); - if ( ! $countries ) { + if ( empty( $countries ) ) { return array(); } $output = array(); @@ -304,7 +304,7 @@ class SettingsOptions extends AbstractController { * * @since 3.0.0 * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function update_item( $request ) { $setting = $this->get_setting( $request['group_id'], $request['id'] ); diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php index a829609dbc6..6ab092118f5 100644 --- a/src/Controllers/Version4/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -95,7 +95,7 @@ class ShippingMethods extends AbstractController { * Get shipping methods. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $wc_shipping = \WC_Shipping::instance(); diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index 654b0ccf7bd..547c801aa50 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -23,6 +23,13 @@ class SystemStatus extends AbstractController { */ protected $rest_base = 'system_status'; + /** + * Store available updates. + * + * @var array + */ + protected $available_updates = array(); + /** * Register the route for /system_status */ @@ -60,7 +67,7 @@ class SystemStatus extends AbstractController { * Get a system status info, by section. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $schema = $this->get_item_schema(); diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php index d90f9e72789..956f5b0d763 100644 --- a/src/Controllers/Version4/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -206,7 +206,7 @@ class SystemStatusTools extends AbstractController { * Get a list of system status tools. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $tools = array(); @@ -232,7 +232,7 @@ class SystemStatusTools extends AbstractController { * Return a single tool. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $tools = $this->get_tools(); @@ -257,7 +257,7 @@ class SystemStatusTools extends AbstractController { * Update (execute) a tool. * * @param \WP_REST_Request $request Request data. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function update_item( $request ) { $tools = $this->get_tools(); @@ -416,7 +416,7 @@ class SystemStatusTools extends AbstractController { $attribute_taxonomies = wc_get_attribute_taxonomies(); - if ( $attribute_taxonomies ) { + if ( ! empty( $attribute_taxonomies ) ) { foreach ( $attribute_taxonomies as $attribute ) { delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name ); } diff --git a/src/Controllers/Version4/TaxClasses.php b/src/Controllers/Version4/TaxClasses.php index 770ad1599d6..a6304b9fa74 100644 --- a/src/Controllers/Version4/TaxClasses.php +++ b/src/Controllers/Version4/TaxClasses.php @@ -158,7 +158,7 @@ class TaxClasses extends AbstractController { * Create a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function create_item( $request ) { $exists = false; @@ -191,7 +191,7 @@ class TaxClasses extends AbstractController { /** * Fires after a tax class is created or updated via the REST API. * - * @param stdClass $tax_class Data used to create the tax class. + * @param \stdClass $tax_class Data used to create the tax class. * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating tax class, false when updating tax class. */ @@ -210,7 +210,7 @@ class TaxClasses extends AbstractController { * Delete a single tax class. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function delete_item( $request ) { global $wpdb; @@ -276,7 +276,7 @@ class TaxClasses extends AbstractController { /** * Fires after a tax class is deleted via the REST API. * - * @param stdClass $tax_class The tax data. + * @param \stdClass $tax_class The tax data. * @param \WP_REST_Response $response The response returned from the API. * @param \WP_REST_Request $request The request sent to the API. */ @@ -308,7 +308,7 @@ class TaxClasses extends AbstractController { * Filter tax object returned from the REST API. * * @param \WP_REST_Response $response The response object. - * @param stdClass $tax_class Tax object used to create response. + * @param \stdClass $tax_class Tax object used to create response. * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_tax', $response, (object) $tax_class, $request ); diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php index 64741ae8328..5f974dd5dbb 100644 --- a/src/Controllers/Version4/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -197,7 +197,7 @@ class Taxes extends AbstractController { * Get all taxes and allow filtering by tax code. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { global $wpdb; @@ -306,7 +306,7 @@ class Taxes extends AbstractController { * Take tax data from the request and return the updated or newly created rate. * * @param \WP_REST_Request $request Full details about the request. - * @param stdClass|null $current Existing tax object. + * @param \stdClass|null $current Existing tax object. * @return object */ protected function create_or_update_tax( $request, $current = null ) { @@ -376,7 +376,7 @@ class Taxes extends AbstractController { * Create a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -390,7 +390,7 @@ class Taxes extends AbstractController { /** * Fires after a tax is created or updated via the REST API. * - * @param stdClass $tax Data used to create the tax. + * @param \stdClass $tax Data used to create the tax. * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating tax, false when updating tax. */ @@ -409,7 +409,7 @@ class Taxes extends AbstractController { * Get a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; @@ -429,7 +429,7 @@ class Taxes extends AbstractController { * Update a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function update_item( $request ) { $id = (int) $request['id']; @@ -446,7 +446,7 @@ class Taxes extends AbstractController { /** * Fires after a tax is created or updated via the REST API. * - * @param stdClass $tax Data used to create the tax. + * @param \stdClass $tax Data used to create the tax. * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating tax, false when updating tax. */ @@ -463,7 +463,7 @@ class Taxes extends AbstractController { * Delete a single tax. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function delete_item( $request ) { global $wpdb; @@ -494,7 +494,7 @@ class Taxes extends AbstractController { /** * Fires after a tax is deleted via the REST API. * - * @param stdClass $tax The tax data. + * @param \stdClass $tax The tax data. * @param \WP_REST_Response $response The response returned from the API. * @param \WP_REST_Request $request The request sent to the API. */ @@ -506,7 +506,7 @@ class Taxes extends AbstractController { /** * Prepare a single tax output for response. * - * @param stdClass $tax Tax object. + * @param \stdClass $tax Tax object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ @@ -560,7 +560,7 @@ class Taxes extends AbstractController { * Filter tax object returned from the REST API. * * @param \WP_REST_Response $response The response object. - * @param stdClass $tax Tax object used to create response. + * @param \stdClass $tax Tax object used to create response. * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_tax', $response, $tax, $request ); @@ -569,7 +569,7 @@ class Taxes extends AbstractController { /** * Prepare links for the request. * - * @param stdClass $tax Tax object. + * @param \stdClass $tax Tax object. * @return array Links for the given tax. */ protected function prepare_links( $tax ) { diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index c652ad2a951..ececa580c0a 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -228,7 +228,7 @@ class Webhooks extends AbstractController { * Get all webhooks. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { $args = array(); @@ -298,7 +298,7 @@ class Webhooks extends AbstractController { * Get a single item. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { $id = (int) $request['id']; @@ -317,7 +317,7 @@ class Webhooks extends AbstractController { * Create a single webhook. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { @@ -377,7 +377,7 @@ class Webhooks extends AbstractController { * Update a single webhook. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error\WP_REST_Response + * @return \WP_Error|\WP_REST_Response */ public function update_item( $request ) { $id = (int) $request['id']; @@ -541,7 +541,7 @@ class Webhooks extends AbstractController { * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being * prepared for insertion. * - * @param stdClass $data An object representing a single item prepared + * @param \stdClass $data An object representing a single item prepared * for inserting or updating the database. * @param \WP_REST_Request $request Request object. */ @@ -584,7 +584,7 @@ class Webhooks extends AbstractController { // Wrap the data in a response object. $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $webhook->get_id(), $request ) ); + $response->add_links( $this->prepare_links( $webhook->get_id() ) ); /** * Filter webhook object returned from the REST API. From 7bb20c33e3a6561260b0be274c11d18f563bc425 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 14:03:36 +0100 Subject: [PATCH 121/440] cs --- .../Version4/AbstractController.php | 2 +- .../Version4/ProductVariations.php | 34 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index cedb052b590..fe827724f19 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -451,7 +451,7 @@ abstract class AbstractController extends WP_REST_Controller { if ( ! isset( $request['_fields'] ) ) { return $fields; } - $requested_fields = is_array( $request['_fields'] ) ? $request['_fields'] : preg_split( '/[\s,]+/', $request['_fields'] ); + $requested_fields = array_filter( is_array( $request['_fields'] ) ? $request['_fields'] : (array) preg_split( '/[\s,]+/', $request['_fields'] ) ); if ( 0 === count( $requested_fields ) ) { return $fields; } diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index 57b2de3b17b..56b9b7b0a71 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -117,7 +117,8 @@ class ProductVariations extends Products { true ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', + $this->namespace, + '/' . $this->rest_base . '/batch', array( 'args' => array( 'product_id' => array( @@ -142,7 +143,7 @@ class ProductVariations extends Products { * * @since 3.0.0 * @param int $id Object ID. - * @return WC_Data + * @return \WC_Data */ protected function get_object( $id ) { return wc_get_product( $id ); @@ -172,7 +173,7 @@ class ProductVariations extends Products { /** * Prepare a single variation output for response. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response */ @@ -240,7 +241,7 @@ class ProductVariations extends Products { * refers to object type being prepared for the response. * * @param \WP_REST_Response $response The response object. - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); @@ -249,7 +250,7 @@ class ProductVariations extends Products { /** * Get the image for a product variation. * - * @param WC_Product_Variation $variation Variation data. + * @param \WC_Product_Variation $variation Variation data. * @return array */ protected function get_image( $variation ) { @@ -289,7 +290,7 @@ class ProductVariations extends Products { * * @param \WC_Product_Variation $variation Variation instance. * @param array $image Image data. - * @return WC_Product_Variation + * @return \WC_Product_Variation */ protected function set_variation_image( $variation, $image ) { $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; @@ -421,8 +422,8 @@ class ProductVariations extends Products { * Prepare a single variation for create or update. * * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WP_Error|WC_Data + * @param bool $creating If is creating a new object. + * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { if ( isset( $request['id'] ) ) { @@ -619,7 +620,7 @@ class ProductVariations extends Products { * The dynamic portion of the hook name, `$this->post_type`, * refers to the object type slug. * - * @param WC_Data $variation Object object. + * @param \WC_Data $variation Object object. * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ @@ -629,7 +630,7 @@ class ProductVariations extends Products { /** * Clear caches here so in sync with any new variations. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. */ public function clear_transients( $object ) { wc_delete_product_transients( $object->get_parent_id() ); @@ -641,7 +642,7 @@ class ProductVariations extends Products { * * @param \WP_REST_Request $request Full details about the request. * - * @return bool|\WP_Error\WP_REST_Response + * @return bool|\WP_Error|\WP_REST_Response */ public function delete_item( $request ) { $force = (bool) $request['force']; @@ -663,8 +664,8 @@ class ProductVariations extends Products { * * Return false to disable trash support for the object. * - * @param boolean $supports_trash Whether the object type support trashing. - * @param WC_Data $object The object being considered for trashing support. + * @param boolean $supports_trash Whether the object type support trashing. + * @param \WC_Data $object The object being considered for trashing support. */ $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); @@ -734,7 +735,7 @@ class ProductVariations extends Products { /** * Fires after a single object is deleted or trashed via the REST API. * - * @param WC_Data $object The deleted or trashed object. + * @param \WC_Data $object The deleted or trashed object. * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ @@ -763,7 +764,8 @@ class ProductVariations extends Products { $injected_items[] = is_array( $item ) ? array_merge( array( 'product_id' => $product_id, - ), $item + ), + $item ) : $item; } $body_params[ $batch_type ] = $injected_items; @@ -779,7 +781,7 @@ class ProductVariations extends Products { /** * Prepare links for the request. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ From 525716e5cba5b2feac9b7c6ec02e74ca96be4c2d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 14:37:38 +0100 Subject: [PATCH 122/440] Lookup table usage --- .../Version4/ProductVariations.php | 59 ++----- src/Controllers/Version4/Products.php | 156 +++++++----------- 2 files changed, 71 insertions(+), 144 deletions(-) diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index 56b9b7b0a71..ffba6580906 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -345,22 +345,18 @@ class ProductVariations extends Products { // Set post_status. $args['post_status'] = $request['status']; - // Filter by sku. - if ( ! empty( $request['sku'] ) ) { - $skus = explode( ',', $request['sku'] ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $request['sku']; + // Set custom args to handle later during clauses. + $custom_keys = array( + 'sku', + 'min_price', + 'max_price', + 'stock_status', + 'low_in_stock', + ); + foreach ( $custom_keys as $key ) { + if ( ! empty( $request[ $key ] ) ) { + $args[ $key ] = $request[ $key ]; } - - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', - ) - ); } // Filter by tax class. @@ -374,22 +370,6 @@ class ProductVariations extends Products { ); } - // Price filter. - if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { - $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. - } - - // Filter product based on stock_status. - if ( ! empty( $request['stock_status'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_stock_status', - 'value' => $request['stock_status'], - ) - ); - } - // Filter by on sale products. if ( is_bool( $request['on_sale'] ) ) { $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; @@ -1210,21 +1190,4 @@ class ProductVariations extends Products { return $params; } - - /** - * Get a collection of posts and add the post title filter option to \WP_Query. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); - add_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10, 2 ); - add_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10, 2 ); - $response = parent::get_items( $request ); - remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10 ); - remove_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10 ); - remove_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10 ); - return $response; - } } diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index aa77240f159..9b011dcb6cf 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -600,92 +600,76 @@ class Products extends AbstractObjectsController { * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { - add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10, 2 ); - add_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10, 2 ); - add_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10, 2 ); + add_filter( 'posts_clauses', array( $this, 'get_items_query_clauses' ), 10, 2 ); $response = parent::get_items( $request ); - remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_filter' ), 10 ); - remove_filter( 'posts_join', array( __CLASS__, 'add_wp_query_join' ), 10 ); - remove_filter( 'posts_groupby', array( __CLASS__, 'add_wp_query_group_by' ), 10 ); + remove_filter( 'posts_clauses', array( $this, 'get_items_query_clauses' ), 10 ); return $response; } /** * Add in conditional search filters for products. * - * @param string $where Where clause used to search posts. - * @param object $wp_query \WP_Query object. - * @return string + * @param array $args Query args. + * @param \WC_Query $wp_query WC_Query object. + * @return array */ - public static function add_wp_query_filter( $where, $wp_query ) { + public function get_items_query_clauses( $args, $wp_query ) { global $wpdb; - $search = $wp_query->get( 'search' ); - if ( $search ) { - $search = $wpdb->esc_like( $search ); - $search = "'%" . $search . "%'"; - $where .= " AND ({$wpdb->posts}.post_title LIKE {$search}"; - $where .= wc_product_sku_enabled() ? ' OR ps_post_meta.meta_key = "_sku" AND ps_post_meta.meta_value LIKE ' . $search . ')' : ')'; + if ( $wp_query->get( 'search' ) ) { + $search = "'%" . $wpdb->esc_like( $wp_query->get( 'search' ) ) . "%'"; + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= " AND ({$wpdb->posts}.post_title LIKE {$search}"; + $args['where'] .= wc_product_sku_enabled() ? ' OR wc_product_meta_lookup.sku LIKE ' . $search . ')' : ')'; + } + + if ( $wp_query->get( 'sku' ) ) { + $skus = explode( ',', $wp_query->get( 'sku' ) ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $wp_query->get( 'sku' ); + } + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= ' AND wc_product_meta_lookup.sku IN ("' . implode( '","', array_map( 'esc_sql', $skus ) ) . '")'; + } + + if ( $wp_query->get( 'min_price' ) ) { + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.min_price >= %f ', floatval( $wp_query->get( 'min_price' ) ) ); + } + + if ( $wp_query->get( 'max_price' ) ) { + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.max_price <= %f ', floatval( $wp_query->get( 'max_price' ) ) ); + } + + if ( $wp_query->get( 'stock_status' ) ) { + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.stock_status = %s ', $wp_query->get( 'stock_status' ) ); } if ( $wp_query->get( 'low_in_stock' ) ) { - $low_stock_amount = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) ); - $where .= " AND lis_postmeta2.meta_key = '_manage_stock' - AND lis_postmeta2.meta_value = 'yes' - AND lis_postmeta.meta_key = '_stock' - AND lis_postmeta.meta_value IS NOT NULL - AND lis_postmeta3.meta_key = '_low_stock_amount' - AND ( - lis_postmeta3.meta_value > '' - AND CAST(lis_postmeta.meta_value AS SIGNED) <= CAST(lis_postmeta3.meta_value AS SIGNED) - OR lis_postmeta3.meta_value <= '' - AND CAST(lis_postmeta.meta_value AS SIGNED) <= {$low_stock_amount} - )"; + $low_stock = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) ); + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.stock_quantity <= %d', $low_stock ); } - return $where; + return $args; } /** - * Join posts meta tables when product search or low stock query is present. + * Join wc_product_meta_lookup to posts if not already joined. * - * @param string $join Join clause used to search posts. - * @param object $wp_query \WP_Query object. + * @param string $sql SQL join. * @return string */ - public static function add_wp_query_join( $join, $wp_query ) { + protected function append_product_sorting_table_join( $sql ) { global $wpdb; - $search = $wp_query->get( 'search' ); - if ( $search && wc_product_sku_enabled() ) { - $join .= " INNER JOIN {$wpdb->postmeta} AS ps_post_meta ON ps_post_meta.post_id = {$wpdb->posts}.ID"; + if ( ! strstr( $sql, 'wc_product_meta_lookup' ) ) { + $sql .= " LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON $wpdb->posts.ID = wc_product_meta_lookup.product_id "; } - - if ( $wp_query->get( 'low_in_stock' ) ) { - $join .= " INNER JOIN {$wpdb->postmeta} AS lis_postmeta ON {$wpdb->posts}.ID = lis_postmeta.post_id - INNER JOIN {$wpdb->postmeta} AS lis_postmeta2 ON {$wpdb->posts}.ID = lis_postmeta2.post_id - INNER JOIN {$wpdb->postmeta} AS lis_postmeta3 ON {$wpdb->posts}.ID = lis_postmeta3.post_id"; - } - - return $join; - } - - /** - * Group by post ID to prevent duplicates. - * - * @param string $groupby Group by clause used to organize posts. - * @param object $wp_query \WP_Query object. - * @return string - */ - public static function add_wp_query_group_by( $groupby, $wp_query ) { - global $wpdb; - - $search = $wp_query->get( 'search' ); - $low_in_stock = $wp_query->get( 'low_in_stock' ); - if ( empty( $groupby ) && ( $search || $low_in_stock ) ) { - $groupby = $wpdb->posts . '.ID'; - } - return $groupby; + return $sql; } /** @@ -701,6 +685,20 @@ class Products extends AbstractObjectsController { // Set post_status. $args['post_status'] = $request['status']; + // Set custom args to handle later during clauses. + $custom_keys = array( + 'sku', + 'min_price', + 'max_price', + 'stock_status', + 'low_in_stock', + ); + foreach ( $custom_keys as $key ) { + if ( ! empty( $request[ $key ] ) ) { + $args[ $key ] = $request[ $key ]; + } + } + // Taxonomy query to filter products by type, category, // tag, shipping class, and attribute. $tax_query = array(); @@ -762,24 +760,6 @@ class Products extends AbstractObjectsController { ); } - // Filter by sku. - if ( ! empty( $request['sku'] ) ) { - $skus = explode( ',', $request['sku'] ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $request['sku']; - } - - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', - ) - ); - } - // Filter by tax class. if ( ! empty( $request['tax_class'] ) ) { $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. @@ -791,22 +771,6 @@ class Products extends AbstractObjectsController { ); } - // Price filter. - if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { - $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. - } - - // Filter product by stock_status. - if ( ! empty( $request['stock_status'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_stock_status', - 'value' => $request['stock_status'], - ) - ); - } - // Filter by on sale products. if ( is_bool( $request['on_sale'] ) ) { $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; From e0d40324522bc203175d02287b25531c64d1c2b4 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 14:40:04 +0100 Subject: [PATCH 123/440] CS --- src/Controllers/Version4/AbstractObjectsController.php | 4 ++-- src/Controllers/Version4/Coupons.php | 6 +++--- src/Controllers/Version4/Customers.php | 2 +- src/Controllers/Version4/Orders.php | 2 +- src/Controllers/Version4/Products.php | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 0e85ba5af4a..160413d559f 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -191,7 +191,7 @@ abstract class AbstractObjectsController extends AbstractController { * @since 3.0.0 * @param \WP_REST_Request $request Full details about the request. * @param bool $creating If is creating a new object. - * @return WC_Data|\WP_Error + * @return \WC_Data|\WP_Error */ protected function save_object( $request, $creating = false ) { try { @@ -531,7 +531,7 @@ abstract class AbstractObjectsController extends AbstractController { * Return false to disable trash support for the object. * * @param boolean $supports_trash Whether the object type support trashing. - * @param WC_Data $object The object being considered for trashing support. + * @param \WC_Data $object The object being considered for trashing support. */ return apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); } diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index 6ba8c0c7118..1aa84341749 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -126,7 +126,7 @@ class Coupons extends AbstractObjectsController { * * @since 3.0.0 * @param int $id Object ID. - * @return WC_Data + * @return \WC_Data */ protected function get_object( $id ) { return new \WC_Coupon( $id ); @@ -217,7 +217,7 @@ class Coupons extends AbstractObjectsController { * refers to object type being prepared for the response. * * @param \WP_REST_Response $response The response object. - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); @@ -306,7 +306,7 @@ class Coupons extends AbstractObjectsController { * The dynamic portion of the hook name, `$this->post_type`, * refers to the object type slug. * - * @param WC_Data $coupon Object object. + * @param \WC_Data $coupon Object object. * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index f5fbe968727..4e0234b5138 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -228,7 +228,7 @@ class Customers extends AbstractController { /** * Get formatted item data. * - * @param WC_Data $object WC_Data instance. + * @param \WC_Data $object WC_Data instance. * * @since 3.0.0 * @return array diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index a082444c830..57e76a2916e 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -321,7 +321,7 @@ class Orders extends AbstractObjectsController { /** * Prepare links for the request. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 9b011dcb6cf..a81187c2d45 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -586,7 +586,7 @@ class Products extends AbstractObjectsController { * The dynamic portion of the hook name, `$this->post_type`, * refers to the object type slug. * - * @param WC_Data $product Object object. + * @param \WC_Data $product Object object. * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. */ @@ -1391,7 +1391,7 @@ class Products extends AbstractObjectsController { /** * Clear caches here so in sync with any new variations/children. * - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. */ public function clear_transients( $object ) { wc_delete_product_transients( $object->get_id() ); @@ -1439,7 +1439,7 @@ class Products extends AbstractObjectsController { * Return false to disable trash support for the object. * * @param boolean $supports_trash Whether the object type support trashing. - * @param WC_Data $object The object being considered for trashing support. + * @param \WC_Data $object The object being considered for trashing support. */ $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); @@ -1517,7 +1517,7 @@ class Products extends AbstractObjectsController { /** * Fires after a single object is deleted or trashed via the REST API. * - * @param WC_Data $object The deleted or trashed object. + * @param \WC_Data $object The deleted or trashed object. * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ From 4b719c2ea7d8d0396741ac12599038795dc7b681 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 14:42:22 +0100 Subject: [PATCH 124/440] CS --- .../Version4/AbstractTermsContoller.php | 8 ++-- src/Controllers/Version4/Products.php | 48 +++++++++---------- src/Controllers/Version4/Settings.php | 2 +- src/Controllers/Version4/ShippingMethods.php | 6 +-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index fa2596d46b1..43d4966853f 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -251,7 +251,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Check permissions. * * @param \WP_REST_Request $request Full details about the request. - * @param string $context Request context. + * @param string $context Request context. * @return bool|\WP_Error */ protected function check_permissions( $request, $context = 'read' ) { @@ -587,7 +587,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Prepare links for the request. * - * @param object $term Term object. + * @param object $term Term object. * @param \WP_REST_Request $request Full details about the request. * @return array Links for the given term. */ @@ -622,7 +622,7 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Update term meta fields. * - * @param WP_Term $term Term object. + * @param \WP_Term $term Term object. * @param \WP_REST_Request $request Full details about the request. * @return bool|\WP_Error */ @@ -638,7 +638,7 @@ abstract class AbstractTermsContoller extends AbstractController { * supported, notably `include`, `exclude`. In `self::get_items()` these * are instead treated as a full query. * - * @param array $prepared_args Arguments for `get_terms()`. + * @param array $prepared_args Arguments for `get_terms()`. * @param \WP_REST_Request $request Full details about the request. * @return array List of term objects. (Total count in `$this->total_terms`). */ diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index a81187c2d45..6d694c34367 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -805,7 +805,7 @@ class Products extends AbstractObjectsController { /** * Get the downloads for a product or product variation. * - * @param WC_Product|WC_Product_Variation $product Product instance. + * @param \WC_Product|WC_Product_Variation $product Product instance. * * @return array */ @@ -828,8 +828,8 @@ class Products extends AbstractObjectsController { /** * Get taxonomy terms. * - * @param WC_Product $product Product instance. - * @param string $taxonomy Taxonomy slug. + * @param \WC_Product $product Product instance. + * @param string $taxonomy Taxonomy slug. * * @return array */ @@ -850,7 +850,7 @@ class Products extends AbstractObjectsController { /** * Get the images for a product or product variation. * - * @param WC_Product|WC_Product_Variation $product Product instance. + * @param \WC_Product|WC_Product_Variation $product Product instance. * @return array */ protected function get_images( $product ) { @@ -910,8 +910,8 @@ class Products extends AbstractObjectsController { /** * Get product attribute taxonomy name. * - * @param string $slug Taxonomy name. - * @param WC_Product $product Product data. + * @param string $slug Taxonomy name. + * @param \WC_Product $product Product data. * * @since 3.0.0 * @return string @@ -946,7 +946,7 @@ class Products extends AbstractObjectsController { /** * Get default attributes. * - * @param WC_Product $product Product instance. + * @param \WC_Product $product Product instance. * * @return array */ @@ -1001,7 +1001,7 @@ class Products extends AbstractObjectsController { /** * Get the attributes for a product or product variation. * - * @param WC_Product|WC_Product_Variation $product Product instance. + * @param \WC_Product|WC_Product_Variation $product Product instance. * * @return array */ @@ -1052,8 +1052,8 @@ class Products extends AbstractObjectsController { /** * Get product data. * - * @param WC_Product $product Product instance. - * @param string $context Request context. + * @param \WC_Product $product Product instance. + * @param string $context Request context. * Options: 'view' and 'edit'. * * @return array @@ -1166,9 +1166,9 @@ class Products extends AbstractObjectsController { * * @throws \WC_REST_Exception REST API exceptions. * - * @param WC_Product $product Product instance. - * @param array $images Images data. - * @return WC_Product + * @param \WC_Product $product Product instance. + * @param array $images Images data. + * @return \WC_Product */ protected function set_product_images( $product, $images ) { $images = is_array( $images ) ? array_filter( $images ) : array(); @@ -1234,10 +1234,10 @@ class Products extends AbstractObjectsController { /** * Save product shipping data. * - * @param WC_Product $product Product instance. - * @param array $data Shipping data. + * @param \WC_Product $product Product instance. + * @param array $data Shipping data. * - * @return WC_Product + * @return \WC_Product */ protected function save_product_shipping_data( $product, $data ) { // Virtual. @@ -1280,11 +1280,11 @@ class Products extends AbstractObjectsController { /** * Save downloadable files. * - * @param WC_Product $product Product instance. - * @param array $downloads Downloads data. - * @param int $deprecated Deprecated since 3.0. + * @param \WC_Product $product Product instance. + * @param array $downloads Downloads data. + * @param int $deprecated Deprecated since 3.0. * - * @return WC_Product + * @return \WC_Product */ protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { if ( $deprecated ) { @@ -1311,11 +1311,11 @@ class Products extends AbstractObjectsController { /** * Save taxonomy terms. * - * @param WC_Product $product Product instance. - * @param array $terms Terms data. - * @param string $taxonomy Taxonomy name. + * @param \WC_Product $product Product instance. + * @param array $terms Terms data. + * @param string $taxonomy Taxonomy name. * - * @return WC_Product + * @return \WC_Product */ protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { $term_ids = wp_list_pluck( $terms, 'id' ); diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index 9c57617c938..0d29ed833ff 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -143,7 +143,7 @@ class Settings extends AbstractController { * Prepare a report sales object for serialization. * * @since 3.0.0 - * @param array $item Group object. + * @param array $item Group object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php index 6ab092118f5..63ff6c542b4 100644 --- a/src/Controllers/Version4/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -130,7 +130,7 @@ class ShippingMethods extends AbstractController { /** * Prepare a shipping method for response. * - * @param WC_Shipping_Method $method Shipping method object. + * @param \WC_Shipping_Method $method Shipping method object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ @@ -154,7 +154,7 @@ class ShippingMethods extends AbstractController { * Filter shipping methods object returned from the REST API. * * @param \WP_REST_Response $response The response object. - * @param WC_Shipping_Method $method Shipping method object used to create response. + * @param \WC_Shipping_Method $method Shipping method object used to create response. * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_shipping_method', $response, $method, $request ); @@ -163,7 +163,7 @@ class ShippingMethods extends AbstractController { /** * Prepare links for the request. * - * @param WC_Shipping_Method $method Shipping method object. + * @param \WC_Shipping_Method $method Shipping method object. * @param \WP_REST_Request $request Request object. * @return array */ From 0b770df6a4d45e1ee162fae0d234f7153c4f4882 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 14:59:37 +0100 Subject: [PATCH 125/440] Break up get_environment_info --- src/Controllers/Version4/SystemStatus.php | 182 +++++++++++++++------- 1 file changed, 128 insertions(+), 54 deletions(-) diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index 547c801aa50..60ac351b5c2 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -594,24 +594,53 @@ class SystemStatus extends AbstractController { * @return array */ public function get_environment_info() { - global $wpdb; + $post_request = $this->test_post_request(); + $get_request = $this->test_get_request(); + $database_version = wc_get_server_database_version(); - // Figure out cURL version, if installed. - $curl_version = ''; - if ( function_exists( 'curl_version' ) ) { - $curl_version = curl_version(); - $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; - } elseif ( extension_loaded( 'curl' ) ) { - $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); - } + // Return all environment info. Described by JSON Schema. + return array( + 'home_url' => get_option( 'home' ), + 'site_url' => get_option( 'siteurl' ), + 'version' => WC()->version, + 'log_directory' => WC_LOG_DIR, + 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore + 'wp_version' => get_bloginfo( 'version' ), + 'wp_multisite' => is_multisite(), + 'wp_memory_limit' => $this->get_wp_memory_limit(), + 'wp_debug_mode' => $this->is_constant_true( 'WP_DEBUG' ), + 'wp_cron' => ! $this->is_constant_true( 'DISABLE_WP_CRON' ), + 'language' => get_locale(), + 'external_object_cache' => wp_using_ext_object_cache(), + 'server_info' => $this->get_server_software(), + 'php_version' => phpversion(), + 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), + 'php_max_execution_time' => ini_get( 'max_execution_time' ), + 'php_max_input_vars' => ini_get( 'max_input_vars' ), + 'curl_version' => $this->get_curl_version(), + 'suhosin_installed' => extension_loaded( 'suhosin' ), + 'max_upload_size' => wp_max_upload_size(), + 'mysql_version' => $database_version['number'], + 'mysql_version_string' => $database_version['string'], + 'default_timezone' => date_default_timezone_get(), + 'fsockopen_or_curl_enabled' => $this->fsockopen_or_curl_enabled(), + 'soapclient_enabled' => class_exists( 'SoapClient' ), + 'domdocument_enabled' => class_exists( 'DOMDocument' ), + 'gzip_enabled' => is_callable( 'gzopen' ), + 'mbstring_enabled' => extension_loaded( 'mbstring' ), + 'remote_post_successful' => $post_request['success'], + 'remote_post_response' => $post_request['response'], + 'remote_get_successful' => $get_request['success'], + 'remote_get_response' => $get_request['response'], + ); + } - // WP memory limit. - $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); - if ( function_exists( 'memory_get_usage' ) ) { - $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); - } - - // Test POST requests. + /** + * Test POST to an external server. + * + * @return array + */ + protected function test_post_request() { $post_response_code = get_transient( 'woocommerce_test_remote_post' ); if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { @@ -632,9 +661,25 @@ class SystemStatus extends AbstractController { set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); } - $post_response_successful = ! is_wp_error( $post_response_code ) && $post_response_code >= 200 && $post_response_code < 300; + if ( is_wp_error( $post_response_code ) ) { + return array( + 'success' => false, + 'response' => $post_response_code->get_error_message(), + ); + } - // Test GET requests. + return array( + 'success' => $post_response_code >= 200 && $post_response_code < 300, + 'response' => $post_response_code, + ); + } + + /** + * Test GET to an external server. + * + * @return array + */ + protected function test_get_request() { $get_response_code = get_transient( 'woocommerce_test_remote_get' ); if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { @@ -645,47 +690,76 @@ class SystemStatus extends AbstractController { set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); } - $get_response_successful = ! is_wp_error( $get_response_code ) && $get_response_code >= 200 && $get_response_code < 300; + if ( is_wp_error( $get_response_code ) ) { + return array( + 'success' => false, + 'response' => $get_response_code->get_error_message(), + ); + } - $database_version = wc_get_server_database_version(); - - // Return all environment info. Described by JSON Schema. return array( - 'home_url' => get_option( 'home' ), - 'site_url' => get_option( 'siteurl' ), - 'version' => WC()->version, - 'log_directory' => WC_LOG_DIR, - 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), - 'wp_version' => get_bloginfo( 'version' ), - 'wp_multisite' => is_multisite(), - 'wp_memory_limit' => $wp_memory_limit, - 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), - 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ), - 'language' => get_locale(), - 'external_object_cache' => wp_using_ext_object_cache(), - 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '', - 'php_version' => phpversion(), - 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), - 'php_max_execution_time' => ini_get( 'max_execution_time' ), - 'php_max_input_vars' => ini_get( 'max_input_vars' ), - 'curl_version' => $curl_version, - 'suhosin_installed' => extension_loaded( 'suhosin' ), - 'max_upload_size' => wp_max_upload_size(), - 'mysql_version' => $database_version['number'], - 'mysql_version_string' => $database_version['string'], - 'default_timezone' => date_default_timezone_get(), - 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ), - 'soapclient_enabled' => class_exists( 'SoapClient' ), - 'domdocument_enabled' => class_exists( 'DOMDocument' ), - 'gzip_enabled' => is_callable( 'gzopen' ), - 'mbstring_enabled' => extension_loaded( 'mbstring' ), - 'remote_post_successful' => $post_response_successful, - 'remote_post_response' => is_wp_error( $post_response_code ) ? $post_response_code->get_error_message() : $post_response_code, - 'remote_get_successful' => $get_response_successful, - 'remote_get_response' => is_wp_error( $get_response_code ) ? $get_response_code->get_error_message() : $get_response_code, + 'success' => $get_response_code >= 200 && $get_response_code < 300, + 'response' => $get_response_code, ); } + /** + * Return if a constant is defined and true. + * + * @param string $name Constant name. + * @return bool + */ + protected function is_constant_true( $name ) { + return defined( $name ) && (bool) constant( $name ); + } + + /** + * Return info about server software running. + * + * @return string + */ + protected function get_server_software() { + return isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : ''; + } + + /** + * Get CURL version running on server. + * + * @return string + */ + protected function get_curl_version() { + $curl_version = ''; + if ( function_exists( 'curl_version' ) ) { + $curl_version = curl_version(); + $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; + } elseif ( extension_loaded( 'curl' ) ) { + $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); + } + return $curl_version; + } + + /** + * Get WP memory limit. + * + * @return string + */ + protected function get_wp_memory_limit() { + $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); + if ( function_exists( 'memory_get_usage' ) ) { + $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); + } + return (string) $wp_memory_limit; + } + + /** + * See if modules are enabled. + * + * @return bool + */ + protected function fsockopen_or_curl_enabled() { + return function_exists( 'fsockopen' ) || function_exists( 'curl_init' ); + } + /** * Add prefix to table. * From 865bb6b6152600101dbb85f7d91d2d4732ad0d84 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 15:14:05 +0100 Subject: [PATCH 126/440] Fix WP_User ID --- src/Controllers/Version4/CustomerDownloads.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index 7e191b957b6..e03f6ec175d 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -62,7 +62,7 @@ class CustomerDownloads extends AbstractController { return new \WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } - if ( ! wc_rest_check_user_permissions( 'read', $customer->get_id() ) ) { + if ( ! wc_rest_check_user_permissions( 'read', $customer->ID ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } From 6e82a35766b4033c1a251b7f5699703c0425e181 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 15:17:00 +0100 Subject: [PATCH 127/440] CS --- src/Controllers/Version4/Coupons.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index 1aa84341749..5cb72e0bf26 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -136,7 +136,7 @@ class Coupons extends AbstractObjectsController { * Get formatted item data. * * @since 3.0.0 - * @param WC_Data $object WC_Data instance. + * @param \WC_Data $object WC_Data instance. * @return array */ protected function get_formatted_item_data( $object ) { @@ -198,7 +198,7 @@ class Coupons extends AbstractObjectsController { * Prepare a single coupon output for response. * * @since 3.0.0 - * @param WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response */ @@ -251,7 +251,7 @@ class Coupons extends AbstractObjectsController { * * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return \WP_Error|WC_Data + * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; From cd847fb4ea1c8121991603bc2f232591b5f24ee0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 15:19:15 +0100 Subject: [PATCH 128/440] CS --- src/Controllers/Version4/Products.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 6d694c34367..c137842b1f9 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -422,13 +422,13 @@ class Products extends AbstractObjectsController { } if ( $product->is_type( 'grouped' ) ) { - $product->set_manage_stock( 'no' ); - $product->set_backorders( 'no' ); + $product->set_manage_stock( false ); + $product->set_backorders( false ); $product->set_stock_quantity( '' ); $product->set_stock_status( $stock_status ); } elseif ( $product->is_type( 'external' ) ) { - $product->set_manage_stock( 'no' ); - $product->set_backorders( 'no' ); + $product->set_manage_stock( false ); + $product->set_backorders( false ); $product->set_stock_quantity( '' ); $product->set_stock_status( 'instock' ); } elseif ( $product->get_manage_stock() ) { @@ -447,7 +447,7 @@ class Products extends AbstractObjectsController { } } else { // Don't manage stock. - $product->set_manage_stock( 'no' ); + $product->set_manage_stock( false ); $product->set_stock_quantity( '' ); $product->set_stock_status( $stock_status ); } From f92730544305364054f885736545ea3099683b1d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 15:33:56 +0100 Subject: [PATCH 129/440] set_backorders --- src/Controllers/Version4/Products.php | 4 ++-- unit-tests/Tests/Version4/Products.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index c137842b1f9..536d9d5a5d2 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -423,12 +423,12 @@ class Products extends AbstractObjectsController { if ( $product->is_type( 'grouped' ) ) { $product->set_manage_stock( false ); - $product->set_backorders( false ); + $product->set_backorders( 'no' ); $product->set_stock_quantity( '' ); $product->set_stock_status( $stock_status ); } elseif ( $product->is_type( 'external' ) ) { $product->set_manage_stock( false ); - $product->set_backorders( false ); + $product->set_backorders( 'no' ); $product->set_stock_quantity( '' ); $product->set_stock_status( 'instock' ); } elseif ( $product->get_manage_stock() ) { diff --git a/unit-tests/Tests/Version4/Products.php b/unit-tests/Tests/Version4/Products.php index 94585a06e97..744674c8a8c 100644 --- a/unit-tests/Tests/Version4/Products.php +++ b/unit-tests/Tests/Version4/Products.php @@ -281,7 +281,7 @@ class Products extends WC_REST_Unit_Test_Case { ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); - +var_dump($data); $this->assertEquals( 'Test API Update', $data['button_text'] ); $this->assertEquals( 'http://automattic.com', $data['external_url'] ); } From 7aa7ca1baf7f941089488e0d9316c8fc039bdd34 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 16:11:59 +0100 Subject: [PATCH 130/440] CS --- src/Controllers/Version4/AbstractTermsContoller.php | 2 +- unit-tests/Tests/Version4/Products.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index 43d4966853f..fea0f2ce815 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -802,7 +802,7 @@ abstract class AbstractTermsContoller extends AbstractController { * Get taxonomy. * * @param \WP_REST_Request $request Full details about the request. - * @return int|\WP_Error + * @return string */ protected function get_taxonomy( $request ) { // Check if taxonomy is defined. diff --git a/unit-tests/Tests/Version4/Products.php b/unit-tests/Tests/Version4/Products.php index 744674c8a8c..94585a06e97 100644 --- a/unit-tests/Tests/Version4/Products.php +++ b/unit-tests/Tests/Version4/Products.php @@ -281,7 +281,7 @@ class Products extends WC_REST_Unit_Test_Case { ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); -var_dump($data); + $this->assertEquals( 'Test API Update', $data['button_text'] ); $this->assertEquals( 'http://automattic.com', $data['external_url'] ); } From d54bb381c06a6d9c29ed4078cd13391dbe967f39 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 16:17:58 +0100 Subject: [PATCH 131/440] meta_id default to 0 --- src/Controllers/Version4/Coupons.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index 5cb72e0bf26..a32d11bf31b 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -284,7 +284,7 @@ class Coupons extends AbstractObjectsController { case 'meta_data': if ( is_array( $value ) ) { foreach ( $value as $meta ) { - $coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + $coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : 0 ); } } break; From 989a9978e2970b432ca144cc97ac3e1829fc8bb8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 16:28:07 +0100 Subject: [PATCH 132/440] Docblock CS --- .../Version4/AbstractObjectsController.php | 2 +- src/Controllers/Version4/OrderNotes.php | 25 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 160413d559f..5a78e5711fa 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -389,7 +389,7 @@ abstract class AbstractObjectsController extends AbstractController { * Get a collection of posts. * * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response + * @return \WP_REST_Response */ public function get_items( $request ) { $query_args = $this->prepare_objects_query( $request ); diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index 9b9d17d21c9..7e3f680266d 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -54,13 +54,16 @@ class OrderNotes extends AbstractController { 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( - 'note' => array( - 'type' => 'string', - 'description' => __( 'Order note content.', 'woocommerce' ), - 'required' => true, - ), - ) ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), + array( + 'note' => array( + 'type' => 'string', + 'description' => __( 'Order note content.', 'woocommerce' ), + 'required' => true, + ), + ) + ), ), 'schema' => array( $this, 'get_public_item_schema' ), ), @@ -254,7 +257,7 @@ class OrderNotes extends AbstractController { /** * Fires after a order note is created or updated via the REST API. * - * @param WP_Comment $note New order note object. + * @param \WP_Comment $note New order note object. * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ @@ -341,7 +344,7 @@ class OrderNotes extends AbstractController { /** * Fires after a order note is deleted or trashed via the REST API. * - * @param WP_Comment $note The deleted or trashed order note. + * @param \WP_Comment $note The deleted or trashed order note. * @param \WP_REST_Response $response The response data. * @param \WP_REST_Request $request The request sent to the API. */ @@ -353,7 +356,7 @@ class OrderNotes extends AbstractController { /** * Prepare a single order note output for response. * - * @param WP_Comment $note Order note object. + * @param \WP_Comment $note Order note object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ @@ -380,7 +383,7 @@ class OrderNotes extends AbstractController { * Filter order note object returned from the REST API. * * @param \WP_REST_Response $response The response object. - * @param WP_Comment $note Order note object used to create response. + * @param \WP_Comment $note Order note object used to create response. * @param \WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); From 29b45d8f885919c299b7125966867c58d8fc7e1b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 16:49:34 +0100 Subject: [PATCH 133/440] Make get_object abstract --- src/Controllers/Version4/AbstractObjectsController.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 5a78e5711fa..98367c83775 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -32,12 +32,9 @@ abstract class AbstractObjectsController extends AbstractController { * Get object. * * @param int $id Object ID. - * @return \WP_Error|\WC_Data + * @return \WC_Data */ - protected function get_object( $id ) { - // translators: %s: Class method name. - return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); - } + abstract protected function get_object( $id ); /** * Check if a given request has access to read items. From 85f980d8658b47a9327a1c4aaa1e530514693023 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 16:53:28 +0100 Subject: [PATCH 134/440] CS --- src/Controllers/Version4/AbstractObjectsController.php | 2 +- src/Controllers/Version4/Orders.php | 2 +- src/Controllers/Version4/Products.php | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 98367c83775..c933c92a56a 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -156,7 +156,7 @@ abstract class AbstractObjectsController extends AbstractController { * @since 3.0.0 * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return \WP_Error|WC_Data The prepared item, or \WP_Error object on failure. + * @return \WP_Error|\WC_Data The prepared item, or \WP_Error object on failure. */ protected function prepare_object_for_database( $request, $creating = false ) { // translators: %s: Class method name. diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index 57e76a2916e..b145056f801 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -463,7 +463,7 @@ class Orders extends AbstractObjectsController { * @throws \WC_REST_Exception When fails to set any item. * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return \WP_Error|WC_Data + * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 536d9d5a5d2..75feda08b86 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -805,7 +805,7 @@ class Products extends AbstractObjectsController { /** * Get the downloads for a product or product variation. * - * @param \WC_Product|WC_Product_Variation $product Product instance. + * @param \WC_Product|\WC_Product_Variation $product Product instance. * * @return array */ @@ -850,7 +850,7 @@ class Products extends AbstractObjectsController { /** * Get the images for a product or product variation. * - * @param \WC_Product|WC_Product_Variation $product Product instance. + * @param \WC_Product|\WC_Product_Variation $product Product instance. * @return array */ protected function get_images( $product ) { @@ -1001,7 +1001,7 @@ class Products extends AbstractObjectsController { /** * Get the attributes for a product or product variation. * - * @param \WC_Product|WC_Product_Variation $product Product instance. + * @param \WC_Product|\WC_Product_Variation $product Product instance. * * @return array */ From 1a98d24b38de9dfd5427eea6f36c22584699ba04 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 16:54:53 +0100 Subject: [PATCH 135/440] More abstract methods --- .../Version4/AbstractObjectsController.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index c933c92a56a..642b2235dc7 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -143,12 +143,9 @@ abstract class AbstractObjectsController extends AbstractController { * @since 3.0.0 * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. - * @return \WP_Error|\WP_REST_Response Response object on success, or \WP_Error object on failure. + * @return \WP_REST_Response Response object on success, or \WP_Error object on failure. */ - protected function prepare_object_for_response( $object, $request ) { - // translators: %s: Class method name. - return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); - } + abstract protected function prepare_object_for_response( $object, $request ); /** * Prepares one object for create or update operation. @@ -156,12 +153,9 @@ abstract class AbstractObjectsController extends AbstractController { * @since 3.0.0 * @param \WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. - * @return \WP_Error|\WC_Data The prepared item, or \WP_Error object on failure. + * @return \WC_Data The prepared item, or \WP_Error object on failure. */ - protected function prepare_object_for_database( $request, $creating = false ) { - // translators: %s: Class method name. - return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); - } + abstract protected function prepare_object_for_database( $request, $creating = false ); /** * Get a single item. From 893fa62594cb74208f2da21a29b5293a13a1453c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 17:19:58 +0100 Subject: [PATCH 136/440] Break up execute_tool method --- .../Version4/SystemStatusTools.php | 341 +++++++++++------- 1 file changed, 205 insertions(+), 136 deletions(-) diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php index 956f5b0d763..17b073b4b13 100644 --- a/src/Controllers/Version4/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -136,7 +136,7 @@ class SystemStatusTools extends AbstractController { 'button' => __( 'Clean up download permissions', 'woocommerce' ), 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ), ), - 'regenerate_product_lookup_tables' => array( + 'regenerate_product_lookup_tables' => array( 'name' => __( 'Product lookup tables', 'woocommerce' ), 'button' => __( 'Regenerate', 'woocommerce' ), 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce' ), @@ -292,7 +292,7 @@ class SystemStatusTools extends AbstractController { /** * Prepare a tool item for serialization. * - * @param array $item Object. + * @param array $item Object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ @@ -402,150 +402,37 @@ class SystemStatusTools extends AbstractController { /** * Actually executes a tool. * + * @throws Exception When the tool cannot run. * @param string $tool Tool. * @return array */ public function execute_tool( $tool ) { - global $wpdb; - $ran = true; - switch ( $tool ) { - case 'clear_transients': - wc_delete_product_transients(); - wc_delete_shop_order_transients(); - delete_transient( 'wc_count_comments' ); + $ran = false; + $tools = $this->get_tools(); - $attribute_taxonomies = wc_get_attribute_taxonomies(); + try { + if ( ! isset( $tools[ $tool ] ) ) { + throw new Exception( __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ) ); + } - if ( ! empty( $attribute_taxonomies ) ) { - foreach ( $attribute_taxonomies as $attribute ) { - delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name ); - } - } + $callback = isset( $tools[ $tool ]['callback'] ) ? $tools[ $tool ]['callback'] : array( $this, $tool ); - \WC_Cache_Helper::get_transient_version( 'shipping', true ); - $message = __( 'Product transients cleared', 'woocommerce' ); - break; + if ( ! is_callable( $callback ) ) { + throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce' ) ); + } - case 'clear_expired_transients': - /* translators: %d: amount of expired transients */ - $message = sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() ); - break; + $message = call_user_func( $callback ); - case 'delete_orphaned_variations': - // Delete orphans. - $result = absint( - $wpdb->query( - "DELETE products - FROM {$wpdb->posts} products - LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent - WHERE wp.ID IS NULL AND products.post_type = 'product_variation';" - ) - ); - /* translators: %d: amount of orphaned variations */ - $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result ); - break; + if ( false === $message ) { + throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce' ) ); + } - case 'clear_expired_download_permissions': - // Delete expired download permissions and ones with 0 downloads remaining. - $result = absint( - $wpdb->query( - $wpdb->prepare( - "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions - WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )", - date( 'Y-m-d', current_time( 'timestamp' ) ) - ) - ) - ); - /* translators: %d: amount of permissions */ - $message = sprintf( __( '%d permissions deleted', 'woocommerce' ), $result ); - break; - - case 'regenerate_product_lookup_tables': - if ( ! wc_update_product_lookup_tables_is_running() ) { - wc_update_product_lookup_tables(); - } - $message = __( 'Lookup tables are regenerating', 'woocommerce' ); - break; - case 'reset_roles': - // Remove then re-add caps and roles. - \WC_Install::remove_roles(); - \WC_Install::create_roles(); - $message = __( 'Roles successfully reset', 'woocommerce' ); - break; - - case 'recount_terms': - $product_cats = get_terms( - 'product_cat', - array( - 'hide_empty' => false, - 'fields' => 'id=>parent', - ) - ); - _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false ); - $product_tags = get_terms( - 'product_tag', - array( - 'hide_empty' => false, - 'fields' => 'id=>parent', - ) - ); - _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); - $message = __( 'Terms successfully recounted', 'woocommerce' ); - break; - - case 'clear_sessions': - $wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" ); - $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. - wp_cache_flush(); - /* translators: %d: amount of sessions */ - $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) ); - break; - - case 'install_pages': - \WC_Install::create_pages(); - $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); - break; - - case 'delete_taxes': - $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); - $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); - \WC_Cache_Helper::incr_cache_prefix( 'taxes' ); - $message = __( 'Tax rates successfully deleted', 'woocommerce' ); - break; - - case 'regenerate_thumbnails': - \WC_Regenerate_Images::queue_image_regeneration(); - $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); - break; - - case 'db_update_routine': - $blog_id = get_current_blog_id(); - // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). - // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. - do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); - $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' ); - break; - - default: - $tools = $this->get_tools(); - if ( isset( $tools[ $tool ]['callback'] ) ) { - $callback = $tools[ $tool ]['callback']; - $return = call_user_func( $callback ); - if ( is_string( $return ) ) { - $message = $return; - } elseif ( false === $return ) { - $callback_string = is_array( $callback ) ? get_class( $callback[0] ) . '::' . $callback[1] : $callback; - $ran = false; - /* translators: %s: callback string */ - $message = sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback_string ); - } else { - $message = __( 'Tool ran.', 'woocommerce' ); - } - } else { - $ran = false; - $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ); - } - break; + if ( empty( $message ) || ! is_string( $message ) ) { + $message = __( 'Tool ran.', 'woocommerce' ); + } + } catch ( Exception $e ) { + $message = $e->getMessage(); + $ran = false; } return array( @@ -553,4 +440,186 @@ class SystemStatusTools extends AbstractController { 'message' => $message, ); } + + /** + * Tool: clear_transients. + * + * @return string Success message. + */ + protected function clear_transients() { + wc_delete_product_transients(); + wc_delete_shop_order_transients(); + delete_transient( 'wc_count_comments' ); + + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( ! empty( $attribute_taxonomies ) ) { + foreach ( $attribute_taxonomies as $attribute ) { + delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name ); + } + } + + \WC_Cache_Helper::get_transient_version( 'shipping', true ); + return __( 'Product transients cleared', 'woocommerce' ); + } + + /** + * Tool: clear_expired_transients. + * + * @return string Success message. + */ + protected function clear_expired_transients() { + /* translators: %d: amount of expired transients */ + return sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() ); + } + + /** + * Tool: delete_orphaned_variations. + * + * @return string Success message. + */ + protected function delete_orphaned_variations() { + global $wpdb; + + $result = absint( + $wpdb->query( + "DELETE products + FROM {$wpdb->posts} products + LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent + WHERE wp.ID IS NULL AND products.post_type = 'product_variation';" + ) + ); + /* translators: %d: amount of orphaned variations */ + return sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result ); + } + + /** + * Tool: clear_expired_download_permissions. + * + * @return string Success message. + */ + protected function clear_expired_download_permissions() { + global $wpdb; + + $result = absint( + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )", + date( 'Y-m-d', current_time( 'timestamp' ) ) + ) + ) + ); + /* translators: %d: amount of permissions */ + return sprintf( __( '%d permissions deleted', 'woocommerce' ), $result ); + } + + /** + * Tool: regenerate_product_lookup_tables. + * + * @return string Success message. + */ + protected function regenerate_product_lookup_tables() { + if ( ! wc_update_product_lookup_tables_is_running() ) { + wc_update_product_lookup_tables(); + } + return __( 'Lookup tables are regenerating', 'woocommerce' ); + } + + /** + * Tool: reset_roles. + * + * @return string Success message. + */ + protected function reset_roles() { + \WC_Install::remove_roles(); + \WC_Install::create_roles(); + return __( 'Roles successfully reset', 'woocommerce' ); + } + + /** + * Tool: recount_terms. + * + * @return string Success message. + */ + protected function recount_terms() { + $product_cats = get_terms( + 'product_cat', + array( + 'hide_empty' => false, + 'fields' => 'id=>parent', + ) + ); + _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false ); + $product_tags = get_terms( + 'product_tag', + array( + 'hide_empty' => false, + 'fields' => 'id=>parent', + ) + ); + _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); + return __( 'Terms successfully recounted', 'woocommerce' ); + } + + /** + * Tool: clear_sessions. + * + * @return string Success message. + */ + protected function clear_sessions() { + global $wpdb; + + $wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" ); + $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. + wp_cache_flush(); + /* translators: %d: amount of sessions */ + return sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) ); + } + + /** + * Tool: install_pages. + * + * @return string Success message. + */ + protected function install_pages() { + \WC_Install::create_pages(); + return __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); + } + + /** + * Tool: delete_taxes. + * + * @return string Success message. + */ + protected function delete_taxes() { + global $wpdb; + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); + \WC_Cache_Helper::incr_cache_prefix( 'taxes' ); + return __( 'Tax rates successfully deleted', 'woocommerce' ); + } + + /** + * Tool: regenerate_thumbnails. + * + * @return string Success message. + */ + protected function regenerate_thumbnails() { + \WC_Regenerate_Images::queue_image_regeneration(); + return __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); + } + + /** + * Tool: db_update_routine. + * + * @return string Success message. + */ + protected function db_update_routine() { + $blog_id = get_current_blog_id(); + // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). + // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. + do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); + return __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' ); + } } From 9a7f47bfdfa9a11352be5ed27f6c511e81848d97 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 13 Jun 2019 17:24:29 +0100 Subject: [PATCH 137/440] Tool ran should be true --- src/Controllers/Version4/AbstractObjectsController.php | 2 +- src/Controllers/Version4/OrderRefunds.php | 2 +- src/Controllers/Version4/ProductVariations.php | 2 +- src/Controllers/Version4/Products.php | 2 +- src/Controllers/Version4/SystemStatusTools.php | 2 ++ 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 642b2235dc7..c0b2a202196 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -32,7 +32,7 @@ abstract class AbstractObjectsController extends AbstractController { * Get object. * * @param int $id Object ID. - * @return \WC_Data + * @return \WC_Data|bool */ abstract protected function get_object( $id ); diff --git a/src/Controllers/Version4/OrderRefunds.php b/src/Controllers/Version4/OrderRefunds.php index 0a100717fb0..dc40abf6e09 100644 --- a/src/Controllers/Version4/OrderRefunds.php +++ b/src/Controllers/Version4/OrderRefunds.php @@ -120,7 +120,7 @@ class OrderRefunds extends Orders { * * @since 3.0.0 * @param int $id Object ID. - * @return \WC_Data + * @return \WC_Data|bool */ protected function get_object( $id ) { return wc_get_order( $id ); diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index ffba6580906..d0da8692edc 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -143,7 +143,7 @@ class ProductVariations extends Products { * * @since 3.0.0 * @param int $id Object ID. - * @return \WC_Data + * @return \WC_Data|bool */ protected function get_object( $id ) { return wc_get_product( $id ); diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 75feda08b86..26045c52312 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -136,7 +136,7 @@ class Products extends AbstractObjectsController { * @param int $id Object ID. * * @since 3.0.0 - * @return \WC_Data + * @return \WC_Data|bool */ protected function get_object( $id ) { return wc_get_product( $id ); diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php index 17b073b4b13..51ead8897cf 100644 --- a/src/Controllers/Version4/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -430,6 +430,8 @@ class SystemStatusTools extends AbstractController { if ( empty( $message ) || ! is_string( $message ) ) { $message = __( 'Tool ran.', 'woocommerce' ); } + + $ran = true; } catch ( Exception $e ) { $message = $e->getMessage(); $ran = false; From d88ab33dda3dd89b17e6e7b6107eafcb8cc8f85b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 14 Jun 2019 11:44:09 +0100 Subject: [PATCH 138/440] Split batch and settings into traits --- .../Version4/AbstractController.php | 492 +++--------------- .../Version4/AbstractObjectsController.php | 78 +-- src/Controllers/Version4/BatchTrait.php | 263 ++++++++++ src/Controllers/Version4/Coupons.php | 92 +--- src/Controllers/Version4/Orders.php | 82 --- src/Controllers/Version4/PaymentGateways.php | 1 + src/Controllers/Version4/Products.php | 86 --- src/Controllers/Version4/SettingsOptions.php | 1 + src/Controllers/Version4/SettingsTrait.php | 152 ++++++ .../Version4/ShippingZoneMethods.php | 1 + 10 files changed, 545 insertions(+), 703 deletions(-) create mode 100644 src/Controllers/Version4/BatchTrait.php create mode 100644 src/Controllers/Version4/SettingsTrait.php diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index fe827724f19..a9b6b06b7ea 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -2,9 +2,6 @@ /** * REST Controller * - * This class extend `WP_REST_Controller` in order to include /batch endpoint - * for almost all endpoints in WooCommerce REST API. - * * It's required to follow "Controller Classes" guide before extending this class: * * @@ -42,425 +39,92 @@ abstract class AbstractController extends WP_REST_Controller { */ protected $rest_base = ''; + /** + * Register route for items requests. + */ + protected function register_items_route() { + register_rest_route( + $this->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(), + ), + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ), + true + ); + } + + /** + * Register route for item create/get/delete/update requests. + */ + protected function register_item_route() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier 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' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + array( + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => \WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'type' => 'boolean', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ), + true + ); + } + /** * Add the schema from additional fields to an schema array. * - * The type of object is inferred from the passed schema. - * * @param array $schema Schema array. - * * @return array */ protected function add_additional_fields_schema( $schema ) { - if ( empty( $schema['title'] ) ) { - return $schema; - } - - /** - * Can't use $this->get_object_type otherwise we cause an inf loop. - */ - $object_type = $schema['title']; - - $additional_fields = $this->get_additional_fields( $object_type ); - - foreach ( $additional_fields as $field_name => $field_options ) { - if ( ! $field_options['schema'] ) { - continue; - } - - $schema['properties'][ $field_name ] = $field_options['schema']; - } - + $schema = parent::add_additional_fields_schema( $schema ); + $object_type = $schema['title']; $schema['properties'] = apply_filters( 'woocommerce_rest_' . $object_type . '_schema', $schema['properties'] ); - return $schema; } - - /** - * Get normalized rest base. - * - * @return string - */ - protected function get_normalized_rest_base() { - return preg_replace( '/\(.*\)\//i', '', $this->rest_base ); - } - - /** - * Check batch limit. - * - * @param array $items Request items. - * @return bool|\WP_Error - */ - protected function check_batch_limit( $items ) { - $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); - $total = 0; - - if ( ! empty( $items['create'] ) ) { - $total += count( $items['create'] ); - } - - if ( ! empty( $items['update'] ) ) { - $total += count( $items['update'] ); - } - - if ( ! empty( $items['delete'] ) ) { - $total += count( $items['delete'] ); - } - - if ( $total > $limit ) { - /* translators: %s: items limit */ - return new \WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); - } - - return true; - } - - /** - * Bulk create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * @return array Of \WP_Error or \WP_REST_Response. - */ - public function batch_items( $request ) { - /** - * REST Server - * - * @var WP_REST_Server $wp_rest_server - */ - global $wp_rest_server; - - // Get the request params. - $items = array_filter( $request->get_params() ); - $response = array(); - - // Check batch limit. - $limit = $this->check_batch_limit( $items ); - if ( is_wp_error( $limit ) ) { - return $limit; - } - - if ( ! empty( $items['create'] ) ) { - foreach ( $items['create'] as $item ) { - $_item = new \WP_REST_Request( 'POST' ); - - // Default parameters. - $defaults = array(); - $schema = $this->get_public_item_schema(); - foreach ( $schema['properties'] as $arg => $options ) { - if ( isset( $options['default'] ) ) { - $defaults[ $arg ] = $options['default']; - } - } - $_item->set_default_params( $defaults ); - - // Set request parameters. - $_item->set_body_params( $item ); - $_response = $this->create_item( $_item ); - - if ( is_wp_error( $_response ) ) { - $response['create'][] = array( - 'id' => 0, - 'error' => array( - 'code' => $_response->get_error_code(), - 'message' => $_response->get_error_message(), - 'data' => $_response->get_error_data(), - ), - ); - } else { - $response['create'][] = $wp_rest_server->response_to_data( $_response, '' ); - } - } - } - - if ( ! empty( $items['update'] ) ) { - foreach ( $items['update'] as $item ) { - $_item = new \WP_REST_Request( 'PUT' ); - $_item->set_body_params( $item ); - $_response = $this->update_item( $_item ); - - if ( is_wp_error( $_response ) ) { - $response['update'][] = array( - 'id' => $item['id'], - 'error' => array( - 'code' => $_response->get_error_code(), - 'message' => $_response->get_error_message(), - 'data' => $_response->get_error_data(), - ), - ); - } else { - $response['update'][] = $wp_rest_server->response_to_data( $_response, '' ); - } - } - } - - if ( ! empty( $items['delete'] ) ) { - foreach ( $items['delete'] as $id ) { - $id = (int) $id; - - if ( 0 === $id ) { - continue; - } - - $_item = new \WP_REST_Request( 'DELETE' ); - $_item->set_query_params( - array( - 'id' => $id, - 'force' => true, - ) - ); - $_response = $this->delete_item( $_item ); - - if ( is_wp_error( $_response ) ) { - $response['delete'][] = array( - 'id' => $id, - 'error' => array( - 'code' => $_response->get_error_code(), - 'message' => $_response->get_error_message(), - 'data' => $_response->get_error_data(), - ), - ); - } else { - $response['delete'][] = $wp_rest_server->response_to_data( $_response, '' ); - } - } - } - - return $response; - } - - /** - * Validate a text value for a text based setting. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string - */ - public function validate_setting_text_field( $value, $setting ) { - $value = is_null( $value ) ? '' : $value; - return wp_kses_post( trim( stripslashes( $value ) ) ); - } - - /** - * Validate select based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string|\WP_Error - */ - public function validate_setting_select_field( $value, $setting ) { - if ( array_key_exists( $value, $setting['options'] ) ) { - return $value; - } else { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); - } - } - - /** - * Validate multiselect based settings. - * - * @since 3.0.0 - * @param array $values Values. - * @param array $setting Setting. - * @return array|\WP_Error - */ - public function validate_setting_multiselect_field( $values, $setting ) { - if ( empty( $values ) ) { - return array(); - } - - if ( ! is_array( $values ) ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - $final_values = array(); - foreach ( $values as $value ) { - if ( array_key_exists( $value, $setting['options'] ) ) { - $final_values[] = $value; - } - } - - return $final_values; - } - - /** - * Validate image_width based settings. - * - * @since 3.0.0 - * @param array $values Values. - * @param array $setting Setting. - * @return string|\WP_Error - */ - public function validate_setting_image_width_field( $values, $setting ) { - if ( ! is_array( $values ) ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - $current = $setting['value']; - if ( isset( $values['width'] ) ) { - $current['width'] = intval( $values['width'] ); - } - if ( isset( $values['height'] ) ) { - $current['height'] = intval( $values['height'] ); - } - if ( isset( $values['crop'] ) ) { - $current['crop'] = (bool) $values['crop']; - } - return $current; - } - - /** - * Validate radio based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string|\WP_Error - */ - public function validate_setting_radio_field( $value, $setting ) { - return $this->validate_setting_select_field( $value, $setting ); - } - - /** - * Validate checkbox based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string|\WP_Error - */ - public function validate_setting_checkbox_field( $value, $setting ) { - if ( in_array( $value, array( 'yes', 'no' ), true ) ) { - return $value; - } elseif ( empty( $value ) ) { - $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; - return $value; - } else { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); - } - } - - /** - * Validate textarea based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string - */ - public function validate_setting_textarea_field( $value, $setting ) { - $value = is_null( $value ) ? '' : $value; - return wp_kses( - trim( stripslashes( $value ) ), - array_merge( - array( - 'iframe' => array( - 'src' => true, - 'style' => true, - 'id' => true, - 'class' => true, - ), - ), - wp_kses_allowed_html( 'post' ) - ) - ); - } - - /** - * Add meta query. - * - * @since 3.0.0 - * @param array $args Query args. - * @param array $meta_query Meta query. - * @return array - */ - protected function add_meta_query( $args, $meta_query ) { - if ( empty( $args['meta_query'] ) ) { - $args['meta_query'] = []; // phpcs:ignore - } - - $args['meta_query'][] = $meta_query; - - return $args['meta_query']; - } - - /** - * Get the batch schema, conforming to JSON Schema. - * - * @return array - */ - public function get_public_batch_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'batch', - 'type' => 'object', - 'properties' => array( - 'create' => array( - 'description' => __( 'List of created resources.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - ), - ), - 'update' => array( - 'description' => __( 'List of updated resources.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - ), - ), - 'delete' => array( - 'description' => __( 'List of delete resources.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'integer', - ), - ), - ), - ); - - return $schema; - } - - /** - * Gets an array of fields to be included on the response. - * Included fields are based on item schema and `_fields=` request argument. - * Introduced to support WordPress 4.9.6 changes. - * - * @since 3.5.0 - * @param \WP_REST_Request $request Full details about the request. - * @return array Fields to be included in the response. - */ - public function get_fields_for_response( $request ) { - $schema = $this->get_item_schema(); - $fields = isset( $schema['properties'] ) ? array_keys( $schema['properties'] ) : array(); - - $additional_fields = $this->get_additional_fields(); - foreach ( $additional_fields as $field_name => $field_options ) { - // For back-compat, include any field with an empty schema - // because it won't be present in $this->get_item_schema(). - if ( is_null( $field_options['schema'] ) ) { - $fields[] = $field_name; - } - } - - if ( ! isset( $request['_fields'] ) ) { - return $fields; - } - $requested_fields = array_filter( is_array( $request['_fields'] ) ? $request['_fields'] : (array) preg_split( '/[\s,]+/', $request['_fields'] ) ); - if ( 0 === count( $requested_fields ) ) { - return $fields; - } - // Trim off outside whitespace from the comma delimited list. - $requested_fields = array_map( 'trim', $requested_fields ); - // Always persist 'id', because it can be needed for add_additional_fields_to_object(). - if ( in_array( 'id', $fields, true ) ) { - $requested_fields[] = 'id'; - } - return array_intersect( $fields, $requested_fields ); - } } diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index c0b2a202196..efca889a057 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -13,6 +13,7 @@ defined( 'ABSPATH' ) || exit; * CRUD Object Controller. */ abstract class AbstractObjectsController extends AbstractController { + use BatchTrait; /** * If object is hierarchical. @@ -36,6 +37,35 @@ abstract class AbstractObjectsController extends AbstractController { */ abstract protected function get_object( $id ); + /** + * Prepares the object for the REST response. + * + * @since 3.0.0 + * @param \WC_Data $object Object data. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response Response object on success, or \WP_Error object on failure. + */ + abstract protected function prepare_object_for_response( $object, $request ); + + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param \WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return \WC_Data The prepared item, or \WP_Error object on failure. + */ + abstract protected function prepare_object_for_database( $request, $creating = false ); + + /** + * Register the routes for products. + */ + public function register_routes() { + $this->register_items_route(); + $this->register_item_route(); + $this->register_batch_route(); + } + /** * Check if a given request has access to read items. * @@ -127,36 +157,6 @@ abstract class AbstractObjectsController extends AbstractController { return true; } - /** - * Get object permalink. - * - * @param object $object Object. - * @return string - */ - protected function get_permalink( $object ) { - return ''; - } - - /** - * Prepares the object for the REST response. - * - * @since 3.0.0 - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response Response object on success, or \WP_Error object on failure. - */ - abstract protected function prepare_object_for_response( $object, $request ); - - /** - * Prepares one object for create or update operation. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WC_Data The prepared item, or \WP_Error object on failure. - */ - abstract protected function prepare_object_for_database( $request, $creating = false ); - /** * Get a single item. * @@ -814,4 +814,22 @@ abstract class AbstractObjectsController extends AbstractController { return $valid_vars; } + + /** + * Add meta query. + * + * @since 3.0.0 + * @param array $args Query args. + * @param array $meta_query Meta query. + * @return array + */ + protected function add_meta_query( $args, $meta_query ) { + if ( empty( $args['meta_query'] ) ) { + $args['meta_query'] = []; // phpcs:ignore + } + + $args['meta_query'][] = $meta_query; + + return $args['meta_query']; + } } diff --git a/src/Controllers/Version4/BatchTrait.php b/src/Controllers/Version4/BatchTrait.php new file mode 100644 index 00000000000..44125054470 --- /dev/null +++ b/src/Controllers/Version4/BatchTrait.php @@ -0,0 +1,263 @@ +get_params() ); + $limit = $this->check_batch_limit( $items ); + if ( is_wp_error( $limit ) ) { + return $limit; + } + + $response = []; + $batches = [ 'create', 'update', 'delete' ]; + foreach ( $batches as $batch ) { + if ( ! isset( $items[ $batch ] ) ) { + continue; + } + $items[ $batch ] = wp_parse_id_list( $items[ $batch ] ); + $response[ $batch ] = $this->{"batch_$batch"}( $items[ $batch ] ); + } + + return $response; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param \WP_REST_Request $request Full details about the request. + * @return boolean|\WP_Error + */ + abstract public function batch_items_permissions_check( $request ); + + /** + * Register route for batch requests. + */ + protected function register_batch_route() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ), + true + ); + } + + /** + * Get the batch schema, conforming to JSON Schema. + * + * @return array + */ + protected function get_public_batch_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'batch', + 'type' => 'object', + 'properties' => array( + 'create' => array( + 'description' => __( 'List of created resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + ), + ), + 'update' => array( + 'description' => __( 'List of updated resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + ), + ), + 'delete' => array( + 'description' => __( 'List of delete resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + ), + ), + ); + + return $schema; + } + + /** + * Get normalized rest base. + * + * @return string + */ + protected function get_normalized_rest_base() { + return preg_replace( '/\(.*\)\//i', '', $this->rest_base ); + } + + /** + * Check batch limit. + * + * @param array $items Request items. + * @return bool|\WP_Error + */ + protected function check_batch_limit( $items ) { + $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); + $total = 0; + + $batches = [ 'create', 'update', 'delete' ]; + foreach ( $batches as $batch ) { + if ( ! isset( $items[ $batch ] ) ) { + continue; + } + $items[ $batch ] = wp_parse_id_list( $items[ $batch ] ); + $total = $total + count( $items[ $batch ] ); + } + + if ( $total > $limit ) { + /* translators: %s: items limit */ + return new \WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); + } + + return true; + } + + /** + * Get default params from schema. + * + * @return array + */ + protected function get_default_params() { + $defaults = []; + $schema = $this->get_public_item_schema(); + foreach ( $schema['properties'] as $arg => $options ) { + if ( isset( $options['default'] ) ) { + $defaults[ $arg ] = $options['default']; + } + } + return $defaults; + } + + /** + * Batch create items. + * + * @param array $items Array of item ids. + * @return array Response data. + */ + protected function batch_create( $items ) { + $response = []; + + foreach ( $items as $id ) { + $item = new \WP_REST_Request( 'POST' ); + $item->set_default_params( $this->get_default_params() ); + $item->set_body_params( $item ); + $item_response = $this->create_item( $item ); + $response[] = $this->format_response( $id, $item_response ); + } + + return $response; + } + + /** + * Batch update items. + * + * @param array $items Array of item ids. + * @return array Response data. + */ + protected function batch_update( $items ) { + $response = []; + + foreach ( $items as $id ) { + $item = new \WP_REST_Request( 'PUT' ); + $item->set_body_params( $item ); + $item_response = $this->update_item( $item ); + $response[] = $this->format_response( $id, $item_response ); + } + + return $response; + } + + /** + * Batch delete items. + * + * @param array $items Array of item ids. + * @return array Response data. + */ + protected function batch_delete( $items ) { + $response = []; + + foreach ( $items as $id ) { + $item = new \WP_REST_Request( 'DELETE' ); + $item->set_query_params( + [ + 'id' => $id, + 'force' => true, + ] + ); + $item_response = $this->delete_item( $item ); + $response[] = $this->format_response( $id, $item_response ); + } + + return $response; + } + + /** + * Format response data. + * + * @param int $id ID of item being updated. + * @param \WP_REST_Response|\WP_Error $response Response object. + * @return array + */ + protected function format_response( $id, $response ) { + /** + * REST Server + * + * @var \WP_REST_Server $wp_rest_server + */ + global $wp_rest_server; + + if ( is_wp_error( $response ) ) { + return $this->format_error_response( $response ); + } else { + return array( + 'id' => $id, + 'error' => $wp_rest_server->response_to_data( $response, '' ), + ); + } + } + + /** + * Format WP Error to response data. + * + * @param \WP_Error $error Error object. + * @return array + */ + protected function format_error_response( $error ) { + return array( + 'code' => $error->get_error_code(), + 'message' => $error->get_error_message(), + 'data' => $error->get_error_data(), + ); + } +} diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index a32d11bf31b..7bc765561a2 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -30,97 +30,6 @@ class Coupons extends AbstractObjectsController { */ protected $post_type = 'shop_coupon'; - /** - * Register the routes for coupons. - */ - public function register_routes() { - register_rest_route( - $this->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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), - 'required' => true, - 'type' => 'string', - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); - } - /** * Get object. * @@ -334,6 +243,7 @@ class Coupons extends AbstractObjectsController { 'description' => __( 'Coupon code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), + 'required' => true, ), 'amount' => array( 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index b145056f801..762741ffff0 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -44,88 +44,6 @@ class Orders extends AbstractObjectsController { */ protected $request = array(); - /** - * Register the routes for orders. - */ - public function register_routes() { - register_rest_route( - $this->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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); - } - /** * Get object. Return false if object is not of required type. * diff --git a/src/Controllers/Version4/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php index ee073b1ea1a..773b499e3cb 100644 --- a/src/Controllers/Version4/PaymentGateways.php +++ b/src/Controllers/Version4/PaymentGateways.php @@ -15,6 +15,7 @@ defined( 'ABSPATH' ) || exit; * Payment gateways controller class. */ class PaymentGateways extends AbstractController { + use SettingsTrait; /** * Route base. diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 26045c52312..96301be217b 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -44,92 +44,6 @@ class Products extends AbstractObjectsController { add_action( "woocommerce_rest_insert_{$this->post_type}_object", array( $this, 'clear_transients' ) ); } - /** - * Register the routes for products. - */ - public function register_routes() { - register_rest_route( - $this->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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), - 'type' => 'boolean', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); - } - /** * Get object. * diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index 092ce3eda30..af2e525efe5 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -15,6 +15,7 @@ defined( 'ABSPATH' ) || exit; * REST API Setting Options controller class. */ class SettingsOptions extends AbstractController { + use SettingsTrait; /** * Route base. diff --git a/src/Controllers/Version4/SettingsTrait.php b/src/Controllers/Version4/SettingsTrait.php new file mode 100644 index 00000000000..a16763e5a43 --- /dev/null +++ b/src/Controllers/Version4/SettingsTrait.php @@ -0,0 +1,152 @@ + 400 ) ); + } + } + + /** + * Validate multiselect based settings. + * + * @since 3.0.0 + * @param array $values Values. + * @param array $setting Setting. + * @return array|\WP_Error + */ + public function validate_setting_multiselect_field( $values, $setting ) { + if ( empty( $values ) ) { + return array(); + } + + if ( ! is_array( $values ) ) { + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $final_values = array(); + foreach ( $values as $value ) { + if ( array_key_exists( $value, $setting['options'] ) ) { + $final_values[] = $value; + } + } + + return $final_values; + } + + /** + * Validate image_width based settings. + * + * @since 3.0.0 + * @param array $values Values. + * @param array $setting Setting. + * @return string|\WP_Error + */ + public function validate_setting_image_width_field( $values, $setting ) { + if ( ! is_array( $values ) ) { + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $current = $setting['value']; + if ( isset( $values['width'] ) ) { + $current['width'] = intval( $values['width'] ); + } + if ( isset( $values['height'] ) ) { + $current['height'] = intval( $values['height'] ); + } + if ( isset( $values['crop'] ) ) { + $current['crop'] = (bool) $values['crop']; + } + return $current; + } + + /** + * Validate radio based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|\WP_Error + */ + public function validate_setting_radio_field( $value, $setting ) { + return $this->validate_setting_select_field( $value, $setting ); + } + + /** + * Validate checkbox based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|\WP_Error + */ + public function validate_setting_checkbox_field( $value, $setting ) { + if ( in_array( $value, array( 'yes', 'no' ), true ) ) { + return $value; + } elseif ( empty( $value ) ) { + $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; + return $value; + } else { + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + /** + * Validate textarea based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string + */ + public function validate_setting_textarea_field( $value, $setting ) { + $value = is_null( $value ) ? '' : $value; + return wp_kses( + trim( stripslashes( $value ) ), + array_merge( + array( + 'iframe' => array( + 'src' => true, + 'style' => true, + 'id' => true, + 'class' => true, + ), + ), + wp_kses_allowed_html( 'post' ) + ) + ); + } +} diff --git a/src/Controllers/Version4/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php index 717205ff2a8..92e063891f7 100644 --- a/src/Controllers/Version4/ShippingZoneMethods.php +++ b/src/Controllers/Version4/ShippingZoneMethods.php @@ -15,6 +15,7 @@ defined( 'ABSPATH' ) || exit; * REST API Shipping Zone Methods class. */ class ShippingZoneMethods extends AbstractShippingZonesController { + use SettingsTrait; /** * Register the routes for Shipping Zone Methods. From 7f2ea5cc2fc2e3255a397c1a78116eaf597e0a88 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 14 Jun 2019 13:43:29 +0100 Subject: [PATCH 139/440] Fix tests for batches --- phpunit.xml | 3 + .../Version4/AbstractController.php | 134 ++++++++++-------- .../Version4/AbstractObjectsController.php | 1 - .../Version4/AbstractTermsContoller.php | 15 +- src/Controllers/Version4/BatchTrait.php | 98 +++++++------ .../Version4/CustomerDownloads.php | 21 +-- src/Controllers/Version4/Customers.php | 15 +- .../Version4/ProductAttributes.php | 15 +- src/Controllers/Version4/ProductReviews.php | 15 +- .../Version4/ProductVariations.php | 46 +++--- src/Controllers/Version4/Settings.php | 14 +- src/Controllers/Version4/SettingsOptions.php | 34 ++--- src/Controllers/Version4/Taxes.php | 15 +- src/Controllers/Version4/Webhooks.php | 15 +- unit-tests/Tests/Version4/Data.php | 30 +++- 15 files changed, 215 insertions(+), 256 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 9119520176d..8f9df0b9fb5 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -13,5 +13,8 @@ ./unit-tests/Tests + + ./unit-tests/Tests/Version4 + diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index a9b6b06b7ea..d10479673e2 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -24,6 +24,7 @@ use \WP_REST_Controller; * @version 2.6.0 */ abstract class AbstractController extends WP_REST_Controller { + use BatchTrait; /** * Endpoint namespace. @@ -41,76 +42,97 @@ abstract class AbstractController extends WP_REST_Controller { /** * Register route for items requests. + * + * @param array $methods Supported methods. read, create. */ - protected function register_items_route() { + protected function register_items_route( $methods = [ 'read', 'create' ] ) { + $routes = []; + $routes['schema'] = [ $this, 'get_public_item_schema' ]; + + if ( in_array( 'read', $methods, true ) ) { + $routes[] = array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ); + } + + if ( in_array( 'create', $methods, true ) ) { + $routes[] = array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), + ); + } + register_rest_route( $this->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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), + $routes, true ); } /** * Register route for item create/get/delete/update requests. + * + * @param array $methods Supported methods. read, create. */ - protected function register_item_route() { + protected function register_item_route( $methods = [ 'read', 'edit', 'delete' ] ) { + $routes = []; + $routes['schema'] = [ $this, 'get_public_item_schema' ]; + $routes['args'] = [ + 'id' => [ + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ], + ]; + + if ( in_array( 'read', $methods, true ) ) { + $routes[] = array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ); + } + + if ( in_array( 'edit', $methods, true ) ) { + $routes[] = array( + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), + ); + } + + if ( in_array( 'delete', $methods, true ) ) { + $routes[] = array( + 'methods' => \WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'type' => 'boolean', + ), + ), + ); + } + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier 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' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), - 'type' => 'boolean', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), + $routes, true ); } diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index efca889a057..f3eb35c278b 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -13,7 +13,6 @@ defined( 'ABSPATH' ) || exit; * CRUD Object Controller. */ abstract class AbstractObjectsController extends AbstractController { - use BatchTrait; /** * If object is hierarchical. diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index fea0f2ce815..956d83c9474 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -117,20 +117,7 @@ abstract class AbstractTermsContoller extends AbstractController { true ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); + $this->register_batch_route(); } /** diff --git a/src/Controllers/Version4/BatchTrait.php b/src/Controllers/Version4/BatchTrait.php index 44125054470..40a50491d23 100644 --- a/src/Controllers/Version4/BatchTrait.php +++ b/src/Controllers/Version4/BatchTrait.php @@ -19,23 +19,37 @@ trait BatchTrait { * @return array Of \WP_Error or \WP_REST_Response. */ public function batch_items( $request ) { - $items = array_filter( $request->get_params() ); + $items = $request->get_params(); $limit = $this->check_batch_limit( $items ); if ( is_wp_error( $limit ) ) { return $limit; } - $response = []; $batches = [ 'create', 'update', 'delete' ]; + $response = []; + foreach ( $batches as $batch ) { - if ( ! isset( $items[ $batch ] ) ) { - continue; - } - $items[ $batch ] = wp_parse_id_list( $items[ $batch ] ); - $response[ $batch ] = $this->{"batch_$batch"}( $items[ $batch ] ); + $response[ $batch ] = $this->{"batch_$batch"}( $this->get_batch_of_items_from_request( $request, $batch ) ); } - return $response; + return array_filter( $response ); + } + + /** + * Get batch of items from requst. + * + * @param \WP_REST_Request $request Full details about the request. + * @param string $batch_type Batch type; one of create, update, delete. + * @return array + */ + protected function get_batch_of_items_from_request( $request, $batch_type ) { + $params = $request->get_params(); + + if ( ! isset( $params[ $batch_type ] ) ) { + return array(); + } + + return array_filter( $params[ $batch_type ] ); } /** @@ -44,7 +58,9 @@ trait BatchTrait { * @param \WP_REST_Request $request Full details about the request. * @return boolean|\WP_Error */ - abstract public function batch_items_permissions_check( $request ); + public function batch_items_permissions_check( $request ) { + return update_items_permissions_check( $request ); + } /** * Register route for batch requests. @@ -123,16 +139,15 @@ trait BatchTrait { * @return bool|\WP_Error */ protected function check_batch_limit( $items ) { - $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); - $total = 0; + $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); + $total = 0; + $batches = [ 'create', 'update', 'delete' ]; - $batches = [ 'create', 'update', 'delete' ]; foreach ( $batches as $batch ) { if ( ! isset( $items[ $batch ] ) ) { continue; } - $items[ $batch ] = wp_parse_id_list( $items[ $batch ] ); - $total = $total + count( $items[ $batch ] ); + $total = $total + count( $items[ $batch ] ); } if ( $total > $limit ) { @@ -162,40 +177,42 @@ trait BatchTrait { /** * Batch create items. * - * @param array $items Array of item ids. + * @param array $items Array of items. * @return array Response data. */ protected function batch_create( $items ) { - $response = []; + $batch_response = []; - foreach ( $items as $id ) { - $item = new \WP_REST_Request( 'POST' ); - $item->set_default_params( $this->get_default_params() ); - $item->set_body_params( $item ); - $item_response = $this->create_item( $item ); - $response[] = $this->format_response( $id, $item_response ); + foreach ( $items as $item ) { + $request = new \WP_REST_Request( 'POST' ); + $request->set_default_params( $this->get_default_params() ); + $request->set_body_params( $item ); + + $response = $this->create_item( $request ); + $batch_response[] = $this->format_response( 0, $response ); } - return $response; + return $batch_response; } /** * Batch update items. * - * @param array $items Array of item ids. + * @param array $items Array of items. * @return array Response data. */ protected function batch_update( $items ) { - $response = []; + $batch_response = []; - foreach ( $items as $id ) { - $item = new \WP_REST_Request( 'PUT' ); - $item->set_body_params( $item ); - $item_response = $this->update_item( $item ); - $response[] = $this->format_response( $id, $item_response ); + foreach ( $items as $item ) { + $request = new \WP_REST_Request( 'PUT' ); + $request->set_body_params( $item ); + + $response = $this->update_item( $request ); + $batch_response[] = $this->format_response( $item['id'], $response ); } - return $response; + return $batch_response; } /** @@ -205,21 +222,22 @@ trait BatchTrait { * @return array Response data. */ protected function batch_delete( $items ) { - $response = []; + $batch_response = []; + $items = wp_parse_id_list( $items ); foreach ( $items as $id ) { - $item = new \WP_REST_Request( 'DELETE' ); - $item->set_query_params( + $request = new \WP_REST_Request( 'DELETE' ); + $request->set_query_params( [ 'id' => $id, 'force' => true, ] ); - $item_response = $this->delete_item( $item ); - $response[] = $this->format_response( $id, $item_response ); + $response = $this->delete_item( $request ); + $batch_response[] = $this->format_response( $id, $response ); } - return $response; + return $batch_response; } /** @@ -237,12 +255,12 @@ trait BatchTrait { */ global $wp_rest_server; - if ( is_wp_error( $response ) ) { - return $this->format_error_response( $response ); + if ( ! is_wp_error( $response ) ) { + return $wp_rest_server->response_to_data( $response, '' ); } else { return array( 'id' => $id, - 'error' => $wp_rest_server->response_to_data( $response, '' ), + 'error' => $this->format_error_response( $response ), ); } } diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index e03f6ec175d..588da40d3b5 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -27,26 +27,7 @@ class CustomerDownloads extends AbstractController { * Register the routes for customers. */ public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - 'args' => array( - 'customer_id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - ), - ), - 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 - ); + $this->register_items_route( [ 'read' ] ); } /** diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 4e0234b5138..41d6a07f4a8 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -115,20 +115,7 @@ class Customers extends AbstractController { true ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); + $this->register_batch_route(); } /** diff --git a/src/Controllers/Version4/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php index 70f955ea928..53c9ef2aada 100644 --- a/src/Controllers/Version4/ProductAttributes.php +++ b/src/Controllers/Version4/ProductAttributes.php @@ -105,20 +105,7 @@ class ProductAttributes extends AbstractController { true ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); + $this->register_batch_route(); } /** diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index 1a1b87be436..f6eb8600bbb 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -113,20 +113,7 @@ class ProductReviews extends AbstractController { true ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); + $this->register_batch_route(); } /** diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index d0da8692edc..9d81af75af3 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -725,37 +725,35 @@ class ProductVariations extends Products { } /** - * Bulk create, update and delete items. + * Get batch of items from requst. * - * @since 3.0.0 * @param \WP_REST_Request $request Full details about the request. - * @return array Of \WP_Error or \WP_REST_Response. + * @param string $batch_type Batch type; one of create, update, delete. + * @return array */ - public function batch_items( $request ) { - $items = array_filter( $request->get_params() ); - $params = $request->get_url_params(); - $product_id = $params['product_id']; - $body_params = array(); + protected function get_batch_of_items_from_request( $request, $batch_type ) { + $params = $request->get_params(); + $url_params = $request->get_url_params(); + $product_id = $url_params['product_id']; - foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { - if ( ! empty( $items[ $batch_type ] ) ) { - $injected_items = array(); - foreach ( $items[ $batch_type ] as $item ) { - $injected_items[] = is_array( $item ) ? array_merge( - array( - 'product_id' => $product_id, - ), - $item - ) : $item; - } - $body_params[ $batch_type ] = $injected_items; + if ( ! isset( $params[ $batch_type ] ) ) { + return array(); + } + + $items = array_filter( $params[ $batch_type ] ); + + if ( 'update' === $batch_type || 'create' === $batch_type ) { + foreach ( $items as $key => $item ) { + $items[ $key ] = array_merge( + array( + 'product_id' => $product_id, + ), + $item + ); } } - $request = new \WP_REST_Request( $request->get_method() ); - $request->set_body_params( $body_params ); - - return parent::batch_items( $request ); + return array_filter( $items ); } /** diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index 0d29ed833ff..8110ad64cae 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -42,19 +42,7 @@ class Settings extends AbstractController { ), true ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); + $this->register_batch_route(); } /** diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index af2e525efe5..6fba4a8ab1e 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -274,30 +274,32 @@ class SettingsOptions extends AbstractController { } /** - * Bulk create, update and delete items. + * Get batch of items from requst. * - * @since 3.0.0 * @param \WP_REST_Request $request Full details about the request. - * @return array Of \WP_Error or \WP_REST_Response. + * @param string $batch_type Batch type; one of create, update, delete. + * @return array */ - public function batch_items( $request ) { - // Get the request params. - $items = array_filter( $request->get_params() ); + protected function get_batch_of_items_from_request( $request, $batch_type ) { + $params = $request->get_params(); - /* + if ( ! isset( $params[ $batch_type ] ) ) { + return array(); + } + + /** * Since our batch settings update is group-specific and matches based on the route, * we inject the URL parameters (containing group) into the batch items */ - if ( ! empty( $items['update'] ) ) { - $to_update = array(); - foreach ( $items['update'] as $item ) { - $to_update[] = array_merge( $request->get_url_params(), $item ); + $items = array_filter( $params[ $batch_type ] ); + + if ( 'update' === $batch_type ) { + foreach ( $items as $key => $item ) { + $items[ $key ] = array_merge( $request->get_url_params(), $item ); } - $request = new \WP_REST_Request( $request->get_method() ); - $request->set_body_params( array( 'update' => $to_update ) ); } - return parent::batch_items( $request ); + return array_filter( $items ); } /** @@ -345,8 +347,7 @@ class SettingsOptions extends AbstractController { /** * Prepare a single setting object for response. * - * @since 3.0.0 - * @param object $item Setting object. + * @param object $item Setting object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ @@ -363,7 +364,6 @@ class SettingsOptions extends AbstractController { /** * Prepare links for the request. * - * @since 3.0.0 * @param string $setting_id Setting ID. * @param string $group_id Group ID. * @return array Links for the given setting. diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php index 5f974dd5dbb..595cede149e 100644 --- a/src/Controllers/Version4/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -89,20 +89,7 @@ class Taxes extends AbstractController { true ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); + $this->register_batch_route(); } /** diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index ececa580c0a..77886eb0703 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -110,20 +110,7 @@ class Webhooks extends AbstractController { true ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); + $this->register_batch_route(); } /** diff --git a/unit-tests/Tests/Version4/Data.php b/unit-tests/Tests/Version4/Data.php index f57849732a3..15b14b95ef7 100644 --- a/unit-tests/Tests/Version4/Data.php +++ b/unit-tests/Tests/Version4/Data.php @@ -12,7 +12,7 @@ defined( 'ABSPATH' ) || exit; /** * WC Tests API Data */ -class Data { +class Data extends \WC_REST_Unit_Test_Case { /** * Endpoints. @@ -21,6 +21,34 @@ class Data { */ protected $endpoint = '/wc/v4/data'; + /** + * User variable. + * + * @var WP_User + */ + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Setup test class. + */ + public function setUp() { + parent::setUp(); + wp_set_current_user( self::$user ); + } + /** * Test that the list of data endpoints includes download-ips. */ From 5630d2534a46caaa6211a429016489114562908f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 14 Jun 2019 16:55:47 +0100 Subject: [PATCH 140/440] Split out product schema from controller class --- ...-rest-product-variations-v2-controller.php | 8 - .../Version4/ProductVariations.php | 798 +------ src/Controllers/Version4/Products.php | 1872 ++--------------- .../Version4/Schema/ProductSchema.php | 1400 ++++++++++++ .../Schema/ProductVariationSchema.php | 680 ++++++ 5 files changed, 2277 insertions(+), 2481 deletions(-) create mode 100644 src/Controllers/Version4/Schema/ProductSchema.php create mode 100644 src/Controllers/Version4/Schema/ProductVariationSchema.php diff --git a/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php index d1fdb90e72f..8c1c4d1ad1d 100644 --- a/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php @@ -39,14 +39,6 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr */ protected $post_type = 'product_variation'; - /** - * Initialize product actions (parent). - */ - public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'add_product_id' ), 9, 2 ); - parent::__construct(); - } - /** * Register the routes for products. */ diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index 9d81af75af3..fd283f0ea2e 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use WooCommerce\RestApi\Controllers\Version4\Schema\ProductVariationSchema; + /** * REST API variations controller class. */ @@ -30,14 +32,6 @@ class ProductVariations extends Products { */ protected $post_type = 'product_variation'; - /** - * Initialize product actions (parent). - */ - public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'add_product_id' ), 9, 2 ); - parent::__construct(); - } - /** * Register the routes for products. */ @@ -138,6 +132,52 @@ class ProductVariations extends Products { ); } + /** + * Get the Variation's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = ProductVariationSchema::get_schema(); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + unset( + $params['in_stock'], + $params['type'], + $params['featured'], + $params['category'], + $params['tag'], + $params['shipping_class'], + $params['attribute'], + $params['attribute_term'] + ); + + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['search'] = array( + 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + /** * Get object. * @@ -178,57 +218,8 @@ class ProductVariations extends Products { * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = array( - 'id' => $object->get_id(), - 'name' => $object->get_name( $context ), - 'type' => $object->get_type(), - 'parent_id' => $object->get_parent_id( $context ), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), - 'description' => wc_format_content( $object->get_description() ), - 'permalink' => $object->get_permalink(), - 'sku' => $object->get_sku(), - 'price' => $object->get_price(), - 'regular_price' => $object->get_regular_price(), - 'sale_price' => $object->get_sale_price(), - 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), - 'on_sale' => $object->is_on_sale(), - 'status' => $object->get_status(), - 'purchasable' => $object->is_purchasable(), - 'virtual' => $object->is_virtual(), - 'downloadable' => $object->is_downloadable(), - 'downloads' => $this->get_downloads( $object ), - 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, - 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, - 'tax_status' => $object->get_tax_status(), - 'tax_class' => $object->get_tax_class(), - 'manage_stock' => $object->managing_stock(), - 'stock_quantity' => $object->get_stock_quantity(), - 'stock_status' => $object->get_stock_status(), - 'backorders' => $object->get_backorders(), - 'backorders_allowed' => $object->backorders_allowed(), - 'backordered' => $object->is_on_backorder(), - 'weight' => $object->get_weight(), - 'dimensions' => array( - 'length' => $object->get_length(), - 'width' => $object->get_width(), - 'height' => $object->get_height(), - ), - 'shipping_class' => $object->get_shipping_class(), - 'shipping_class_id' => $object->get_shipping_class_id(), - 'image' => $this->get_image( $object ), - 'attributes' => $this->get_attributes( $object ), - 'menu_order' => $object->get_menu_order(), - 'meta_data' => $object->get_meta_data(), - ); - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = ProductVariationSchema::object_to_schema( $object, $context ); $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); @@ -247,91 +238,6 @@ class ProductVariations extends Products { return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } - /** - * Get the image for a product variation. - * - * @param \WC_Product_Variation $variation Variation data. - * @return array - */ - protected function get_image( $variation ) { - if ( ! $variation->get_image_id() ) { - return; - } - - $attachment_id = $variation->get_image_id(); - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - return; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - return; - } - - if ( ! isset( $image ) ) { - return array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - } - - /** - * Set variation image. - * - * @throws \WC_REST_Exception REST API exceptions. - * - * @param \WC_Product_Variation $variation Variation instance. - * @param array $image Image data. - * @return \WC_Product_Variation - */ - protected function set_variation_image( $variation, $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $variation->get_id(), array( $image ) ) ) { - throw new \WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $variation->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: attachment ID */ - throw new \WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); - } - - $variation->set_image_id( $attachment_id ); - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); - } - - return $variation; - } - /** * Prepare objects query. * @@ -406,193 +312,7 @@ class ProductVariations extends Products { * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { - if ( isset( $request['id'] ) ) { - $variation = wc_get_product( absint( $request['id'] ) ); - } else { - $variation = new \WC_Product_Variation(); - } - - $variation->set_parent_id( absint( $request['product_id'] ) ); - - // Status. - if ( isset( $request['status'] ) ) { - $variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); - } - - // SKU. - if ( isset( $request['sku'] ) ) { - $variation->set_sku( wc_clean( $request['sku'] ) ); - } - - // Thumbnail. - if ( isset( $request['image'] ) ) { - if ( is_array( $request['image'] ) ) { - $variation = $this->set_variation_image( $variation, $request['image'] ); - } else { - $variation->set_image_id( '' ); - } - } - - // Virtual variation. - if ( isset( $request['virtual'] ) ) { - $variation->set_virtual( $request['virtual'] ); - } - - // Downloadable variation. - if ( isset( $request['downloadable'] ) ) { - $variation->set_downloadable( $request['downloadable'] ); - } - - // Downloads. - if ( $variation->get_downloadable() ) { - // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); - } - - // Download limit. - if ( isset( $request['download_limit'] ) ) { - $variation->set_download_limit( $request['download_limit'] ); - } - - // Download expiry. - if ( isset( $request['download_expiry'] ) ) { - $variation->set_download_expiry( $request['download_expiry'] ); - } - } - - // Shipping data. - $variation = $this->save_product_shipping_data( $variation, $request ); - - // Stock handling. - if ( isset( $request['manage_stock'] ) ) { - $variation->set_manage_stock( $request['manage_stock'] ); - } - - if ( isset( $request['stock_status'] ) ) { - $variation->set_stock_status( $request['stock_status'] ); - } - - if ( isset( $request['backorders'] ) ) { - $variation->set_backorders( $request['backorders'] ); - } - - if ( $variation->get_manage_stock() ) { - if ( isset( $request['stock_quantity'] ) ) { - $variation->set_stock_quantity( $request['stock_quantity'] ); - } elseif ( isset( $request['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); - $variation->set_stock_quantity( $stock_quantity ); - } - } else { - $variation->set_backorders( 'no' ); - $variation->set_stock_quantity( '' ); - } - - // Regular Price. - if ( isset( $request['regular_price'] ) ) { - $variation->set_regular_price( $request['regular_price'] ); - } - - // Sale Price. - if ( isset( $request['sale_price'] ) ) { - $variation->set_sale_price( $request['sale_price'] ); - } - - if ( isset( $request['date_on_sale_from'] ) ) { - $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); - } - - if ( isset( $request['date_on_sale_from_gmt'] ) ) { - $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); - } - - if ( isset( $request['date_on_sale_to'] ) ) { - $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); - } - - if ( isset( $request['date_on_sale_to_gmt'] ) ) { - $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); - } - - // Tax class. - if ( isset( $request['tax_class'] ) ) { - $variation->set_tax_class( $request['tax_class'] ); - } - - // Description. - if ( isset( $request['description'] ) ) { - $variation->set_description( wp_kses_post( $request['description'] ) ); - } - - // Update taxonomies. - if ( isset( $request['attributes'] ) ) { - $attributes = array(); - $parent = wc_get_product( $variation->get_parent_id() ); - - if ( ! $parent ) { - return new \WP_Error( - // Translators: %d parent ID. - "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $variation->get_parent_id() ), array( - 'status' => 404, - ) - ); - } - - $parent_attributes = $parent->get_attributes(); - - foreach ( $request['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { - continue; - } - - $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); - $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $attribute_value = $term->slug; - } else { - $attribute_value = sanitize_title( $attribute_value ); - } - } - - $attributes[ $attribute_key ] = $attribute_value; - } - - $variation->set_attributes( $attributes ); - } - - // Menu order. - if ( $request['menu_order'] ) { - $variation->set_menu_order( $request['menu_order'] ); - } - - // Meta data. - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } + $variation = ProductVariationSchema::schema_to_object( $request ); /** * Filters an object before it is inserted via the REST API. @@ -607,15 +327,6 @@ class ProductVariations extends Products { return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); } - /** - * Clear caches here so in sync with any new variations. - * - * @param \WC_Data $object Object data. - */ - public function clear_transients( $object ) { - wc_delete_product_transients( $object->get_parent_id() ); - wp_cache_delete( 'product-' . $object->get_parent_id(), 'products' ); - } /** * Delete a variation. @@ -779,413 +490,4 @@ class ProductVariations extends Products { ); return $links; } - - /** - * Get the Variation's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product parent name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'variation', - 'enum' => array( 'variation' ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Variation status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_keys( get_post_statuses() ), - 'context' => array( 'view', 'edit' ), - ), - 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - unset( - $params['in_stock'], - $params['type'], - $params['featured'], - $params['category'], - $params['tag'], - $params['shipping_class'], - $params['attribute'], - $params['attribute_term'] - ); - - $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['search'] = array( - 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } } diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 96301be217b..87e65aea4fe 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use WooCommerce\RestApi\Controllers\Version4\Schema\ProductSchema; + /** * REST API Products controller class. */ @@ -38,10 +40,149 @@ class Products extends AbstractObjectsController { protected $hierarchical = true; /** - * Initialize product actions. + * Get the Product's schema, conforming to JSON Schema. + * + * @return array */ - public function __construct() { - add_action( "woocommerce_rest_insert_{$this->post_type}_object", array( $this, 'clear_transients' ) ); + public function get_item_schema() { + return $this->add_additional_fields_schema( ProductSchema::get_schema() ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['slug'] = array( + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['type'] = array( + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_types() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['sku'] = array( + 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['featured'] = array( + 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['category'] = array( + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['tag'] = array( + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['shipping_class'] = array( + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['attribute'] = array( + 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['attribute_term'] = array( + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + if ( wc_tax_enabled() ) { + $params['tax_class'] = array( + 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + } + + $params['on_sale'] = array( + 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['min_price'] = array( + 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['max_price'] = array( + 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['low_in_stock'] = array( + 'description' => __( 'Limit result set to products that are low or out of stock.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + ); + + $params['search'] = array( + 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); + + return $params; } /** @@ -66,19 +207,8 @@ class Products extends AbstractObjectsController { * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->get_product_data( $object, $context ); - - // Add variations to variable products. - if ( $object->is_type( 'variable' ) && $object->has_child() ) { - $data['variations'] = $object->get_children(); - } - - // Add grouped products data. - if ( $object->is_type( 'grouped' ) && $object->has_child() ) { - $data['grouped_products'] = $object->get_children(); - } - + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = ProductSchema::object_to_schema( $object, $context ); $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); @@ -105,394 +235,7 @@ class Products extends AbstractObjectsController { * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - - // Type is the most important part here because we need to be using the correct class and methods. - if ( isset( $request['type'] ) ) { - $classname = \WC_Product_Factory::get_classname_from_product_type( $request['type'] ); - - if ( ! class_exists( $classname ) ) { - $classname = 'WC_Product_Simple'; - } - - $product = new $classname( $id ); - } elseif ( isset( $request['id'] ) ) { - $product = wc_get_product( $id ); - } else { - $product = new \WC_Product_Simple(); - } - - if ( 'variation' === $product->get_type() ) { - return new \WP_Error( - "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), - array( - 'status' => 404, - ) - ); - } - - // Post title. - if ( isset( $request['name'] ) ) { - $product->set_name( wp_filter_post_kses( $request['name'] ) ); - } - - // Post content. - if ( isset( $request['description'] ) ) { - $product->set_description( wp_filter_post_kses( $request['description'] ) ); - } - - // Post excerpt. - if ( isset( $request['short_description'] ) ) { - $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); - } - - // Post status. - if ( isset( $request['status'] ) ) { - $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); - } - - // Post slug. - if ( isset( $request['slug'] ) ) { - $product->set_slug( $request['slug'] ); - } - - // Menu order. - if ( isset( $request['menu_order'] ) ) { - $product->set_menu_order( $request['menu_order'] ); - } - - // Comment status. - if ( isset( $request['reviews_allowed'] ) ) { - $product->set_reviews_allowed( $request['reviews_allowed'] ); - } - - // Virtual. - if ( isset( $request['virtual'] ) ) { - $product->set_virtual( $request['virtual'] ); - } - - // Tax status. - if ( isset( $request['tax_status'] ) ) { - $product->set_tax_status( $request['tax_status'] ); - } - - // Tax Class. - if ( isset( $request['tax_class'] ) ) { - $product->set_tax_class( $request['tax_class'] ); - } - - // Catalog Visibility. - if ( isset( $request['catalog_visibility'] ) ) { - $product->set_catalog_visibility( $request['catalog_visibility'] ); - } - - // Purchase Note. - if ( isset( $request['purchase_note'] ) ) { - $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); - } - - // Featured Product. - if ( isset( $request['featured'] ) ) { - $product->set_featured( $request['featured'] ); - } - - // Shipping data. - $product = $this->save_product_shipping_data( $product, $request ); - - // SKU. - if ( isset( $request['sku'] ) ) { - $product->set_sku( wc_clean( $request['sku'] ) ); - } - - // Attributes. - if ( isset( $request['attributes'] ) ) { - $attributes = array(); - - foreach ( $request['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = wc_clean( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( $attribute_id ) { - - if ( isset( $attribute['options'] ) ) { - $options = $attribute['options']; - - if ( ! is_array( $attribute['options'] ) ) { - // Text based attributes - Posted values are term names. - $options = explode( WC_DELIMITER, $options ); - } - - $values = array_map( 'wc_sanitize_term_text_based', $options ); - $values = array_filter( $values, 'strlen' ); - } else { - $values = array(); - } - - if ( ! empty( $values ) ) { - // Add attribute to array, but don't set values. - $attribute_object = new \WC_Product_Attribute(); - $attribute_object->set_id( $attribute_id ); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } elseif ( isset( $attribute['options'] ) ) { - // Custom attribute - Add attribute to array and set the values. - if ( is_array( $attribute['options'] ) ) { - $values = $attribute['options']; - } else { - $values = explode( WC_DELIMITER, $attribute['options'] ); - } - $attribute_object = new \WC_Product_Attribute(); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } - $product->set_attributes( $attributes ); - } - - // Sales and prices. - if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { - $product->set_regular_price( '' ); - $product->set_sale_price( '' ); - $product->set_date_on_sale_to( '' ); - $product->set_date_on_sale_from( '' ); - $product->set_price( '' ); - } else { - // Regular Price. - if ( isset( $request['regular_price'] ) ) { - $product->set_regular_price( $request['regular_price'] ); - } - - // Sale Price. - if ( isset( $request['sale_price'] ) ) { - $product->set_sale_price( $request['sale_price'] ); - } - - if ( isset( $request['date_on_sale_from'] ) ) { - $product->set_date_on_sale_from( $request['date_on_sale_from'] ); - } - - if ( isset( $request['date_on_sale_from_gmt'] ) ) { - $product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); - } - - if ( isset( $request['date_on_sale_to'] ) ) { - $product->set_date_on_sale_to( $request['date_on_sale_to'] ); - } - - if ( isset( $request['date_on_sale_to_gmt'] ) ) { - $product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); - } - } - - // Product parent ID. - if ( isset( $request['parent_id'] ) ) { - $product->set_parent_id( $request['parent_id'] ); - } - - // Sold individually. - if ( isset( $request['sold_individually'] ) ) { - $product->set_sold_individually( $request['sold_individually'] ); - } - - // Stock status; stock_status has priority over in_stock. - if ( isset( $request['stock_status'] ) ) { - $stock_status = $request['stock_status']; - } else { - $stock_status = $product->get_stock_status(); - } - - // Stock data. - if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { - // Manage stock. - if ( isset( $request['manage_stock'] ) ) { - $product->set_manage_stock( $request['manage_stock'] ); - } - - // Backorders. - if ( isset( $request['backorders'] ) ) { - $product->set_backorders( $request['backorders'] ); - } - - if ( $product->is_type( 'grouped' ) ) { - $product->set_manage_stock( false ); - $product->set_backorders( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( $stock_status ); - } elseif ( $product->is_type( 'external' ) ) { - $product->set_manage_stock( false ); - $product->set_backorders( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( 'instock' ); - } elseif ( $product->get_manage_stock() ) { - // Stock status is always determined by children so sync later. - if ( ! $product->is_type( 'variable' ) ) { - $product->set_stock_status( $stock_status ); - } - - // Stock quantity. - if ( isset( $request['stock_quantity'] ) ) { - $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); - } elseif ( isset( $request['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); - $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); - } - } else { - // Don't manage stock. - $product->set_manage_stock( false ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( $stock_status ); - } - } elseif ( ! $product->is_type( 'variable' ) ) { - $product->set_stock_status( $stock_status ); - } - - // Upsells. - if ( isset( $request['upsell_ids'] ) ) { - $upsells = array(); - $ids = $request['upsell_ids']; - - if ( ! empty( $ids ) ) { - foreach ( $ids as $id ) { - if ( $id && $id > 0 ) { - $upsells[] = $id; - } - } - } - - $product->set_upsell_ids( $upsells ); - } - - // Cross sells. - if ( isset( $request['cross_sell_ids'] ) ) { - $crosssells = array(); - $ids = $request['cross_sell_ids']; - - if ( ! empty( $ids ) ) { - foreach ( $ids as $id ) { - if ( $id && $id > 0 ) { - $crosssells[] = $id; - } - } - } - - $product->set_cross_sell_ids( $crosssells ); - } - - // Product categories. - if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { - $product = $this->save_taxonomy_terms( $product, $request['categories'] ); - } - - // Product tags. - if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { - $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); - } - - // Downloadable. - if ( isset( $request['downloadable'] ) ) { - $product->set_downloadable( $request['downloadable'] ); - } - - // Downloadable options. - if ( $product->get_downloadable() ) { - - // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - $product = $this->save_downloadable_files( $product, $request['downloads'] ); - } - - // Download limit. - if ( isset( $request['download_limit'] ) ) { - $product->set_download_limit( $request['download_limit'] ); - } - - // Download expiry. - if ( isset( $request['download_expiry'] ) ) { - $product->set_download_expiry( $request['download_expiry'] ); - } - } - - // Product url and button text for external products. - if ( $product->is_type( 'external' ) ) { - if ( isset( $request['external_url'] ) ) { - $product->set_product_url( $request['external_url'] ); - } - - if ( isset( $request['button_text'] ) ) { - $product->set_button_text( $request['button_text'] ); - } - } - - // Save default attributes for variable products. - if ( $product->is_type( 'variable' ) ) { - $product = $this->save_default_attributes( $product, $request ); - } - - // Set children for a grouped product. - if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { - $product->set_children( $request['grouped_products'] ); - } - - // Check for featured/gallery images, upload it and set it. - if ( isset( $request['images'] ) ) { - $product = $this->set_product_images( $product, $request['images'] ); - } - - // Allow set meta_data. - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - - if ( ! empty( $request['date_created'] ) ) { - $date = rest_parse_date( $request['date_created'] ); - - if ( $date ) { - $product->set_date_created( $date ); - } - } - - if ( ! empty( $request['date_created_gmt'] ) ) { - $date = rest_parse_date( $request['date_created_gmt'], true ); - - if ( $date ) { - $product->set_date_created( $date ); - } - } - - if ( ! empty( $request['search'] ) ) { - $args['search'] = trim( $request['search'] ); - unset( $args['s'] ); - } - - if ( ! empty( $request['low_in_stock'] ) ) { - $args['low_in_stock'] = $request['low_in_stock']; - $args['post_type'] = array( 'product', 'product_variation' ); - } + $product = ProductSchema::schema_to_object( $request ); /** * Filters an object before it is inserted via the REST API. @@ -716,338 +459,6 @@ class Products extends AbstractObjectsController { return $args; } - /** - * Get the downloads for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $product Product instance. - * - * @return array - */ - protected function get_downloads( $product ) { - $downloads = array(); - - if ( $product->is_downloadable() ) { - foreach ( $product->get_downloads() as $file_id => $file ) { - $downloads[] = array( - 'id' => $file_id, // MD5 hash. - 'name' => $file['name'], - 'file' => $file['file'], - ); - } - } - - return $downloads; - } - - /** - * Get taxonomy terms. - * - * @param \WC_Product $product Product instance. - * @param string $taxonomy Taxonomy slug. - * - * @return array - */ - protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { - $terms = array(); - - foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { - $terms[] = array( - 'id' => $term->term_id, - 'name' => $term->name, - 'slug' => $term->slug, - ); - } - - return $terms; - } - - /** - * Get the images for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $product Product instance. - * @return array - */ - protected function get_images( $product ) { - $images = array(); - $attachment_ids = array(); - - // Add featured image. - if ( $product->get_image_id() ) { - $attachment_ids[] = $product->get_image_id(); - } - - // Add gallery images. - $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); - - // Build image data. - foreach ( $attachment_ids as $attachment_id ) { - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - continue; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - continue; - } - - $images[] = array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - - return $images; - } - - /** - * Get attribute taxonomy label. - * - * @param string $name Taxonomy name. - * - * @deprecated 3.0.0 - * @return string - */ - protected function get_attribute_taxonomy_label( $name ) { - $tax = get_taxonomy( $name ); - $labels = get_taxonomy_labels( $tax ); - - return $labels->singular_name; - } - - /** - * Get product attribute taxonomy name. - * - * @param string $slug Taxonomy name. - * @param \WC_Product $product Product data. - * - * @since 3.0.0 - * @return string - */ - protected function get_attribute_taxonomy_name( $slug, $product ) { - // Format slug so it matches attributes of the product. - $slug = wc_attribute_taxonomy_slug( $slug ); - $attributes = $product->get_attributes(); - $attribute = false; - - // pa_ attributes. - if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { - $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; - } elseif ( isset( $attributes[ $slug ] ) ) { - $attribute = $attributes[ $slug ]; - } - - if ( ! $attribute ) { - return $slug; - } - - // Taxonomy attribute name. - if ( $attribute->is_taxonomy() ) { - $taxonomy = $attribute->get_taxonomy_object(); - return $taxonomy->attribute_label; - } - - // Custom product attribute name. - return $attribute->get_name(); - } - - /** - * Get default attributes. - * - * @param \WC_Product $product Product instance. - * - * @return array - */ - protected function get_default_attributes( $product ) { - $default = array(); - - if ( $product->is_type( 'variable' ) ) { - foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { - if ( 0 === strpos( $key, 'pa_' ) ) { - $default[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $key ), - 'name' => $this->get_attribute_taxonomy_name( $key, $product ), - 'option' => $value, - ); - } else { - $default[] = array( - 'id' => 0, - 'name' => $this->get_attribute_taxonomy_name( $key, $product ), - 'option' => $value, - ); - } - } - } - - return $default; - } - - /** - * Get attribute options. - * - * @param int $product_id Product ID. - * @param array $attribute Attribute data. - * - * @return array - */ - protected function get_attribute_options( $product_id, $attribute ) { - if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { - return wc_get_product_terms( - $product_id, - $attribute['name'], - array( - 'fields' => 'names', - ) - ); - } elseif ( isset( $attribute['value'] ) ) { - return array_map( 'trim', explode( '|', $attribute['value'] ) ); - } - - return array(); - } - - /** - * Get the attributes for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $product Product instance. - * - * @return array - */ - protected function get_attributes( $product ) { - $attributes = array(); - - if ( $product->is_type( 'variation' ) ) { - $_product = wc_get_product( $product->get_parent_id() ); - foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { - $name = str_replace( 'attribute_', '', $attribute_name ); - - if ( empty( $attribute ) && '0' !== $attribute ) { - continue; - } - - // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. - if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { - $option_term = get_term_by( 'slug', $attribute, $name ); - $attributes[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $name ), - 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), - 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, - ); - } else { - $attributes[] = array( - 'id' => 0, - 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), - 'option' => $attribute, - ); - } - } - } else { - foreach ( $product->get_attributes() as $attribute ) { - $attributes[] = array( - 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, - 'name' => $this->get_attribute_taxonomy_name( $attribute['name'], $product ), - 'position' => (int) $attribute['position'], - 'visible' => (bool) $attribute['is_visible'], - 'variation' => (bool) $attribute['is_variation'], - 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), - ); - } - } - - return $attributes; - } - - /** - * Get product data. - * - * @param \WC_Product $product Product instance. - * @param string $context Request context. - * Options: 'view' and 'edit'. - * - * @return array - */ - protected function get_product_data( $product, $context = 'view' ) { - $data = array( - 'id' => $product->get_id(), - 'name' => $product->get_name( $context ), - 'slug' => $product->get_slug( $context ), - 'permalink' => $product->get_permalink(), - 'date_created' => wc_rest_prepare_date_response( $product->get_date_created( $context ), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $product->get_date_created( $context ) ), - 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified( $context ), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $product->get_date_modified( $context ) ), - 'type' => $product->get_type(), - 'status' => $product->get_status( $context ), - 'featured' => $product->is_featured(), - 'catalog_visibility' => $product->get_catalog_visibility( $context ), - 'description' => 'view' === $context ? wpautop( do_shortcode( $product->get_description() ) ) : $product->get_description( $context ), - 'short_description' => 'view' === $context ? apply_filters( 'woocommerce_short_description', $product->get_short_description() ) : $product->get_short_description( $context ), - 'sku' => $product->get_sku( $context ), - 'price' => $product->get_price( $context ), - 'regular_price' => $product->get_regular_price( $context ), - 'sale_price' => $product->get_sale_price( $context ) ? $product->get_sale_price( $context ) : '', - 'date_on_sale_from' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ) ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ) ), - 'price_html' => $product->get_price_html(), - 'on_sale' => $product->is_on_sale( $context ), - 'purchasable' => $product->is_purchasable(), - 'total_sales' => $product->get_total_sales( $context ), - 'virtual' => $product->is_virtual(), - 'downloadable' => $product->is_downloadable(), - 'downloads' => $this->get_downloads( $product ), - 'download_limit' => $product->get_download_limit( $context ), - 'download_expiry' => $product->get_download_expiry( $context ), - 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url( $context ) : '', - 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text( $context ) : '', - 'tax_status' => $product->get_tax_status( $context ), - 'tax_class' => $product->get_tax_class( $context ), - 'manage_stock' => $product->managing_stock(), - 'stock_quantity' => $product->get_stock_quantity( $context ), - 'stock_status' => $product->get_stock_status( $context ), - 'backorders' => $product->get_backorders( $context ), - 'backorders_allowed' => $product->backorders_allowed(), - 'backordered' => $product->is_on_backorder(), - 'sold_individually' => $product->is_sold_individually(), - 'weight' => $product->get_weight( $context ), - 'dimensions' => array( - 'length' => $product->get_length( $context ), - 'width' => $product->get_width( $context ), - 'height' => $product->get_height( $context ), - ), - 'shipping_required' => $product->needs_shipping(), - 'shipping_taxable' => $product->is_shipping_taxable(), - 'shipping_class' => $product->get_shipping_class(), - 'shipping_class_id' => $product->get_shipping_class_id( $context ), - 'reviews_allowed' => $product->get_reviews_allowed( $context ), - 'average_rating' => 'view' === $context ? wc_format_decimal( $product->get_average_rating(), 2 ) : $product->get_average_rating( $context ), - 'rating_count' => $product->get_rating_count(), - 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), - 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids( $context ) ), - 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids( $context ) ), - 'parent_id' => $product->get_parent_id( $context ), - 'purchase_note' => 'view' === $context ? wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ) : $product->get_purchase_note( $context ), - 'categories' => $this->get_taxonomy_terms( $product ), - 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), - 'images' => $this->get_images( $product ), - 'attributes' => $this->get_attributes( $product ), - 'default_attributes' => $this->get_default_attributes( $product ), - 'variations' => array(), - 'grouped_products' => array(), - 'menu_order' => $product->get_menu_order( $context ), - 'meta_data' => $product->get_meta_data(), - ); - - return $data; - } - /** * Prepare links for the request. * @@ -1075,243 +486,6 @@ class Products extends AbstractObjectsController { return $links; } - /** - * Set product images. - * - * @throws \WC_REST_Exception REST API exceptions. - * - * @param \WC_Product $product Product instance. - * @param array $images Images data. - * @return \WC_Product - */ - protected function set_product_images( $product, $images ) { - $images = is_array( $images ) ? array_filter( $images ) : array(); - - if ( ! empty( $images ) ) { - $gallery = array(); - - foreach ( $images as $index => $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { - throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); - } else { - continue; - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: image ID */ - throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); - } - - $featured_image = $product->get_image_id(); - - if ( 0 === $index ) { - $product->set_image_id( $attachment_id ); - } else { - $gallery[] = $attachment_id; - } - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); - } - } - - $product->set_gallery_image_ids( $gallery ); - } else { - $product->set_image_id( '' ); - $product->set_gallery_image_ids( array() ); - } - - return $product; - } - - /** - * Save product shipping data. - * - * @param \WC_Product $product Product instance. - * @param array $data Shipping data. - * - * @return \WC_Product - */ - protected function save_product_shipping_data( $product, $data ) { - // Virtual. - if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { - $product->set_weight( '' ); - $product->set_height( '' ); - $product->set_length( '' ); - $product->set_width( '' ); - } else { - if ( isset( $data['weight'] ) ) { - $product->set_weight( $data['weight'] ); - } - - // Height. - if ( isset( $data['dimensions']['height'] ) ) { - $product->set_height( $data['dimensions']['height'] ); - } - - // Width. - if ( isset( $data['dimensions']['width'] ) ) { - $product->set_width( $data['dimensions']['width'] ); - } - - // Length. - if ( isset( $data['dimensions']['length'] ) ) { - $product->set_length( $data['dimensions']['length'] ); - } - } - - // Shipping class. - if ( isset( $data['shipping_class'] ) ) { - $data_store = $product->get_data_store(); - $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); - $product->set_shipping_class_id( $shipping_class_id ); - } - - return $product; - } - - /** - * Save downloadable files. - * - * @param \WC_Product $product Product instance. - * @param array $downloads Downloads data. - * @param int $deprecated Deprecated since 3.0. - * - * @return \WC_Product - */ - protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { - if ( $deprecated ) { - wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); - } - - $files = array(); - foreach ( $downloads as $key => $file ) { - if ( empty( $file['file'] ) ) { - continue; - } - - $download = new \WC_Product_Download(); - $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); - $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); - $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); - $files[] = $download; - } - $product->set_downloads( $files ); - - return $product; - } - - /** - * Save taxonomy terms. - * - * @param \WC_Product $product Product instance. - * @param array $terms Terms data. - * @param string $taxonomy Taxonomy name. - * - * @return \WC_Product - */ - protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { - $term_ids = wp_list_pluck( $terms, 'id' ); - - if ( 'cat' === $taxonomy ) { - $product->set_category_ids( $term_ids ); - } elseif ( 'tag' === $taxonomy ) { - $product->set_tag_ids( $term_ids ); - } - - return $product; - } - - /** - * Save default attributes. - * - * @param \WC_Product $product Product instance. - * @param \WP_REST_Request $request Request data. - * @return \WC_Product - */ - protected function save_default_attributes( $product, $request ) { - if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { - - $attributes = $product->get_attributes(); - $default_attributes = array(); - - foreach ( $request['default_attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( isset( $attributes[ $attribute_name ] ) ) { - $_attribute = $attributes[ $attribute_name ]; - - if ( $_attribute['is_variation'] ) { - $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( ! empty( $_attribute['is_taxonomy'] ) ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $value = $term->slug; - } else { - $value = sanitize_title( $value ); - } - } - - if ( $value ) { - $default_attributes[ $attribute_name ] = $value; - } - } - } - } - - $product->set_default_attributes( $default_attributes ); - } - - return $product; - } - - /** - * Clear caches here so in sync with any new variations/children. - * - * @param \WC_Data $object Object data. - */ - public function clear_transients( $object ) { - wc_delete_product_transients( $object->get_id() ); - wp_cache_delete( 'product-' . $object->get_id(), 'products' ); - } - /** * Delete a single item. * @@ -1439,756 +613,4 @@ class Products extends AbstractObjectsController { return $response; } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit', 'embed' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit', 'embed' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'simple', - 'enum' => array_keys( wc_get_product_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), - 'context' => array( 'view', 'edit' ), - ), - 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'visible', - 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Product description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'images' => array( - 'description' => __( 'List of images.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit', 'embed' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'integer', - ), - 'readonly' => true, - ), - 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['status'] = array( - 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_types() ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['sku'] = array( - 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['featured'] = array( - 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), - 'type' => 'boolean', - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - if ( wc_tax_enabled() ) { - $params['tax_class'] = array( - 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - } - - $params['on_sale'] = array( - 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), - 'type' => 'boolean', - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['min_price'] = array( - 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['max_price'] = array( - 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['low_in_stock'] = array( - 'description' => __( 'Limit result set to products that are low or out of stock.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - ); - - $params['search'] = array( - 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); - - return $params; - } } diff --git a/src/Controllers/Version4/Schema/ProductSchema.php b/src/Controllers/Version4/Schema/ProductSchema.php new file mode 100644 index 00000000000..2bf82a0b96b --- /dev/null +++ b/src/Controllers/Version4/Schema/ProductSchema.php @@ -0,0 +1,1400 @@ + 'http://json-schema.org/draft-04/schema#', + 'title' => 'product', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit', 'embed' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit', 'embed' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wc_clean', + ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_kses_post', + ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit', 'embed' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + 'readonly' => true, + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $schema; + } + + /** + * Convert object to match data in the schema. + * + * @param \WC_Product $object Product instance. + * @param string $context Request context. Options: 'view' and 'edit'. + * @return array + */ + public static function object_to_schema( $object, $context ) { + $data = array( + 'id' => $object->get_id(), + 'name' => $object->get_name( $context ), + 'slug' => $object->get_slug( $context ), + 'permalink' => $object->get_permalink(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created( $context ), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created( $context ) ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified( $context ), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified( $context ) ), + 'type' => $object->get_type(), + 'status' => $object->get_status( $context ), + 'featured' => $object->is_featured(), + 'catalog_visibility' => $object->get_catalog_visibility( $context ), + 'description' => 'view' === $context ? wpautop( do_shortcode( $object->get_description() ) ) : $object->get_description( $context ), + 'short_description' => 'view' === $context ? apply_filters( 'woocommerce_short_description', $object->get_short_description() ) : $object->get_short_description( $context ), + 'sku' => $object->get_sku( $context ), + 'price' => $object->get_price( $context ), + 'regular_price' => $object->get_regular_price( $context ), + 'sale_price' => $object->get_sale_price( $context ) ? $object->get_sale_price( $context ) : '', + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ) ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ) ), + 'price_html' => $object->get_price_html(), + 'on_sale' => $object->is_on_sale( $context ), + 'purchasable' => $object->is_purchasable(), + 'total_sales' => $object->get_total_sales( $context ), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => self::get_downloads( $object ), + 'download_limit' => $object->get_download_limit( $context ), + 'download_expiry' => $object->get_download_expiry( $context ), + 'external_url' => $object->is_type( 'external' ) ? $object->get_product_url( $context ) : '', + 'button_text' => $object->is_type( 'external' ) ? $object->get_button_text( $context ) : '', + 'tax_status' => $object->get_tax_status( $context ), + 'tax_class' => $object->get_tax_class( $context ), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity( $context ), + 'stock_status' => $object->get_stock_status( $context ), + 'backorders' => $object->get_backorders( $context ), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'sold_individually' => $object->is_sold_individually(), + 'weight' => $object->get_weight( $context ), + 'dimensions' => array( + 'length' => $object->get_length( $context ), + 'width' => $object->get_width( $context ), + 'height' => $object->get_height( $context ), + ), + 'shipping_required' => $object->needs_shipping(), + 'shipping_taxable' => $object->is_shipping_taxable(), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id( $context ), + 'reviews_allowed' => $object->get_reviews_allowed( $context ), + 'average_rating' => 'view' === $context ? wc_format_decimal( $object->get_average_rating(), 2 ) : $object->get_average_rating( $context ), + 'rating_count' => $object->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $object->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $object->get_upsell_ids( $context ) ), + 'cross_sell_ids' => array_map( 'absint', $object->get_cross_sell_ids( $context ) ), + 'parent_id' => $object->get_parent_id( $context ), + 'purchase_note' => 'view' === $context ? wpautop( do_shortcode( wp_kses_post( $object->get_purchase_note() ) ) ) : $object->get_purchase_note( $context ), + 'categories' => self::get_taxonomy_terms( $object ), + 'tags' => self::get_taxonomy_terms( $object, 'tag' ), + 'images' => self::get_images( $object ), + 'attributes' => self::get_attributes( $object ), + 'default_attributes' => self::get_default_attributes( $object ), + 'variations' => array(), + 'grouped_products' => array(), + 'menu_order' => $object->get_menu_order( $context ), + 'meta_data' => $object->get_meta_data(), + ); + + // Add variations to variable products. + if ( $object->is_type( 'variable' ) && $object->has_child() ) { + $data['variations'] = $object->get_children(); + } + + // Add grouped products data. + if ( $object->is_type( 'grouped' ) && $object->has_child() ) { + $data['grouped_products'] = $object->get_children(); + } + + return $data; + } + + /** + * Take data in the format of the schema and convert to a product object. + * + * @param \WP_REST_Request $request Request object. + * @return \WP_Error|\WC_Product + */ + public static function schema_to_object( $request ) { + $id = isset( $request['id'] ) ? (int) $request['id'] : 0; + + if ( isset( $request['type'] ) ) { + $classname = '\\' . \WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + + if ( ! class_exists( $classname ) ) { + $classname = '\\WC_Product_Simple'; + } + + $object = new $classname( $id ); + } elseif ( isset( $request['id'] ) ) { + $object = wc_get_product( $id ); + } else { + $object = new \WC_Product_Simple(); + } + + if ( $object->is_type( 'variation' ) ) { + return new \WP_Error( + 'woocommerce_rest_invalid_product_id', + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + + self::set_object_data( $object, $request ); + + return $object; + } + + /** + * Set object data from a request. + * + * @param \WC_Product $object Product object. + * @param \WP_REST_Request $request Request object. + */ + protected static function set_object_data( &$object, $request ) { + $props_to_set = [ + 'name', + 'sku', + 'description', + 'short_description', + 'slug', + 'menu_order', + 'reviews_allowed', + 'virtual', + 'tax_status', + 'tax_class', + 'catalog_visibility', + 'purchase_note', + 'status', + 'featured', + 'regular_price', + 'sale_price', + 'date_on_sale_from', + 'date_on_sale_from_gmt', + 'date_on_sale_to', + 'date_on_sale_to_gmt', + 'parent_id', + 'sold_individually', + 'manage_stock', + 'backorders', + 'stock_status', + 'stock_quantity', + 'downloadable', + 'button_text', + 'download_limit', + 'download_expiry', + ]; + + foreach ( $props_to_set as $prop ) { + if ( isset( $request[ $prop ] ) && is_callable( array( $object, "set_$prop" ) ) ) { + $object->{"set_$prop"}( $request[ $prop ] ); + } + } + + if ( isset( $request['external_url'] ) && is_callable( array( $object, 'set_product_url' ) ) ) { + $object->set_product_url( $request['external_url'] ); + } + + if ( ! empty( $request['date_created'] ) ) { + $date = rest_parse_date( $request['date_created'] ); + + if ( $date ) { + $object->set_date_created( $date ); + } + } + + if ( ! empty( $request['date_created_gmt'] ) ) { + $date = rest_parse_date( $request['date_created_gmt'], true ); + + if ( $date ) { + $object->set_date_created( $date ); + } + } + + if ( isset( $request['upsell_ids'] ) ) { + $object->set_upsell_ids( wp_parse_id_list( $request['upsell_ids'] ) ); + } + + if ( isset( $request['cross_sell_ids'] ) ) { + $object->set_cross_sell_ids( wp_parse_id_list( $request['cross_sell_ids'] ) ); + } + + // Set children for a grouped product. + if ( $object->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { + $object->set_children( $request['grouped_products'] ); + } + + // Allow set meta_data. + if ( isset( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + // Save default attributes for variable products. + if ( $object->is_type( 'variable' ) && isset( $request['default_attributes'] ) ) { + self::set_default_attributes( $object, $request['default_attributes'] ); + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + self::set_images( $object, $request['images'] ); + } + + // Product categories. + if ( isset( $request['categories'] ) ) { + self::set_taxonomy_terms( $object, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) ) { + self::set_taxonomy_terms( $object, $request['tags'], 'tag' ); + } + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + self::set_downloadable_files( $object, $request['downloads'] ); + } + + if ( isset( $request['attributes'] ) ) { + self::set_attributes( $object, $request['attributes'] ); + } + + self::set_shipping_data( $object, $request ); + + return $object; + } + + /** + * Get the downloads for a product or product variation. + * + * @param \WC_Product|\WC_Product_Variation $object Product instance. + * + * @return array + */ + protected static function get_downloads( $object ) { + $downloads = array(); + + if ( $object->is_downloadable() ) { + foreach ( $object->get_downloads() as $file_id => $file ) { + $downloads[] = array( + 'id' => $file_id, // MD5 hash. + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get taxonomy terms. + * + * @param \WC_Product $object Product instance. + * @param string $taxonomy Taxonomy slug. + * + * @return array + */ + protected static function get_taxonomy_terms( $object, $taxonomy = 'cat' ) { + $terms = array(); + + foreach ( wc_get_object_terms( $object->get_id(), 'product_' . $taxonomy ) as $term ) { + $terms[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + ); + } + + return $terms; + } + + /** + * Get the images for a product or product variation. + * + * @param \WC_Product|\WC_Product_Variation $object Product instance. + * @return array + */ + protected static function get_images( $object ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( $object->get_image_id() ) { + $attachment_ids[] = $object->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $object->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + + return $images; + } + + /** + * Get product attribute taxonomy name. + * + * @param string $slug Taxonomy name. + * @param \WC_Product $object Product data. + * + * @since 3.0.0 + * @return string + */ + protected static function get_attribute_taxonomy_name( $slug, $object ) { + // Format slug so it matches attributes of the product. + $slug = wc_attribute_taxonomy_slug( $slug ); + $attributes = $object->get_attributes(); + $attribute = false; + + // pa_ attributes. + if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { + $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; + } elseif ( isset( $attributes[ $slug ] ) ) { + $attribute = $attributes[ $slug ]; + } + + if ( ! $attribute ) { + return $slug; + } + + // Taxonomy attribute name. + if ( $attribute->is_taxonomy() ) { + $taxonomy = $attribute->get_taxonomy_object(); + return $taxonomy->attribute_label; + } + + // Custom product attribute name. + return $attribute->get_name(); + } + + /** + * Get default attributes. + * + * @param \WC_Product $object Product instance. + * + * @return array + */ + protected static function get_default_attributes( $object ) { + $default = array(); + + if ( $object->is_type( 'variable' ) ) { + foreach ( array_filter( (array) $object->get_default_attributes(), 'strlen' ) as $key => $value ) { + if ( 0 === strpos( $key, 'pa_' ) ) { + $default[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $key ), + 'name' => self::get_attribute_taxonomy_name( $key, $object ), + 'option' => $value, + ); + } else { + $default[] = array( + 'id' => 0, + 'name' => self::get_attribute_taxonomy_name( $key, $object ), + 'option' => $value, + ); + } + } + } + + return $default; + } + + /** + * Get attribute options. + * + * @param int $object_id Product ID. + * @param array $attribute Attribute data. + * + * @return array + */ + protected static function get_attribute_options( $object_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( + $object_id, + $attribute['name'], + array( + 'fields' => 'names', + ) + ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation. + * + * @param \WC_Product|\WC_Product_Variation $object Product instance. + * + * @return array + */ + protected static function get_attributes( $object ) { + $attributes = array(); + + if ( $object->is_type( 'variation' ) ) { + $_product = wc_get_product( $object->get_parent_id() ); + foreach ( $object->get_variation_attributes() as $attribute_name => $attribute ) { + $name = str_replace( 'attribute_', '', $attribute_name ); + + if ( empty( $attribute ) && '0' !== $attribute ) { + continue; + } + + // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. + if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $name ); + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $name ), + 'name' => self::get_attribute_taxonomy_name( $name, $_product ), + 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => self::get_attribute_taxonomy_name( $name, $_product ), + 'option' => $attribute, + ); + } + } + } else { + foreach ( $object->get_attributes() as $attribute ) { + $attributes[] = array( + 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, + 'name' => self::get_attribute_taxonomy_name( $attribute['name'], $object ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => self::get_attribute_options( $object->get_id(), $attribute ), + ); + } + } + + return $attributes; + } + + /** + * Set product object's attributes. + * + * @param \WC_Product $object Product object. + * @param array $raw_attributes Attribute data from request. + */ + protected static function set_attributes( &$object, $raw_attributes ) { + $attributes = array(); + + foreach ( $raw_attributes as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new \WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new \WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $object->set_attributes( $attributes ); + } + + /** + * Set product images. + * + * @throws \WC_REST_Exception REST API exceptions. + * + * @param \WC_Product $object Product instance. + * @param array $images Images data. + */ + protected static function set_images( &$object, $images ) { + $images = is_array( $images ) ? array_filter( $images ) : array(); + + if ( ! empty( $images ) ) { + $gallery = array(); + + foreach ( $images as $index => $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), $images ) ) { + throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: image ID */ + throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $featured_image = $object->get_image_id(); + + if ( 0 === $index ) { + $object->set_image_id( $attachment_id ); + } else { + $gallery[] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + } + + $object->set_gallery_image_ids( $gallery ); + } else { + $object->set_image_id( '' ); + $object->set_gallery_image_ids( array() ); + } + } + + /** + * Set product shipping data. + * + * @param \WC_Product $object Product instance. + * @param array $data Shipping data. + */ + protected static function set_shipping_data( &$object, $data ) { + if ( $object->get_virtual() ) { + $object->set_weight( '' ); + $object->set_height( '' ); + $object->set_length( '' ); + $object->set_width( '' ); + } else { + if ( isset( $data['weight'] ) ) { + $object->set_weight( $data['weight'] ); + } + + // Height. + if ( isset( $data['dimensions']['height'] ) ) { + $object->set_height( $data['dimensions']['height'] ); + } + + // Width. + if ( isset( $data['dimensions']['width'] ) ) { + $object->set_width( $data['dimensions']['width'] ); + } + + // Length. + if ( isset( $data['dimensions']['length'] ) ) { + $object->set_length( $data['dimensions']['length'] ); + } + } + + // Shipping class. + if ( isset( $data['shipping_class'] ) ) { + $data_store = $object->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $object->set_shipping_class_id( $shipping_class_id ); + } + } + + /** + * Save downloadable files. + * + * @param \WC_Product $object Product instance. + * @param array $downloads Downloads data. + */ + protected static function set_downloadable_files( &$object, $downloads ) { + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new \WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $object, $key ) ); + $files[] = $download; + } + $object->set_downloads( $files ); + } + + /** + * Save taxonomy terms. + * + * @param \WC_Product $object Product instance. + * @param array $terms Terms data. + * @param string $taxonomy Taxonomy name. + */ + protected static function set_taxonomy_terms( &$object, $terms, $taxonomy = 'cat' ) { + $term_ids = wp_list_pluck( $terms, 'id' ); + + if ( 'cat' === $taxonomy ) { + $object->set_category_ids( $term_ids ); + } elseif ( 'tag' === $taxonomy ) { + $object->set_tag_ids( $term_ids ); + } + } + + /** + * Save default attributes. + * + * @param \WC_Product $object Product instance. + * @param array $raw_default_attributes Default attributes. + */ + protected static function set_default_attributes( &$object, $raw_default_attributes ) { + $attributes = $object->get_attributes(); + $default_attributes = array(); + + foreach ( $raw_default_attributes as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( isset( $attributes[ $attribute_name ] ) ) { + $_attribute = $attributes[ $attribute_name ]; + + if ( $_attribute['is_variation'] ) { + $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( ! empty( $_attribute['is_taxonomy'] ) ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $value = $term->slug; + } else { + $value = sanitize_title( $value ); + } + } + + if ( $value ) { + $default_attributes[ $attribute_name ] = $value; + } + } + } + } + + $object->set_default_attributes( $default_attributes ); + } +} diff --git a/src/Controllers/Version4/Schema/ProductVariationSchema.php b/src/Controllers/Version4/Schema/ProductVariationSchema.php new file mode 100644 index 00000000000..3030a1a06b1 --- /dev/null +++ b/src/Controllers/Version4/Schema/ProductVariationSchema.php @@ -0,0 +1,680 @@ + 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_variation', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product parent name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'variation', + 'enum' => array( 'variation' ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Variation description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wc_clean', + ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Variation status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_keys( get_post_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $schema; + } + + /** + * Convert object to match data in the schema. + * + * @param \WC_Product_Variation $object Product instance. + * @param string $context Request context. Options: 'view' and 'edit'. + * @return array + */ + public static function object_to_schema( $object, $context ) { + $data = array( + 'id' => $object->get_id(), + 'name' => $object->get_name( $context ), + 'type' => $object->get_type(), + 'parent_id' => $object->get_parent_id( $context ), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), + 'description' => wc_format_content( $object->get_description() ), + 'permalink' => $object->get_permalink(), + 'sku' => $object->get_sku(), + 'price' => $object->get_price(), + 'regular_price' => $object->get_regular_price(), + 'sale_price' => $object->get_sale_price(), + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), + 'on_sale' => $object->is_on_sale(), + 'status' => $object->get_status(), + 'purchasable' => $object->is_purchasable(), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => self::get_downloads( $object ), + 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, + 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, + 'tax_status' => $object->get_tax_status(), + 'tax_class' => $object->get_tax_class(), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity(), + 'stock_status' => $object->get_stock_status(), + 'backorders' => $object->get_backorders(), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'weight' => $object->get_weight(), + 'dimensions' => array( + 'length' => $object->get_length(), + 'width' => $object->get_width(), + 'height' => $object->get_height(), + ), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id(), + 'image' => self::get_image( $object ), + 'attributes' => self::get_attributes( $object ), + 'menu_order' => $object->get_menu_order(), + 'meta_data' => $object->get_meta_data(), + ); + return $data; + } + + /** + * Take data in the format of the schema and convert to a product object. + * + * @param \WP_REST_Request $request Request object. + * @return \WP_Error|\WC_Product_Variation + */ + public static function schema_to_object( $request ) { + if ( isset( $request['id'] ) ) { + $object = wc_get_product( absint( $request['id'] ) ); + } else { + $object = new \WC_Product_Variation(); + } + + $object->set_parent_id( absint( $request['product_id'] ) ); + + self::set_object_data( $object, $request ); + + return $object; + } + + /** + * Set object data from a request. + * + * @param \WC_Product_Variation $object Product object. + * @param \WP_REST_Request $request Request object. + */ + protected static function set_object_data( &$object, $request ) { + $props_to_set = [ + 'status', + 'sku', + 'virtual', + 'downloadable', + 'download_limit', + 'download_expiry', + 'manage_stock', + 'stock_status', + 'backorders', + 'regular_price', + 'sale_price', + 'date_on_sale_from', + 'date_on_sale_from_gmt', + 'date_on_sale_to', + 'date_on_sale_to_gmt', + 'tax_class', + 'description', + 'menu_order', + 'stock_quantity', + ]; + + foreach ( $props_to_set as $prop ) { + if ( isset( $request[ $prop ] ) && is_callable( array( $object, "set_$prop" ) ) ) { + $object->{"set_$prop"}( $request[ $prop ] ); + } + } + + // Allow set meta_data. + if ( isset( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['image'] ) ) { + self::set_image( $object, $request['image'] ); + } + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + self::set_downloadable_files( $object, $request['downloads'] ); + } + + if ( isset( $request['attributes'] ) ) { + self::set_attributes( $object, $request['attributes'] ); + } + + self::set_shipping_data( $object, $request ); + } + + /** + * Get the image for a product variation. + * + * @param \WC_Product_Variation $object Variation data. + * @return array + */ + protected static function get_image( $object ) { + if ( ! $object->get_image_id() ) { + return; + } + + $attachment_id = $object->get_image_id(); + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + return; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + return; + } + + if ( ! isset( $image ) ) { + return array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + } + + /** + * Set product object's attributes. + * + * @param \WC_Product_Variation $object Product object. + * @param array $raw_attributes Attribute data from request. + */ + protected static function set_attributes( &$object, $raw_attributes ) { + $attributes = array(); + $parent = wc_get_product( $object->get_parent_id() ); + + if ( ! $parent ) { + return new \WP_Error( + // Translators: %d parent ID. + "woocommerce_rest_product_variation_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $object->get_parent_id() ), array( + 'status' => 404, + ) + ); + } + + $parent_attributes = $parent->get_attributes(); + + foreach ( $raw_attributes as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $object->set_attributes( $attributes ); + } + + /** + * Set product images. + * + * @throws \WC_REST_Exception REST API exceptions. + * + * @param \WC_Product_Variation $object Product instance. + * @param array $image Image data. + */ + protected static function set_image( &$object, $image ) { + if ( ! empty( $image ) ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), array( $image ) ) ) { + throw new \WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: attachment ID */ + throw new \WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $object->set_image_id( $attachment_id ); + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + } else { + $object->set_image_id( '' ); + } + } +} From f1b8f584945262a43c6f198582641a4d535b90d2 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 14 Jun 2019 20:27:00 +0100 Subject: [PATCH 141/440] Removed some inline conditonals --- .../Version4/Schema/ProductSchema.php | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/Controllers/Version4/Schema/ProductSchema.php b/src/Controllers/Version4/Schema/ProductSchema.php index 2bf82a0b96b..f34dc62c910 100644 --- a/src/Controllers/Version4/Schema/ProductSchema.php +++ b/src/Controllers/Version4/Schema/ProductSchema.php @@ -665,8 +665,8 @@ class ProductSchema { 'status' => $object->get_status( $context ), 'featured' => $object->is_featured(), 'catalog_visibility' => $object->get_catalog_visibility( $context ), - 'description' => 'view' === $context ? wpautop( do_shortcode( $object->get_description() ) ) : $object->get_description( $context ), - 'short_description' => 'view' === $context ? apply_filters( 'woocommerce_short_description', $object->get_short_description() ) : $object->get_short_description( $context ), + 'description' => $object->get_description( $context ), + 'short_description' => $object->get_short_description( $context ), 'sku' => $object->get_sku( $context ), 'price' => $object->get_price( $context ), 'regular_price' => $object->get_regular_price( $context ), @@ -684,8 +684,8 @@ class ProductSchema { 'downloads' => self::get_downloads( $object ), 'download_limit' => $object->get_download_limit( $context ), 'download_expiry' => $object->get_download_expiry( $context ), - 'external_url' => $object->is_type( 'external' ) ? $object->get_product_url( $context ) : '', - 'button_text' => $object->is_type( 'external' ) ? $object->get_button_text( $context ) : '', + 'external_url' => '', + 'button_text' => '', 'tax_status' => $object->get_tax_status( $context ), 'tax_class' => $object->get_tax_class( $context ), 'manage_stock' => $object->managing_stock(), @@ -706,13 +706,13 @@ class ProductSchema { 'shipping_class' => $object->get_shipping_class(), 'shipping_class_id' => $object->get_shipping_class_id( $context ), 'reviews_allowed' => $object->get_reviews_allowed( $context ), - 'average_rating' => 'view' === $context ? wc_format_decimal( $object->get_average_rating(), 2 ) : $object->get_average_rating( $context ), + 'average_rating' => $object->get_average_rating( $context ), 'rating_count' => $object->get_rating_count(), - 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $object->get_id() ) ) ), - 'upsell_ids' => array_map( 'absint', $object->get_upsell_ids( $context ) ), - 'cross_sell_ids' => array_map( 'absint', $object->get_cross_sell_ids( $context ) ), + 'related_ids' => wp_parse_id_list( wc_get_related_products( $object->get_id() ) ), + 'upsell_ids' => wp_parse_id_list( $object->get_upsell_ids( $context ) ), + 'cross_sell_ids' => wp_parse_id_list( $object->get_cross_sell_ids( $context ) ), 'parent_id' => $object->get_parent_id( $context ), - 'purchase_note' => 'view' === $context ? wpautop( do_shortcode( wp_kses_post( $object->get_purchase_note() ) ) ) : $object->get_purchase_note( $context ), + 'purchase_note' => $object->get_purchase_note( $context ), 'categories' => self::get_taxonomy_terms( $object ), 'tags' => self::get_taxonomy_terms( $object, 'tag' ), 'images' => self::get_images( $object ), @@ -725,15 +725,28 @@ class ProductSchema { ); // Add variations to variable products. - if ( $object->is_type( 'variable' ) && $object->has_child() ) { + if ( $object->is_type( 'variable' ) ) { $data['variations'] = $object->get_children(); } // Add grouped products data. - if ( $object->is_type( 'grouped' ) && $object->has_child() ) { + if ( $object->is_type( 'grouped' ) ) { $data['grouped_products'] = $object->get_children(); } + // Add external product data. + if ( $object->is_type( 'external' ) ) { + $data['external_url'] = $object->get_product_url( $context ); + $data['button_text'] = $object->get_button_text( $context ); + } + + if ( 'view' === $context ) { + $data['description'] = wpautop( do_shortcode( $data['description'] ) ); + $data['short_description'] = apply_filters( 'woocommerce_short_description', $data['short_description'] ); + $data['average_rating'] = wc_format_decimal( $data['average_rating'], 2 ); + $data['purchase_note'] = wpautop( do_shortcode( $data['purchase_note'] ) ); + } + return $data; } From aa41b1ffd531e6a1d1f54baca009b0fc97a1ed44 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Sat, 15 Jun 2019 21:38:50 +0100 Subject: [PATCH 142/440] Filter values to set. --- .../Version4/Schema/ProductSchema.php | 93 +++++++++---------- .../Schema/ProductVariationSchema.php | 36 ++++--- 2 files changed, 68 insertions(+), 61 deletions(-) diff --git a/src/Controllers/Version4/Schema/ProductSchema.php b/src/Controllers/Version4/Schema/ProductSchema.php index f34dc62c910..02143a7b978 100644 --- a/src/Controllers/Version4/Schema/ProductSchema.php +++ b/src/Controllers/Version4/Schema/ProductSchema.php @@ -795,7 +795,8 @@ class ProductSchema { * @param \WP_REST_Request $request Request object. */ protected static function set_object_data( &$object, $request ) { - $props_to_set = [ + $values = $request->get_params(); + $prop_keys = [ 'name', 'sku', 'description', @@ -826,84 +827,82 @@ class ProductSchema { 'button_text', 'download_limit', 'download_expiry', + 'date_created', + 'date_created_gmt', + 'upsell_ids', + 'cross_sell_ids', ]; - foreach ( $props_to_set as $prop ) { - if ( isset( $request[ $prop ] ) && is_callable( array( $object, "set_$prop" ) ) ) { - $object->{"set_$prop"}( $request[ $prop ] ); + $props_to_set = array_intersect_key( $values, array_flip( $prop_keys ) ); + $props_to_set = array_filter( + $props_to_set, + function ( $prop ) use ( $object ) { + return is_callable( array( $object, "set_$prop" ) ); + }, + ARRAY_FILTER_USE_KEY + ); + + foreach ( $props_to_set as $prop => $value ) { + switch ( $prop ) { + case 'date_created': + case 'date_created_gmt': + $value = rest_parse_date( $value ); + break; + case 'upsell_ids': + case 'cross_sell_ids': + $value = wp_parse_id_list( $value ); + break; } + $object->{"set_$prop"}( $value ); } - if ( isset( $request['external_url'] ) && is_callable( array( $object, 'set_product_url' ) ) ) { - $object->set_product_url( $request['external_url'] ); - } - - if ( ! empty( $request['date_created'] ) ) { - $date = rest_parse_date( $request['date_created'] ); - - if ( $date ) { - $object->set_date_created( $date ); - } - } - - if ( ! empty( $request['date_created_gmt'] ) ) { - $date = rest_parse_date( $request['date_created_gmt'], true ); - - if ( $date ) { - $object->set_date_created( $date ); - } - } - - if ( isset( $request['upsell_ids'] ) ) { - $object->set_upsell_ids( wp_parse_id_list( $request['upsell_ids'] ) ); - } - - if ( isset( $request['cross_sell_ids'] ) ) { - $object->set_cross_sell_ids( wp_parse_id_list( $request['cross_sell_ids'] ) ); + if ( isset( $values['external_url'] ) && is_callable( array( $object, 'set_product_url' ) ) ) { + $object->set_product_url( $values['external_url'] ); } // Set children for a grouped product. - if ( $object->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { - $object->set_children( $request['grouped_products'] ); + if ( $object->is_type( 'grouped' ) && isset( $values['grouped_products'] ) ) { + $object->set_children( $values['grouped_products'] ); } // Allow set meta_data. - if ( isset( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { + if ( isset( $values['meta_data'] ) ) { + foreach ( $values['meta_data'] as $meta ) { $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); } } // Save default attributes for variable products. - if ( $object->is_type( 'variable' ) && isset( $request['default_attributes'] ) ) { - self::set_default_attributes( $object, $request['default_attributes'] ); + if ( $object->is_type( 'variable' ) && isset( $values['default_attributes'] ) ) { + self::set_default_attributes( $object, $values['default_attributes'] ); } // Check for featured/gallery images, upload it and set it. - if ( isset( $request['images'] ) ) { - self::set_images( $object, $request['images'] ); + if ( isset( $values['images'] ) ) { + self::set_images( $object, $values['images'] ); } // Product categories. - if ( isset( $request['categories'] ) ) { - self::set_taxonomy_terms( $object, $request['categories'] ); + if ( isset( $values['categories'] ) ) { + self::set_taxonomy_terms( $object, $values['categories'] ); } // Product tags. - if ( isset( $request['tags'] ) ) { - self::set_taxonomy_terms( $object, $request['tags'], 'tag' ); + if ( isset( $values['tags'] ) ) { + self::set_taxonomy_terms( $object, $values['tags'], 'tag' ); } // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - self::set_downloadable_files( $object, $request['downloads'] ); + if ( isset( $values['downloads'] ) && is_array( $values['downloads'] ) ) { + self::set_downloadable_files( $object, $values['downloads'] ); } - if ( isset( $request['attributes'] ) ) { - self::set_attributes( $object, $request['attributes'] ); + // Attributes. + if ( isset( $values['attributes'] ) ) { + self::set_attributes( $object, $values['attributes'] ); } - self::set_shipping_data( $object, $request ); + self::set_shipping_data( $object, $values ); return $object; } diff --git a/src/Controllers/Version4/Schema/ProductVariationSchema.php b/src/Controllers/Version4/Schema/ProductVariationSchema.php index 3030a1a06b1..1f0f04fda68 100644 --- a/src/Controllers/Version4/Schema/ProductVariationSchema.php +++ b/src/Controllers/Version4/Schema/ProductVariationSchema.php @@ -479,7 +479,8 @@ class ProductVariationSchema extends ProductSchema { * @param \WP_REST_Request $request Request object. */ protected static function set_object_data( &$object, $request ) { - $props_to_set = [ + $values = $request->get_params(); + $prop_keys = [ 'status', 'sku', 'virtual', @@ -501,34 +502,41 @@ class ProductVariationSchema extends ProductSchema { 'stock_quantity', ]; - foreach ( $props_to_set as $prop ) { - if ( isset( $request[ $prop ] ) && is_callable( array( $object, "set_$prop" ) ) ) { - $object->{"set_$prop"}( $request[ $prop ] ); - } + $props_to_set = array_intersect_key( $values, array_flip( $prop_keys ) ); + $props_to_set = array_filter( + $props_to_set, + function ( $prop ) use ( $object ) { + return is_callable( array( $object, "set_$prop" ) ); + }, + ARRAY_FILTER_USE_KEY + ); + + foreach ( $props_to_set as $prop => $value ) { + $object->{"set_$prop"}( $value ); } // Allow set meta_data. - if ( isset( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { + if ( isset( $values['meta_data'] ) ) { + foreach ( $values['meta_data'] as $meta ) { $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); } } // Check for featured/gallery images, upload it and set it. - if ( isset( $request['image'] ) ) { - self::set_image( $object, $request['image'] ); + if ( isset( $values['image'] ) ) { + self::set_image( $object, $values['image'] ); } // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - self::set_downloadable_files( $object, $request['downloads'] ); + if ( isset( $values['downloads'] ) && is_array( $values['downloads'] ) ) { + self::set_downloadable_files( $object, $values['downloads'] ); } - if ( isset( $request['attributes'] ) ) { - self::set_attributes( $object, $request['attributes'] ); + if ( isset( $values['attributes'] ) ) { + self::set_attributes( $object, $values['attributes'] ); } - self::set_shipping_data( $object, $request ); + self::set_shipping_data( $object, $values ); } /** From 2b3c870884190a4ea4ed017d580477ff8c447dca Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 13:19:52 +0100 Subject: [PATCH 143/440] Revised schema handling --- .../Version4/ProductVariations.php | 392 ++++- src/Controllers/Version4/Products.php | 645 +++++++- .../Version4/Schema/AbstractRequest.php | 49 + .../Version4/Schema/AbstractResponse.php | 25 + .../Version4/Schema/ProductRequest.php | 508 ++++++ .../Version4/Schema/ProductResponse.php | 354 +++++ .../Version4/Schema/ProductSchema.php | 1412 ----------------- .../Schema/ProductVariationRequest.php | 205 +++ .../Schema/ProductVariationResponse.php | 111 ++ .../Schema/ProductVariationSchema.php | 688 -------- 10 files changed, 2273 insertions(+), 2116 deletions(-) create mode 100644 src/Controllers/Version4/Schema/AbstractRequest.php create mode 100644 src/Controllers/Version4/Schema/AbstractResponse.php create mode 100644 src/Controllers/Version4/Schema/ProductRequest.php create mode 100644 src/Controllers/Version4/Schema/ProductResponse.php delete mode 100644 src/Controllers/Version4/Schema/ProductSchema.php create mode 100644 src/Controllers/Version4/Schema/ProductVariationRequest.php create mode 100644 src/Controllers/Version4/Schema/ProductVariationResponse.php delete mode 100644 src/Controllers/Version4/Schema/ProductVariationSchema.php diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index fd283f0ea2e..1e501b20398 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -11,7 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Schema\ProductVariationSchema; +use WooCommerce\RestApi\Controllers\Version4\Schema\ProductVariationRequest; +use WooCommerce\RestApi\Controllers\Version4\Schema\ProductVariationResponse; /** * REST API variations controller class. @@ -138,7 +139,376 @@ class ProductVariations extends Products { * @return array */ public function get_item_schema() { - $schema = ProductVariationSchema::get_schema(); + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_variation', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product parent name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'variation', + 'enum' => array( 'variation' ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Variation description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wc_clean', + ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Variation status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_keys( get_post_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); return $this->add_additional_fields_schema( $schema ); } @@ -218,11 +588,12 @@ class ProductVariations extends Products { * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = ProductVariationSchema::object_to_schema( $object, $context ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $variation_response = new ProductVariationResponse(); + $data = $variation_response->prepare_response( $object, $context ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); $response->add_links( $this->prepare_links( $object, $request ) ); /** @@ -312,7 +683,12 @@ class ProductVariations extends Products { * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { - $variation = ProductVariationSchema::schema_to_object( $request ); + try { + $variation_request = new ProductVariationRequest( $request ); + $variation = $variation_request->prepare_object(); + } catch ( \WC_REST_Exception $e ) { + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } /** * Filters an object before it is inserted via the REST API. diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 87e65aea4fe..14937eb7cbc 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -11,7 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Schema\ProductSchema; +use WooCommerce\RestApi\Controllers\Version4\Schema\ProductRequest; +use WooCommerce\RestApi\Controllers\Version4\Schema\ProductResponse; /** * REST API Products controller class. @@ -45,7 +46,629 @@ class Products extends AbstractObjectsController { * @return array */ public function get_item_schema() { - return $this->add_additional_fields_schema( ProductSchema::get_schema() ); + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit', 'embed' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit', 'embed' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit', 'embed' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wc_clean', + ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_kses_post', + ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit', 'embed' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + 'readonly' => true, + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); } /** @@ -207,11 +830,12 @@ class Products extends AbstractObjectsController { * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = ProductSchema::object_to_schema( $object, $context ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $product_response = new ProductResponse(); + $data = $product_response->prepare_response( $object, $context ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); $response->add_links( $this->prepare_links( $object, $request ) ); /** @@ -235,7 +859,12 @@ class Products extends AbstractObjectsController { * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { - $product = ProductSchema::schema_to_object( $request ); + try { + $product_request = new ProductRequest( $request ); + $product = $product_request->prepare_object(); + } catch ( \WC_REST_Exception $e ) { + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } /** * Filters an object before it is inserted via the REST API. diff --git a/src/Controllers/Version4/Schema/AbstractRequest.php b/src/Controllers/Version4/Schema/AbstractRequest.php new file mode 100644 index 00000000000..fbd4a200384 --- /dev/null +++ b/src/Controllers/Version4/Schema/AbstractRequest.php @@ -0,0 +1,49 @@ +request = (array) $request->get_params(); + } + + /** + * Get param from request. + * + * @param string $name Param name. + * @param mixed $default Default to return if not set. + */ + protected function get_param( $name, $default = null ) { + return isset( $this->request[ $name ] ) ? $this->request[ $name ] : $default; + } + + /** + * Convert request to object. + * + * @throws \WC_REST_Exception Will throw an exception if the resulting product object is invalid. + */ + abstract public function prepare_object(); +} diff --git a/src/Controllers/Version4/Schema/AbstractResponse.php b/src/Controllers/Version4/Schema/AbstractResponse.php new file mode 100644 index 00000000000..0e49e14700f --- /dev/null +++ b/src/Controllers/Version4/Schema/AbstractResponse.php @@ -0,0 +1,25 @@ +get_product_object(); + + $this->set_common_props( $object ); + $this->set_meta_data( $object ); + + switch ( $object->get_type() ) { + case 'grouped': + $this->set_grouped_props( $object ); + break; + case 'variable': + $this->set_variable_props( $object ); + break; + case 'external': + $this->set_external_props( $object ); + break; + } + + if ( $object->get_downloadable() ) { + $this->set_downloadable_props( $object ); + } + + return $object; + } + + /** + * Get product object from request args. + * + * @throws \WC_REST_Exception Will throw an exception if the resulting product object is invalid. + * @return \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External + */ + protected function get_product_object() { + $id = (int) $this->get_param( 'id', 0 ); + $type = $this->get_param( 'type', '' ); + + if ( $type ) { + $classname = '\\' . \WC_Product_Factory::get_classname_from_product_type( $type ); + $object = class_exists( $classname ) ? new $classname( $id ) : new \WC_Product_Simple( $id ); + } elseif ( $id ) { + $object = wc_get_product( $id ); + } else { + $object = new \WC_Product_Simple(); + } + + if ( ! $object ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_product_id', __( 'Invalid product.', 'woocommerce' ), 404 ); + } + + if ( $object->is_type( 'variation' ) ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_product_id', __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), 404 ); + } + + return $object; + } + + /** + * Set common product props. + * + * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object reference. + */ + protected function set_common_props( &$object ) { + $props = [ + 'name', + 'sku', + 'description', + 'short_description', + 'slug', + 'menu_order', + 'reviews_allowed', + 'virtual', + 'tax_status', + 'tax_class', + 'catalog_visibility', + 'purchase_note', + 'status', + 'featured', + 'regular_price', + 'sale_price', + 'date_on_sale_from', + 'date_on_sale_from_gmt', + 'date_on_sale_to', + 'date_on_sale_to_gmt', + 'parent_id', + 'sold_individually', + 'manage_stock', + 'backorders', + 'stock_status', + 'stock_quantity', + 'downloadable', + 'date_created', + 'date_created_gmt', + 'upsell_ids', + 'cross_sell_ids', + 'images', + 'categories', + 'tags', + 'attributes', + 'weight', + 'dimensions', + 'shipping_class', + ]; + + $request_props = array_intersect_key( $this->request, array_flip( $props ) ); + $prop_values = []; + + foreach ( $request_props as $prop => $value ) { + switch ( $prop ) { + case 'date_created': + case 'date_created_gmt': + $prop_values[ $prop ] = rest_parse_date( $value ); + break; + case 'upsell_ids': + case 'cross_sell_ids': + $prop_values[ $prop ] = wp_parse_id_list( $value ); + break; + case 'images': + $images = $this->parse_images_field( $value, $object ); + $prop_values = array_merge( $prop_values, $images ); + break; + case 'categories': + $prop_values['category_ids'] = $this->parse_terms_field( $value ); + break; + case 'tags': + $prop_values['tag_ids'] = $this->parse_terms_field( $value ); + break; + case 'attributes': + $prop_values['attributes'] = $this->parse_attributes_field( $value ); + break; + case 'dimensions': + $dimensions = $this->parse_dimensions_fields( $value ); + $prop_values = array_merge( $prop_values, $dimensions ); + break; + case 'shipping_class': + $prop_values['shipping_class_id'] = $this->parse_shipping_class( $value, $object ); + break; + default: + $prop_values[ $prop ] = $value; + } + } + + foreach ( $prop_values as $prop => $value ) { + $object->{"set_$prop"}( $value ); + } + } + + /** + * Set grouped product props. + * + * @param \WC_Product_Grouped $object Product object reference. + */ + protected function set_grouped_props( &$object ) { + $children = $this->get_param( 'grouped_products', null ); + + if ( ! is_null( $children ) ) { + $object->set_children( $children ); + } + } + + /** + * Set variable product props. + * + * @param \WC_Product_Variable $object Product object reference. + */ + protected function set_variable_props( &$object ) { + $default_attributes = $this->get_param( 'default_attributes', null ); + + if ( ! is_null( $default_attributes ) ) { + $object->set_default_attributes( $this->parse_default_attributes( $default_attributes, $object ) ); + } + } + + /** + * Set external product props. + * + * @param \WC_Product_External $object Product object reference. + */ + protected function set_external_props( &$object ) { + $button_text = $this->get_param( 'button_text', null ); + $external_url = $this->get_param( 'external_url', null ); + + if ( ! is_null( $button_text ) ) { + $object->set_button_text( $button_text ); + } + + if ( ! is_null( $external_url ) ) { + $object->set_product_url( $external_url ); + } + } + + /** + * Set downloadable product props. + * + * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object reference. + */ + protected function set_downloadable_props( &$object ) { + $download_limit = $this->get_param( 'download_limit', null ); + $download_expiry = $this->get_param( 'download_expiry', null ); + $downloads = $this->get_param( 'downloads', null ); + + if ( ! is_null( $download_limit ) ) { + $object->set_download_limit( $download_limit ); + } + + if ( ! is_null( $download_expiry ) ) { + $object->set_download_expiry( $download_expiry ); + } + + if ( ! is_null( $downloads ) ) { + $object->set_downloads( $this->parse_downloads_field( $downloads ) ); + } + } + + /** + * Set meta data. + * + * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object reference. + */ + protected function set_meta_data( &$object ) { + $meta_data = $this->get_param( 'meta_data', null ); + + if ( ! is_null( $meta_data ) ) { + foreach ( $meta_data as $meta ) { + $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } + + /** + * Set product object's attributes. + * + * @param array $raw_attributes Attribute data from request. + * @return array + */ + protected function parse_attributes_field( $raw_attributes ) { + $attributes = array(); + + foreach ( $raw_attributes as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new \WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new \WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + return $attributes; + } + + /** + * Set product images. + * + * @throws \WC_REST_Exception REST API exceptions. + * @param array $images Images data. + * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object. + * @return array + */ + protected function parse_images_field( $images, $object ) { + $response = [ + 'image_id' => '', + 'gallery_image_ids' => [], + ]; + + $images = is_array( $images ) ? array_filter( $images ) : []; + + if ( empty( $images ) ) { + return $response; + } + + foreach ( $images as $index => $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), $images ) ) { + throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: image ID */ + throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + if ( 0 === $index ) { + $response['image_id'] = $attachment_id; + } else { + $response['gallery_image_ids'][] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + } + + return $response; + } + + /** + * Parse dimensions. + * + * @param array $dimensions Product dimensions. + * @return array + */ + protected function parse_dimensions_fields( $dimensions ) { + $response = []; + + if ( isset( $dimensions['length'] ) ) { + $response['length'] = $dimensions['length']; + } + + if ( isset( $dimensions['width'] ) ) { + $response['width'] = $dimensions['width']; + } + + if ( isset( $dimensions['height'] ) ) { + $response['height'] = $dimensions['height']; + } + + return $response; + } + + /** + * Parse shipping class. + * + * @param string $shipping_class Shipping class slug. + * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object. + * @return int + */ + protected function parse_shipping_class( $shipping_class, $object ) { + $data_store = $object->get_data_store(); + return $data_store->get_shipping_class_id_by_slug( wc_clean( $shipping_class ) ); + } + + /** + * Parse downloadable files. + * + * @param array $downloads Downloads data. + * @return array + */ + protected function parse_downloads_field( $downloads ) { + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new \WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( $file['file'] ); + $files[] = $download; + } + return $files; + } + + /** + * Save taxonomy terms. + * + * @param array $terms Terms data. + * @return array + */ + protected function parse_terms_field( $terms ) { + return wp_list_pluck( $terms, 'id' ); + } + + /** + * Save default attributes. + * + * @param array $raw_default_attributes Default attributes. + * @param \WC_Product_Variable $object Product object reference. + * @return array + */ + protected function parse_default_attributes( $raw_default_attributes, $object ) { + $attributes = $object->get_attributes(); + $default_attributes = array(); + + foreach ( $raw_default_attributes as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( isset( $attributes[ $attribute_name ] ) ) { + $_attribute = $attributes[ $attribute_name ]; + + if ( $_attribute['is_variation'] ) { + $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( ! empty( $_attribute['is_taxonomy'] ) ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $value = $term->slug; + } else { + $value = sanitize_title( $value ); + } + } + + if ( $value ) { + $default_attributes[ $attribute_name ] = $value; + } + } + } + } + + return $default_attributes; + } +} diff --git a/src/Controllers/Version4/Schema/ProductResponse.php b/src/Controllers/Version4/Schema/ProductResponse.php new file mode 100644 index 00000000000..b85da38eb06 --- /dev/null +++ b/src/Controllers/Version4/Schema/ProductResponse.php @@ -0,0 +1,354 @@ + $object->get_id(), + 'name' => $object->get_name( $context ), + 'slug' => $object->get_slug( $context ), + 'permalink' => $object->get_permalink(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created( $context ), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created( $context ) ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified( $context ), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified( $context ) ), + 'type' => $object->get_type(), + 'status' => $object->get_status( $context ), + 'featured' => $object->is_featured(), + 'catalog_visibility' => $object->get_catalog_visibility( $context ), + 'description' => $object->get_description( $context ), + 'short_description' => $object->get_short_description( $context ), + 'sku' => $object->get_sku( $context ), + 'price' => $object->get_price( $context ), + 'regular_price' => $object->get_regular_price( $context ), + 'sale_price' => $object->get_sale_price( $context ) ? $object->get_sale_price( $context ) : '', + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ) ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ) ), + 'price_html' => $object->get_price_html(), + 'on_sale' => $object->is_on_sale( $context ), + 'purchasable' => $object->is_purchasable(), + 'total_sales' => $object->get_total_sales( $context ), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => $this->prepare_downloads( $object ), + 'download_limit' => $object->get_download_limit( $context ), + 'download_expiry' => $object->get_download_expiry( $context ), + 'external_url' => '', + 'button_text' => '', + 'tax_status' => $object->get_tax_status( $context ), + 'tax_class' => $object->get_tax_class( $context ), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity( $context ), + 'stock_status' => $object->get_stock_status( $context ), + 'backorders' => $object->get_backorders( $context ), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'sold_individually' => $object->is_sold_individually(), + 'weight' => $object->get_weight( $context ), + 'dimensions' => array( + 'length' => $object->get_length( $context ), + 'width' => $object->get_width( $context ), + 'height' => $object->get_height( $context ), + ), + 'shipping_required' => $object->needs_shipping(), + 'shipping_taxable' => $object->is_shipping_taxable(), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id( $context ), + 'reviews_allowed' => $object->get_reviews_allowed( $context ), + 'average_rating' => $object->get_average_rating( $context ), + 'rating_count' => $object->get_rating_count(), + 'related_ids' => wp_parse_id_list( wc_get_related_products( $object->get_id() ) ), + 'upsell_ids' => wp_parse_id_list( $object->get_upsell_ids( $context ) ), + 'cross_sell_ids' => wp_parse_id_list( $object->get_cross_sell_ids( $context ) ), + 'parent_id' => $object->get_parent_id( $context ), + 'purchase_note' => $object->get_purchase_note( $context ), + 'categories' => $this->prepare_taxonomy_terms( $object ), + 'tags' => $this->prepare_taxonomy_terms( $object, 'tag' ), + 'images' => $this->prepare_images( $object ), + 'attributes' => $this->prepare_attributes( $object ), + 'default_attributes' => $this->prepare_default_attributes( $object ), + 'variations' => array(), + 'grouped_products' => array(), + 'menu_order' => $object->get_menu_order( $context ), + 'meta_data' => $object->get_meta_data(), + ); + + // Add variations to variable products. + if ( $object->is_type( 'variable' ) ) { + $data['variations'] = $object->get_children(); + } + + // Add grouped products data. + if ( $object->is_type( 'grouped' ) ) { + $data['grouped_products'] = $object->get_children(); + } + + // Add external product data. + if ( $object->is_type( 'external' ) ) { + $data['external_url'] = $object->get_product_url( $context ); + $data['button_text'] = $object->get_button_text( $context ); + } + + if ( 'view' === $context ) { + $data['description'] = wpautop( do_shortcode( $data['description'] ) ); + $data['short_description'] = apply_filters( 'woocommerce_short_description', $data['short_description'] ); + $data['average_rating'] = wc_format_decimal( $data['average_rating'], 2 ); + $data['purchase_note'] = wpautop( do_shortcode( $data['purchase_note'] ) ); + } + + return $data; + } + + /** + * Get the downloads for a product or product variation. + * + * @param \WC_Product|\WC_Product_Variation $object Product instance. + * + * @return array + */ + protected function prepare_downloads( $object ) { + $downloads = array(); + + if ( $object->is_downloadable() ) { + foreach ( $object->get_downloads() as $file_id => $file ) { + $downloads[] = array( + 'id' => $file_id, // MD5 hash. + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get taxonomy terms. + * + * @param \WC_Product $object Product instance. + * @param string $taxonomy Taxonomy slug. + * + * @return array + */ + protected function prepare_taxonomy_terms( $object, $taxonomy = 'cat' ) { + $terms = array(); + + foreach ( wc_get_object_terms( $object->get_id(), 'product_' . $taxonomy ) as $term ) { + $terms[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + ); + } + + return $terms; + } + + /** + * Get the images for a product or product variation. + * + * @param \WC_Product|\WC_Product_Variation $object Product instance. + * @return array + */ + protected function prepare_images( $object ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( $object->get_image_id() ) { + $attachment_ids[] = $object->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $object->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + + return $images; + } + + /** + * Get default attributes. + * + * @param \WC_Product $object Product instance. + * + * @return array + */ + protected function prepare_default_attributes( $object ) { + $default = array(); + + if ( $object->is_type( 'variable' ) ) { + foreach ( array_filter( (array) $object->get_default_attributes(), 'strlen' ) as $key => $value ) { + if ( 0 === strpos( $key, 'pa_' ) ) { + $default[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $key ), + 'name' => $this->get_attribute_taxonomy_name( $key, $object ), + 'option' => $value, + ); + } else { + $default[] = array( + 'id' => 0, + 'name' => $this->get_attribute_taxonomy_name( $key, $object ), + 'option' => $value, + ); + } + } + } + + return $default; + } + + /** + * Get the attributes for a product or product variation. + * + * @param \WC_Product|\WC_Product_Variation $object Product instance. + * + * @return array + */ + protected function prepare_attributes( $object ) { + $attributes = array(); + + if ( $object->is_type( 'variation' ) ) { + $_product = wc_get_product( $object->get_parent_id() ); + foreach ( $object->get_variation_attributes() as $attribute_name => $attribute ) { + $name = str_replace( 'attribute_', '', $attribute_name ); + + if ( empty( $attribute ) && '0' !== $attribute ) { + continue; + } + + // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. + if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $name ); + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $name ), + 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), + 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), + 'option' => $attribute, + ); + } + } + } else { + foreach ( $object->get_attributes() as $attribute ) { + $attributes[] = array( + 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, + 'name' => $this->get_attribute_taxonomy_name( $attribute['name'], $object ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $object->get_id(), $attribute ), + ); + } + } + + return $attributes; + } + + /** + * Get product attribute taxonomy name. + * + * @param string $slug Taxonomy name. + * @param \WC_Product $object Product data. + * + * @since 3.0.0 + * @return string + */ + protected function get_attribute_taxonomy_name( $slug, $object ) { + // Format slug so it matches attributes of the product. + $slug = wc_attribute_taxonomy_slug( $slug ); + $attributes = $object->get_attributes(); + $attribute = false; + + // pa_ attributes. + if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { + $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; + } elseif ( isset( $attributes[ $slug ] ) ) { + $attribute = $attributes[ $slug ]; + } + + if ( ! $attribute ) { + return $slug; + } + + // Taxonomy attribute name. + if ( $attribute->is_taxonomy() ) { + $taxonomy = $attribute->get_taxonomy_object(); + return $taxonomy->attribute_label; + } + + // Custom product attribute name. + return $attribute->get_name(); + } + + /** + * Get attribute options. + * + * @param int $object_id Product ID. + * @param array $attribute Attribute data. + * + * @return array + */ + protected function get_attribute_options( $object_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( + $object_id, + $attribute['name'], + array( + 'fields' => 'names', + ) + ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } +} diff --git a/src/Controllers/Version4/Schema/ProductSchema.php b/src/Controllers/Version4/Schema/ProductSchema.php deleted file mode 100644 index 02143a7b978..00000000000 --- a/src/Controllers/Version4/Schema/ProductSchema.php +++ /dev/null @@ -1,1412 +0,0 @@ - 'http://json-schema.org/draft-04/schema#', - 'title' => 'product', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit', 'embed' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit', 'embed' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'simple', - 'enum' => array_keys( wc_get_product_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), - 'context' => array( 'view', 'edit' ), - ), - 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'visible', - 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Product description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wc_clean', - ), - ), - 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_kses_post', - ), - ), - 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'images' => array( - 'description' => __( 'List of images.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit', 'embed' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'integer', - ), - 'readonly' => true, - ), - 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $schema; - } - - /** - * Convert object to match data in the schema. - * - * @param \WC_Product $object Product instance. - * @param string $context Request context. Options: 'view' and 'edit'. - * @return array - */ - public static function object_to_schema( $object, $context ) { - $data = array( - 'id' => $object->get_id(), - 'name' => $object->get_name( $context ), - 'slug' => $object->get_slug( $context ), - 'permalink' => $object->get_permalink(), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created( $context ), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created( $context ) ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified( $context ), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified( $context ) ), - 'type' => $object->get_type(), - 'status' => $object->get_status( $context ), - 'featured' => $object->is_featured(), - 'catalog_visibility' => $object->get_catalog_visibility( $context ), - 'description' => $object->get_description( $context ), - 'short_description' => $object->get_short_description( $context ), - 'sku' => $object->get_sku( $context ), - 'price' => $object->get_price( $context ), - 'regular_price' => $object->get_regular_price( $context ), - 'sale_price' => $object->get_sale_price( $context ) ? $object->get_sale_price( $context ) : '', - 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ) ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ) ), - 'price_html' => $object->get_price_html(), - 'on_sale' => $object->is_on_sale( $context ), - 'purchasable' => $object->is_purchasable(), - 'total_sales' => $object->get_total_sales( $context ), - 'virtual' => $object->is_virtual(), - 'downloadable' => $object->is_downloadable(), - 'downloads' => self::get_downloads( $object ), - 'download_limit' => $object->get_download_limit( $context ), - 'download_expiry' => $object->get_download_expiry( $context ), - 'external_url' => '', - 'button_text' => '', - 'tax_status' => $object->get_tax_status( $context ), - 'tax_class' => $object->get_tax_class( $context ), - 'manage_stock' => $object->managing_stock(), - 'stock_quantity' => $object->get_stock_quantity( $context ), - 'stock_status' => $object->get_stock_status( $context ), - 'backorders' => $object->get_backorders( $context ), - 'backorders_allowed' => $object->backorders_allowed(), - 'backordered' => $object->is_on_backorder(), - 'sold_individually' => $object->is_sold_individually(), - 'weight' => $object->get_weight( $context ), - 'dimensions' => array( - 'length' => $object->get_length( $context ), - 'width' => $object->get_width( $context ), - 'height' => $object->get_height( $context ), - ), - 'shipping_required' => $object->needs_shipping(), - 'shipping_taxable' => $object->is_shipping_taxable(), - 'shipping_class' => $object->get_shipping_class(), - 'shipping_class_id' => $object->get_shipping_class_id( $context ), - 'reviews_allowed' => $object->get_reviews_allowed( $context ), - 'average_rating' => $object->get_average_rating( $context ), - 'rating_count' => $object->get_rating_count(), - 'related_ids' => wp_parse_id_list( wc_get_related_products( $object->get_id() ) ), - 'upsell_ids' => wp_parse_id_list( $object->get_upsell_ids( $context ) ), - 'cross_sell_ids' => wp_parse_id_list( $object->get_cross_sell_ids( $context ) ), - 'parent_id' => $object->get_parent_id( $context ), - 'purchase_note' => $object->get_purchase_note( $context ), - 'categories' => self::get_taxonomy_terms( $object ), - 'tags' => self::get_taxonomy_terms( $object, 'tag' ), - 'images' => self::get_images( $object ), - 'attributes' => self::get_attributes( $object ), - 'default_attributes' => self::get_default_attributes( $object ), - 'variations' => array(), - 'grouped_products' => array(), - 'menu_order' => $object->get_menu_order( $context ), - 'meta_data' => $object->get_meta_data(), - ); - - // Add variations to variable products. - if ( $object->is_type( 'variable' ) ) { - $data['variations'] = $object->get_children(); - } - - // Add grouped products data. - if ( $object->is_type( 'grouped' ) ) { - $data['grouped_products'] = $object->get_children(); - } - - // Add external product data. - if ( $object->is_type( 'external' ) ) { - $data['external_url'] = $object->get_product_url( $context ); - $data['button_text'] = $object->get_button_text( $context ); - } - - if ( 'view' === $context ) { - $data['description'] = wpautop( do_shortcode( $data['description'] ) ); - $data['short_description'] = apply_filters( 'woocommerce_short_description', $data['short_description'] ); - $data['average_rating'] = wc_format_decimal( $data['average_rating'], 2 ); - $data['purchase_note'] = wpautop( do_shortcode( $data['purchase_note'] ) ); - } - - return $data; - } - - /** - * Take data in the format of the schema and convert to a product object. - * - * @param \WP_REST_Request $request Request object. - * @return \WP_Error|\WC_Product - */ - public static function schema_to_object( $request ) { - $id = isset( $request['id'] ) ? (int) $request['id'] : 0; - - if ( isset( $request['type'] ) ) { - $classname = '\\' . \WC_Product_Factory::get_classname_from_product_type( $request['type'] ); - - if ( ! class_exists( $classname ) ) { - $classname = '\\WC_Product_Simple'; - } - - $object = new $classname( $id ); - } elseif ( isset( $request['id'] ) ) { - $object = wc_get_product( $id ); - } else { - $object = new \WC_Product_Simple(); - } - - if ( $object->is_type( 'variation' ) ) { - return new \WP_Error( - 'woocommerce_rest_invalid_product_id', - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), - array( - 'status' => 404, - ) - ); - } - - self::set_object_data( $object, $request ); - - return $object; - } - - /** - * Set object data from a request. - * - * @param \WC_Product $object Product object. - * @param \WP_REST_Request $request Request object. - */ - protected static function set_object_data( &$object, $request ) { - $values = $request->get_params(); - $prop_keys = [ - 'name', - 'sku', - 'description', - 'short_description', - 'slug', - 'menu_order', - 'reviews_allowed', - 'virtual', - 'tax_status', - 'tax_class', - 'catalog_visibility', - 'purchase_note', - 'status', - 'featured', - 'regular_price', - 'sale_price', - 'date_on_sale_from', - 'date_on_sale_from_gmt', - 'date_on_sale_to', - 'date_on_sale_to_gmt', - 'parent_id', - 'sold_individually', - 'manage_stock', - 'backorders', - 'stock_status', - 'stock_quantity', - 'downloadable', - 'button_text', - 'download_limit', - 'download_expiry', - 'date_created', - 'date_created_gmt', - 'upsell_ids', - 'cross_sell_ids', - ]; - - $props_to_set = array_intersect_key( $values, array_flip( $prop_keys ) ); - $props_to_set = array_filter( - $props_to_set, - function ( $prop ) use ( $object ) { - return is_callable( array( $object, "set_$prop" ) ); - }, - ARRAY_FILTER_USE_KEY - ); - - foreach ( $props_to_set as $prop => $value ) { - switch ( $prop ) { - case 'date_created': - case 'date_created_gmt': - $value = rest_parse_date( $value ); - break; - case 'upsell_ids': - case 'cross_sell_ids': - $value = wp_parse_id_list( $value ); - break; - } - $object->{"set_$prop"}( $value ); - } - - if ( isset( $values['external_url'] ) && is_callable( array( $object, 'set_product_url' ) ) ) { - $object->set_product_url( $values['external_url'] ); - } - - // Set children for a grouped product. - if ( $object->is_type( 'grouped' ) && isset( $values['grouped_products'] ) ) { - $object->set_children( $values['grouped_products'] ); - } - - // Allow set meta_data. - if ( isset( $values['meta_data'] ) ) { - foreach ( $values['meta_data'] as $meta ) { - $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - - // Save default attributes for variable products. - if ( $object->is_type( 'variable' ) && isset( $values['default_attributes'] ) ) { - self::set_default_attributes( $object, $values['default_attributes'] ); - } - - // Check for featured/gallery images, upload it and set it. - if ( isset( $values['images'] ) ) { - self::set_images( $object, $values['images'] ); - } - - // Product categories. - if ( isset( $values['categories'] ) ) { - self::set_taxonomy_terms( $object, $values['categories'] ); - } - - // Product tags. - if ( isset( $values['tags'] ) ) { - self::set_taxonomy_terms( $object, $values['tags'], 'tag' ); - } - - // Downloadable files. - if ( isset( $values['downloads'] ) && is_array( $values['downloads'] ) ) { - self::set_downloadable_files( $object, $values['downloads'] ); - } - - // Attributes. - if ( isset( $values['attributes'] ) ) { - self::set_attributes( $object, $values['attributes'] ); - } - - self::set_shipping_data( $object, $values ); - - return $object; - } - - /** - * Get the downloads for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $object Product instance. - * - * @return array - */ - protected static function get_downloads( $object ) { - $downloads = array(); - - if ( $object->is_downloadable() ) { - foreach ( $object->get_downloads() as $file_id => $file ) { - $downloads[] = array( - 'id' => $file_id, // MD5 hash. - 'name' => $file['name'], - 'file' => $file['file'], - ); - } - } - - return $downloads; - } - - /** - * Get taxonomy terms. - * - * @param \WC_Product $object Product instance. - * @param string $taxonomy Taxonomy slug. - * - * @return array - */ - protected static function get_taxonomy_terms( $object, $taxonomy = 'cat' ) { - $terms = array(); - - foreach ( wc_get_object_terms( $object->get_id(), 'product_' . $taxonomy ) as $term ) { - $terms[] = array( - 'id' => $term->term_id, - 'name' => $term->name, - 'slug' => $term->slug, - ); - } - - return $terms; - } - - /** - * Get the images for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $object Product instance. - * @return array - */ - protected static function get_images( $object ) { - $images = array(); - $attachment_ids = array(); - - // Add featured image. - if ( $object->get_image_id() ) { - $attachment_ids[] = $object->get_image_id(); - } - - // Add gallery images. - $attachment_ids = array_merge( $attachment_ids, $object->get_gallery_image_ids() ); - - // Build image data. - foreach ( $attachment_ids as $attachment_id ) { - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - continue; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - continue; - } - - $images[] = array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - - return $images; - } - - /** - * Get product attribute taxonomy name. - * - * @param string $slug Taxonomy name. - * @param \WC_Product $object Product data. - * - * @since 3.0.0 - * @return string - */ - protected static function get_attribute_taxonomy_name( $slug, $object ) { - // Format slug so it matches attributes of the product. - $slug = wc_attribute_taxonomy_slug( $slug ); - $attributes = $object->get_attributes(); - $attribute = false; - - // pa_ attributes. - if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { - $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; - } elseif ( isset( $attributes[ $slug ] ) ) { - $attribute = $attributes[ $slug ]; - } - - if ( ! $attribute ) { - return $slug; - } - - // Taxonomy attribute name. - if ( $attribute->is_taxonomy() ) { - $taxonomy = $attribute->get_taxonomy_object(); - return $taxonomy->attribute_label; - } - - // Custom product attribute name. - return $attribute->get_name(); - } - - /** - * Get default attributes. - * - * @param \WC_Product $object Product instance. - * - * @return array - */ - protected static function get_default_attributes( $object ) { - $default = array(); - - if ( $object->is_type( 'variable' ) ) { - foreach ( array_filter( (array) $object->get_default_attributes(), 'strlen' ) as $key => $value ) { - if ( 0 === strpos( $key, 'pa_' ) ) { - $default[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $key ), - 'name' => self::get_attribute_taxonomy_name( $key, $object ), - 'option' => $value, - ); - } else { - $default[] = array( - 'id' => 0, - 'name' => self::get_attribute_taxonomy_name( $key, $object ), - 'option' => $value, - ); - } - } - } - - return $default; - } - - /** - * Get attribute options. - * - * @param int $object_id Product ID. - * @param array $attribute Attribute data. - * - * @return array - */ - protected static function get_attribute_options( $object_id, $attribute ) { - if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { - return wc_get_product_terms( - $object_id, - $attribute['name'], - array( - 'fields' => 'names', - ) - ); - } elseif ( isset( $attribute['value'] ) ) { - return array_map( 'trim', explode( '|', $attribute['value'] ) ); - } - - return array(); - } - - /** - * Get the attributes for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $object Product instance. - * - * @return array - */ - protected static function get_attributes( $object ) { - $attributes = array(); - - if ( $object->is_type( 'variation' ) ) { - $_product = wc_get_product( $object->get_parent_id() ); - foreach ( $object->get_variation_attributes() as $attribute_name => $attribute ) { - $name = str_replace( 'attribute_', '', $attribute_name ); - - if ( empty( $attribute ) && '0' !== $attribute ) { - continue; - } - - // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. - if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { - $option_term = get_term_by( 'slug', $attribute, $name ); - $attributes[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $name ), - 'name' => self::get_attribute_taxonomy_name( $name, $_product ), - 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, - ); - } else { - $attributes[] = array( - 'id' => 0, - 'name' => self::get_attribute_taxonomy_name( $name, $_product ), - 'option' => $attribute, - ); - } - } - } else { - foreach ( $object->get_attributes() as $attribute ) { - $attributes[] = array( - 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, - 'name' => self::get_attribute_taxonomy_name( $attribute['name'], $object ), - 'position' => (int) $attribute['position'], - 'visible' => (bool) $attribute['is_visible'], - 'variation' => (bool) $attribute['is_variation'], - 'options' => self::get_attribute_options( $object->get_id(), $attribute ), - ); - } - } - - return $attributes; - } - - /** - * Set product object's attributes. - * - * @param \WC_Product $object Product object. - * @param array $raw_attributes Attribute data from request. - */ - protected static function set_attributes( &$object, $raw_attributes ) { - $attributes = array(); - - foreach ( $raw_attributes as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = wc_clean( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( $attribute_id ) { - - if ( isset( $attribute['options'] ) ) { - $options = $attribute['options']; - - if ( ! is_array( $attribute['options'] ) ) { - // Text based attributes - Posted values are term names. - $options = explode( WC_DELIMITER, $options ); - } - - $values = array_map( 'wc_sanitize_term_text_based', $options ); - $values = array_filter( $values, 'strlen' ); - } else { - $values = array(); - } - - if ( ! empty( $values ) ) { - // Add attribute to array, but don't set values. - $attribute_object = new \WC_Product_Attribute(); - $attribute_object->set_id( $attribute_id ); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } elseif ( isset( $attribute['options'] ) ) { - // Custom attribute - Add attribute to array and set the values. - if ( is_array( $attribute['options'] ) ) { - $values = $attribute['options']; - } else { - $values = explode( WC_DELIMITER, $attribute['options'] ); - } - $attribute_object = new \WC_Product_Attribute(); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } - $object->set_attributes( $attributes ); - } - - /** - * Set product images. - * - * @throws \WC_REST_Exception REST API exceptions. - * - * @param \WC_Product $object Product instance. - * @param array $images Images data. - */ - protected static function set_images( &$object, $images ) { - $images = is_array( $images ) ? array_filter( $images ) : array(); - - if ( ! empty( $images ) ) { - $gallery = array(); - - foreach ( $images as $index => $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), $images ) ) { - throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); - } else { - continue; - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: image ID */ - throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); - } - - $featured_image = $object->get_image_id(); - - if ( 0 === $index ) { - $object->set_image_id( $attachment_id ); - } else { - $gallery[] = $attachment_id; - } - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); - } - } - - $object->set_gallery_image_ids( $gallery ); - } else { - $object->set_image_id( '' ); - $object->set_gallery_image_ids( array() ); - } - } - - /** - * Set product shipping data. - * - * @param \WC_Product $object Product instance. - * @param array $data Shipping data. - */ - protected static function set_shipping_data( &$object, $data ) { - if ( $object->get_virtual() ) { - $object->set_weight( '' ); - $object->set_height( '' ); - $object->set_length( '' ); - $object->set_width( '' ); - } else { - if ( isset( $data['weight'] ) ) { - $object->set_weight( $data['weight'] ); - } - - // Height. - if ( isset( $data['dimensions']['height'] ) ) { - $object->set_height( $data['dimensions']['height'] ); - } - - // Width. - if ( isset( $data['dimensions']['width'] ) ) { - $object->set_width( $data['dimensions']['width'] ); - } - - // Length. - if ( isset( $data['dimensions']['length'] ) ) { - $object->set_length( $data['dimensions']['length'] ); - } - } - - // Shipping class. - if ( isset( $data['shipping_class'] ) ) { - $data_store = $object->get_data_store(); - $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); - $object->set_shipping_class_id( $shipping_class_id ); - } - } - - /** - * Save downloadable files. - * - * @param \WC_Product $object Product instance. - * @param array $downloads Downloads data. - */ - protected static function set_downloadable_files( &$object, $downloads ) { - $files = array(); - foreach ( $downloads as $key => $file ) { - if ( empty( $file['file'] ) ) { - continue; - } - - $download = new \WC_Product_Download(); - $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); - $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); - $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $object, $key ) ); - $files[] = $download; - } - $object->set_downloads( $files ); - } - - /** - * Save taxonomy terms. - * - * @param \WC_Product $object Product instance. - * @param array $terms Terms data. - * @param string $taxonomy Taxonomy name. - */ - protected static function set_taxonomy_terms( &$object, $terms, $taxonomy = 'cat' ) { - $term_ids = wp_list_pluck( $terms, 'id' ); - - if ( 'cat' === $taxonomy ) { - $object->set_category_ids( $term_ids ); - } elseif ( 'tag' === $taxonomy ) { - $object->set_tag_ids( $term_ids ); - } - } - - /** - * Save default attributes. - * - * @param \WC_Product $object Product instance. - * @param array $raw_default_attributes Default attributes. - */ - protected static function set_default_attributes( &$object, $raw_default_attributes ) { - $attributes = $object->get_attributes(); - $default_attributes = array(); - - foreach ( $raw_default_attributes as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( isset( $attributes[ $attribute_name ] ) ) { - $_attribute = $attributes[ $attribute_name ]; - - if ( $_attribute['is_variation'] ) { - $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( ! empty( $_attribute['is_taxonomy'] ) ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $value = $term->slug; - } else { - $value = sanitize_title( $value ); - } - } - - if ( $value ) { - $default_attributes[ $attribute_name ] = $value; - } - } - } - } - - $object->set_default_attributes( $default_attributes ); - } -} diff --git a/src/Controllers/Version4/Schema/ProductVariationRequest.php b/src/Controllers/Version4/Schema/ProductVariationRequest.php new file mode 100644 index 00000000000..186a953b266 --- /dev/null +++ b/src/Controllers/Version4/Schema/ProductVariationRequest.php @@ -0,0 +1,205 @@ +get_param( 'id', 0 ); + $object = new \WC_Product_Variation( $id ); + $object->set_parent_id( (int) $this->get_param( 'product_id', 0 ) ); + $parent = wc_get_product( $object->get_parent_id() ); + + if ( ! $parent ) { + throw new \WC_REST_Exception( 'woocommerce_rest_product_variation_invalid_parent', __( 'Invalid parent product.', 'woocommerce' ), 404 ); + } + + $this->set_common_props( $object ); + $this->set_meta_data( $object ); + + if ( $object->get_downloadable() ) { + $this->set_downloadable_props( $object ); + } + + return $object; + } + + /** + * Set common product props. + * + * @param \WC_Product_Variation $object Product object reference. + */ + protected function set_common_props( &$object ) { + $props = [ + 'status', + 'sku', + 'virtual', + 'downloadable', + 'download_limit', + 'download_expiry', + 'manage_stock', + 'stock_status', + 'backorders', + 'regular_price', + 'sale_price', + 'date_on_sale_from', + 'date_on_sale_from_gmt', + 'date_on_sale_to', + 'date_on_sale_to_gmt', + 'tax_class', + 'description', + 'menu_order', + 'stock_quantity', + 'image', + 'downloads', + 'attributes', + 'weight', + 'dimensions', + 'shipping_class', + ]; + + $request_props = array_intersect_key( $this->request, array_flip( $props ) ); + $prop_values = []; + + foreach ( $request_props as $prop => $value ) { + switch ( $prop ) { + case 'image': + $prop_values['image_id'] = $this->parse_image_field( $value, $object ); + break; + case 'attributes': + $prop_values['attributes'] = $this->parse_attributes_field( $value, $object ); + break; + case 'dimensions': + $dimensions = $this->parse_dimensions_fields( $value ); + $prop_values = array_merge( $prop_values, $dimensions ); + break; + case 'shipping_class': + $prop_values['shipping_class_id'] = $this->parse_shipping_class( $value, $object ); + break; + default: + $prop_values[ $prop ] = $value; + } + } + + foreach ( $prop_values as $prop => $value ) { + $object->{"set_$prop"}( $value ); + } + } + + /** + * Set product object's attributes. + * + * @param array $raw_attributes Attribute data from request. + * @param \WC_Product_Variation $object Product object. + */ + protected function parse_attributes_field( $raw_attributes, $object = null ) { + $attributes = array(); + $parent = wc_get_product( $object->get_parent_id() ); + $parent_attributes = $parent->get_attributes(); + + foreach ( $raw_attributes as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + return $attributes; + } + + /** + * Set product images. + * + * @throws \WC_REST_Exception REST API exceptions. + * @param array $image Image data. + * @param \WC_Product_Variation $object Product object. + * @return array + */ + protected function parse_image_field( $image, $object ) { + if ( empty( $image ) ) { + return ''; + } + + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), array( $image ) ) ) { + throw new \WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: attachment ID */ + throw new \WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + + return $attachment_id; + } +} diff --git a/src/Controllers/Version4/Schema/ProductVariationResponse.php b/src/Controllers/Version4/Schema/ProductVariationResponse.php new file mode 100644 index 00000000000..e2f155b36eb --- /dev/null +++ b/src/Controllers/Version4/Schema/ProductVariationResponse.php @@ -0,0 +1,111 @@ + $object->get_id(), + 'name' => $object->get_name( $context ), + 'type' => $object->get_type(), + 'parent_id' => $object->get_parent_id( $context ), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), + 'description' => wc_format_content( $object->get_description() ), + 'permalink' => $object->get_permalink(), + 'sku' => $object->get_sku(), + 'price' => $object->get_price(), + 'regular_price' => $object->get_regular_price(), + 'sale_price' => $object->get_sale_price(), + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), + 'on_sale' => $object->is_on_sale(), + 'status' => $object->get_status(), + 'purchasable' => $object->is_purchasable(), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => $this->prepare_downloads( $object ), + 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, + 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, + 'tax_status' => $object->get_tax_status(), + 'tax_class' => $object->get_tax_class(), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity(), + 'stock_status' => $object->get_stock_status(), + 'backorders' => $object->get_backorders(), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'weight' => $object->get_weight(), + 'dimensions' => array( + 'length' => $object->get_length(), + 'width' => $object->get_width(), + 'height' => $object->get_height(), + ), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id(), + 'image' => $this->prepare_image( $object ), + 'attributes' => $this->prepare_attributes( $object ), + 'menu_order' => $object->get_menu_order(), + 'meta_data' => $object->get_meta_data(), + ); + return $data; + } + + /** + * Get the image for a product variation. + * + * @param \WC_Product_Variation $object Variation data. + * @return array + */ + protected static function prepare_image( $object ) { + if ( ! $object->get_image_id() ) { + return; + } + + $attachment_id = $object->get_image_id(); + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + return; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + return; + } + + if ( ! isset( $image ) ) { + return array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + } +} diff --git a/src/Controllers/Version4/Schema/ProductVariationSchema.php b/src/Controllers/Version4/Schema/ProductVariationSchema.php deleted file mode 100644 index 1f0f04fda68..00000000000 --- a/src/Controllers/Version4/Schema/ProductVariationSchema.php +++ /dev/null @@ -1,688 +0,0 @@ - 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_variation', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product parent name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'variation', - 'enum' => array( 'variation' ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wc_clean', - ), - ), - 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Variation status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_keys( get_post_statuses() ), - 'context' => array( 'view', 'edit' ), - ), - 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $schema; - } - - /** - * Convert object to match data in the schema. - * - * @param \WC_Product_Variation $object Product instance. - * @param string $context Request context. Options: 'view' and 'edit'. - * @return array - */ - public static function object_to_schema( $object, $context ) { - $data = array( - 'id' => $object->get_id(), - 'name' => $object->get_name( $context ), - 'type' => $object->get_type(), - 'parent_id' => $object->get_parent_id( $context ), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), - 'description' => wc_format_content( $object->get_description() ), - 'permalink' => $object->get_permalink(), - 'sku' => $object->get_sku(), - 'price' => $object->get_price(), - 'regular_price' => $object->get_regular_price(), - 'sale_price' => $object->get_sale_price(), - 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), - 'on_sale' => $object->is_on_sale(), - 'status' => $object->get_status(), - 'purchasable' => $object->is_purchasable(), - 'virtual' => $object->is_virtual(), - 'downloadable' => $object->is_downloadable(), - 'downloads' => self::get_downloads( $object ), - 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, - 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, - 'tax_status' => $object->get_tax_status(), - 'tax_class' => $object->get_tax_class(), - 'manage_stock' => $object->managing_stock(), - 'stock_quantity' => $object->get_stock_quantity(), - 'stock_status' => $object->get_stock_status(), - 'backorders' => $object->get_backorders(), - 'backorders_allowed' => $object->backorders_allowed(), - 'backordered' => $object->is_on_backorder(), - 'weight' => $object->get_weight(), - 'dimensions' => array( - 'length' => $object->get_length(), - 'width' => $object->get_width(), - 'height' => $object->get_height(), - ), - 'shipping_class' => $object->get_shipping_class(), - 'shipping_class_id' => $object->get_shipping_class_id(), - 'image' => self::get_image( $object ), - 'attributes' => self::get_attributes( $object ), - 'menu_order' => $object->get_menu_order(), - 'meta_data' => $object->get_meta_data(), - ); - return $data; - } - - /** - * Take data in the format of the schema and convert to a product object. - * - * @param \WP_REST_Request $request Request object. - * @return \WP_Error|\WC_Product_Variation - */ - public static function schema_to_object( $request ) { - if ( isset( $request['id'] ) ) { - $object = wc_get_product( absint( $request['id'] ) ); - } else { - $object = new \WC_Product_Variation(); - } - - $object->set_parent_id( absint( $request['product_id'] ) ); - - self::set_object_data( $object, $request ); - - return $object; - } - - /** - * Set object data from a request. - * - * @param \WC_Product_Variation $object Product object. - * @param \WP_REST_Request $request Request object. - */ - protected static function set_object_data( &$object, $request ) { - $values = $request->get_params(); - $prop_keys = [ - 'status', - 'sku', - 'virtual', - 'downloadable', - 'download_limit', - 'download_expiry', - 'manage_stock', - 'stock_status', - 'backorders', - 'regular_price', - 'sale_price', - 'date_on_sale_from', - 'date_on_sale_from_gmt', - 'date_on_sale_to', - 'date_on_sale_to_gmt', - 'tax_class', - 'description', - 'menu_order', - 'stock_quantity', - ]; - - $props_to_set = array_intersect_key( $values, array_flip( $prop_keys ) ); - $props_to_set = array_filter( - $props_to_set, - function ( $prop ) use ( $object ) { - return is_callable( array( $object, "set_$prop" ) ); - }, - ARRAY_FILTER_USE_KEY - ); - - foreach ( $props_to_set as $prop => $value ) { - $object->{"set_$prop"}( $value ); - } - - // Allow set meta_data. - if ( isset( $values['meta_data'] ) ) { - foreach ( $values['meta_data'] as $meta ) { - $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - - // Check for featured/gallery images, upload it and set it. - if ( isset( $values['image'] ) ) { - self::set_image( $object, $values['image'] ); - } - - // Downloadable files. - if ( isset( $values['downloads'] ) && is_array( $values['downloads'] ) ) { - self::set_downloadable_files( $object, $values['downloads'] ); - } - - if ( isset( $values['attributes'] ) ) { - self::set_attributes( $object, $values['attributes'] ); - } - - self::set_shipping_data( $object, $values ); - } - - /** - * Get the image for a product variation. - * - * @param \WC_Product_Variation $object Variation data. - * @return array - */ - protected static function get_image( $object ) { - if ( ! $object->get_image_id() ) { - return; - } - - $attachment_id = $object->get_image_id(); - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - return; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - return; - } - - if ( ! isset( $image ) ) { - return array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - } - - /** - * Set product object's attributes. - * - * @param \WC_Product_Variation $object Product object. - * @param array $raw_attributes Attribute data from request. - */ - protected static function set_attributes( &$object, $raw_attributes ) { - $attributes = array(); - $parent = wc_get_product( $object->get_parent_id() ); - - if ( ! $parent ) { - return new \WP_Error( - // Translators: %d parent ID. - "woocommerce_rest_product_variation_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $object->get_parent_id() ), array( - 'status' => 404, - ) - ); - } - - $parent_attributes = $parent->get_attributes(); - - foreach ( $raw_attributes as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { - continue; - } - - $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); - $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $attribute_value = $term->slug; - } else { - $attribute_value = sanitize_title( $attribute_value ); - } - } - - $attributes[ $attribute_key ] = $attribute_value; - } - - $object->set_attributes( $attributes ); - } - - /** - * Set product images. - * - * @throws \WC_REST_Exception REST API exceptions. - * - * @param \WC_Product_Variation $object Product instance. - * @param array $image Image data. - */ - protected static function set_image( &$object, $image ) { - if ( ! empty( $image ) ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), array( $image ) ) ) { - throw new \WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: attachment ID */ - throw new \WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); - } - - $object->set_image_id( $attachment_id ); - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); - } - } else { - $object->set_image_id( '' ); - } - } -} From 836ece76b14562253fc7cddefa61c6a2859bdd1d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 13:52:14 +0100 Subject: [PATCH 144/440] Simplify parse_attributes_field --- .../Version4/Schema/ProductRequest.php | 72 +++++++------------ 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/src/Controllers/Version4/Schema/ProductRequest.php b/src/Controllers/Version4/Schema/ProductRequest.php index 6291b572518..8bc30c3aa18 100644 --- a/src/Controllers/Version4/Schema/ProductRequest.php +++ b/src/Controllers/Version4/Schema/ProductRequest.php @@ -55,8 +55,13 @@ class ProductRequest extends AbstractRequest { $type = $this->get_param( 'type', '' ); if ( $type ) { - $classname = '\\' . \WC_Product_Factory::get_classname_from_product_type( $type ); - $object = class_exists( $classname ) ? new $classname( $id ) : new \WC_Product_Simple( $id ); + $classname = \WC_Product_Factory::get_classname_from_product_type( $type ); + if ( $classname && class_exists( '\\' . $classname ) ) { + $classname = '\\' . $classname; + } else { + $classname = '\WC_Product_Simple'; + } + $object = new $classname( $id ); } elseif ( $id ) { $object = wc_get_product( $id ); } else { @@ -256,63 +261,36 @@ class ProductRequest extends AbstractRequest { $attributes = array(); foreach ( $raw_attributes as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - // Check ID for global attributes or name for product attributes. if ( ! empty( $attribute['id'] ) ) { $attribute_id = absint( $attribute['id'] ); $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_id = 0; $attribute_name = wc_clean( $attribute['name'] ); } - if ( ! $attribute_id && ! $attribute_name ) { + if ( ! $attribute_name || ! isset( $attribute['options'] ) ) { continue; } - if ( $attribute_id ) { - - if ( isset( $attribute['options'] ) ) { - $options = $attribute['options']; - - if ( ! is_array( $attribute['options'] ) ) { - // Text based attributes - Posted values are term names. - $options = explode( WC_DELIMITER, $options ); - } - - $values = array_map( 'wc_sanitize_term_text_based', $options ); - $values = array_filter( $values, 'strlen' ); - } else { - $values = array(); - } - - if ( ! empty( $values ) ) { - // Add attribute to array, but don't set values. - $attribute_object = new \WC_Product_Attribute(); - $attribute_object->set_id( $attribute_id ); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } elseif ( isset( $attribute['options'] ) ) { - // Custom attribute - Add attribute to array and set the values. - if ( is_array( $attribute['options'] ) ) { - $values = $attribute['options']; - } else { - $values = explode( WC_DELIMITER, $attribute['options'] ); - } - $attribute_object = new \WC_Product_Attribute(); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $attribute['options'] = explode( \WC_DELIMITER, $attribute['options'] ); } + + if ( $attribute_id ) { + $attribute['options'] = array_filter( array_map( 'wc_sanitize_term_text_based', $attribute['options'] ), 'strlen' ); + } + + $attribute_object = new \WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $attribute['options'] ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ! empty( $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ! empty( $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; } return $attributes; } From f8a28ae1a93fc095e482ccab26e018942f4c0417 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 13:53:18 +0100 Subject: [PATCH 145/440] Move set_meta_data --- .../Version4/Schema/AbstractRequest.php | 15 +++++++++++++++ .../Version4/Schema/ProductRequest.php | 15 --------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Controllers/Version4/Schema/AbstractRequest.php b/src/Controllers/Version4/Schema/AbstractRequest.php index fbd4a200384..e7b64799477 100644 --- a/src/Controllers/Version4/Schema/AbstractRequest.php +++ b/src/Controllers/Version4/Schema/AbstractRequest.php @@ -46,4 +46,19 @@ abstract class AbstractRequest { * @throws \WC_REST_Exception Will throw an exception if the resulting product object is invalid. */ abstract public function prepare_object(); + + /** + * Set meta data. + * + * @param mixed $object Product object reference. + */ + protected function set_meta_data( &$object ) { + $meta_data = $this->get_param( 'meta_data', null ); + + if ( ! is_null( $meta_data ) ) { + foreach ( $meta_data as $meta ) { + $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } } diff --git a/src/Controllers/Version4/Schema/ProductRequest.php b/src/Controllers/Version4/Schema/ProductRequest.php index 8bc30c3aa18..b4f01d34922 100644 --- a/src/Controllers/Version4/Schema/ProductRequest.php +++ b/src/Controllers/Version4/Schema/ProductRequest.php @@ -236,21 +236,6 @@ class ProductRequest extends AbstractRequest { } } - /** - * Set meta data. - * - * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object reference. - */ - protected function set_meta_data( &$object ) { - $meta_data = $this->get_param( 'meta_data', null ); - - if ( ! is_null( $meta_data ) ) { - foreach ( $meta_data as $meta ) { - $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - } - /** * Set product object's attributes. * From b6dc7b745fe4d4e21c3db2af60777894b6b4b577 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 15:04:43 +0100 Subject: [PATCH 146/440] Order request/response --- src/Controllers/Version4/Orders.php | 487 +----------------- .../Version4/Schema/OrderRequest.php | 387 ++++++++++++++ .../Version4/Schema/OrderResponse.php | 183 +++++++ .../Version4/Schema/ProductRequest.php | 16 +- 4 files changed, 594 insertions(+), 479 deletions(-) create mode 100644 src/Controllers/Version4/Schema/OrderRequest.php create mode 100644 src/Controllers/Version4/Schema/OrderResponse.php diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index 762741ffff0..2da5eab1caa 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -11,6 +11,9 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use WooCommerce\RestApi\Controllers\Version4\Schema\OrderRequest; +use WooCommerce\RestApi\Controllers\Version4\Schema\OrderResponse; + /** * REST API Orders controller class. */ @@ -112,99 +115,6 @@ class Orders extends AbstractObjectsController { return $data; } - /** - * Get formatted item data. - * - * @since 3.0.0 - * @param \WC_Data $object WC_Data instance. - * @return array - */ - protected function get_formatted_item_data( $object ) { - $data = $object->get_data(); - $format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' ); - $format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' ); - $format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $datetime = $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - // Format the order status. - $data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status']; - - // Format line items. - foreach ( $format_line_items as $key ) { - $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); - } - - // Refunds. - $data['refunds'] = array(); - foreach ( $object->get_refunds() as $refund ) { - $data['refunds'][] = array( - 'id' => $refund->get_id(), - 'reason' => $refund->get_reason() ? $refund->get_reason() : '', - 'total' => '-' . wc_format_decimal( $refund->get_amount(), $this->request['dp'] ), - ); - } - - // Currency symbols. - $currency_symbol = get_woocommerce_currency_symbol( $data['currency'] ); - $data['currency_symbol'] = html_entity_decode( $currency_symbol ); - - return array( - 'id' => $object->get_id(), - 'parent_id' => $data['parent_id'], - 'number' => $data['number'], - 'order_key' => $data['order_key'], - 'created_via' => $data['created_via'], - 'version' => $data['version'], - 'status' => $data['status'], - 'currency' => $data['currency'], - 'currency_symbol' => $data['currency_symbol'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'discount_total' => $data['discount_total'], - 'discount_tax' => $data['discount_tax'], - 'shipping_total' => $data['shipping_total'], - 'shipping_tax' => $data['shipping_tax'], - 'cart_tax' => $data['cart_tax'], - 'total' => $data['total'], - 'total_tax' => $data['total_tax'], - 'prices_include_tax' => $data['prices_include_tax'], - 'customer_id' => $data['customer_id'], - 'customer_ip_address' => $data['customer_ip_address'], - 'customer_user_agent' => $data['customer_user_agent'], - 'customer_note' => $data['customer_note'], - 'billing' => $data['billing'], - 'shipping' => $data['shipping'], - 'payment_method' => $data['payment_method'], - 'payment_method_title' => $data['payment_method_title'], - 'transaction_id' => $data['transaction_id'], - 'date_paid' => $data['date_paid'], - 'date_paid_gmt' => $data['date_paid_gmt'], - 'date_completed' => $data['date_completed'], - 'date_completed_gmt' => $data['date_completed_gmt'], - 'cart_hash' => $data['cart_hash'], - 'meta_data' => $data['meta_data'], - 'line_items' => $data['line_items'], - 'tax_lines' => $data['tax_lines'], - 'shipping_lines' => $data['shipping_lines'], - 'fee_lines' => $data['fee_lines'], - 'coupon_lines' => $data['coupon_lines'], - 'refunds' => $data['refunds'], - ); - } - /** * Prepare a single order output for response. * @@ -214,13 +124,17 @@ class Orders extends AbstractObjectsController { * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { - $this->request = $request; - $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); - $data = $this->get_formatted_item_data( $object ); - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $order_response = new OrderResponse(); + + if ( ! is_null( $request['dp'] ) ) { + $order_response->set_dp( $request['dp'] ); + } + + $data = $order_response->prepare_response( $object, $context ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); $response->add_links( $this->prepare_links( $object, $request ) ); /** @@ -239,7 +153,7 @@ class Orders extends AbstractObjectsController { /** * Prepare links for the request. * - * @param \WC_Data $object Object data. + * @param \WC_Data $object Object data. * @param \WP_REST_Request $request Request object. * @return array Links for the given post. */ @@ -364,17 +278,6 @@ class Orders extends AbstractObjectsController { return $args; } - /** - * Only return writable props from schema. - * - * @param array $schema Schema. - * @return bool - */ - protected function filter_writable_props( $schema ) { - return empty( $schema['readonly'] ); - } - - /** * Prepare a single order for create or update. * @@ -384,54 +287,11 @@ class Orders extends AbstractObjectsController { * @return \WP_Error|\WC_Data */ protected function prepare_object_for_database( $request, $creating = false ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $order = new \WC_Order( $id ); - $schema = $this->get_item_schema(); - $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - - // Handle all writable props. - foreach ( $data_keys as $key ) { - $value = $request[ $key ]; - - if ( ! is_null( $value ) ) { - switch ( $key ) { - case 'coupon_lines': - case 'status': - // Change should be done later so transitions have new data. - break; - case 'billing': - case 'shipping': - $this->update_address( $order, $value, $key ); - break; - case 'line_items': - case 'shipping_lines': - case 'fee_lines': - if ( is_array( $value ) ) { - foreach ( $value as $item ) { - if ( is_array( $item ) ) { - if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { - $order->remove_item( $item['id'] ); - } else { - $this->set_item( $order, $key, $item ); - } - } - } - } - break; - case 'meta_data': - if ( is_array( $value ) ) { - foreach ( $value as $meta ) { - $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - break; - default: - if ( is_callable( array( $order, "set_{$key}" ) ) ) { - $order->{"set_{$key}"}( $value ); - } - break; - } - } + try { + $order_request = new OrderRequest( $request ); + $order = $order_request->prepare_object(); + } catch ( \WC_REST_Exception $e ) { + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } /** @@ -466,18 +326,6 @@ class Orders extends AbstractObjectsController { // Make sure gateways are loaded so hooks from gateways fire on save/create. WC()->payment_gateways(); - if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { - // Make sure customer exists. - if ( false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); - } - - // Make sure customer is part of blog. - if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { - add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); - } - } - if ( $creating ) { $object->set_created_via( 'rest-api' ); $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); @@ -489,21 +337,11 @@ class Orders extends AbstractObjectsController { } } - // Set coupons. - $this->calculate_coupons( $request, $object ); - - // Set status. - if ( ! empty( $request['status'] ) ) { - $object->set_status( $request['status'] ); - } - $object->save(); // Actions for after the order is saved. - if ( true === $request['set_paid'] ) { - if ( $creating || $object->needs_payment() ) { - $object->payment_complete( $request['transaction_id'] ); - } + if ( true === $request['set_paid'] && ( $creating || $object->needs_payment() ) ) { + $object->payment_complete(); } return $this->get_object( $object->get_id() ); @@ -514,249 +352,6 @@ class Orders extends AbstractObjectsController { } } - /** - * Update address. - * - * @param WC_Order $order Order data. - * @param array $posted Posted data. - * @param string $type Address type. - */ - protected function update_address( $order, $posted, $type = 'billing' ) { - foreach ( $posted as $key => $value ) { - if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { - $order->{"set_{$type}_{$key}"}( $value ); - } - } - } - - /** - * Gets the product ID from the SKU or posted ID. - * - * @param array $posted Request data. - * @return int - * @throws \WC_REST_Exception When SKU or ID is not valid. - */ - protected function get_product_id( $posted ) { - if ( ! empty( $posted['sku'] ) ) { - $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); - } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { - $product_id = (int) $posted['product_id']; - } elseif ( ! empty( $posted['variation_id'] ) ) { - $product_id = (int) $posted['variation_id']; - } else { - throw new \WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); - } - return $product_id; - } - - /** - * Maybe set an item prop if the value was posted. - * - * @param WC_Order_Item $item Order item. - * @param string $prop Order property. - * @param array $posted Request data. - */ - protected function maybe_set_item_prop( $item, $prop, $posted ) { - if ( isset( $posted[ $prop ] ) ) { - $item->{"set_$prop"}( $posted[ $prop ] ); - } - } - - /** - * Maybe set item props if the values were posted. - * - * @param WC_Order_Item $item Order item data. - * @param string[] $props Properties. - * @param array $posted Request data. - */ - protected function maybe_set_item_props( $item, $props, $posted ) { - foreach ( $props as $prop ) { - $this->maybe_set_item_prop( $item, $prop, $posted ); - } - } - - /** - * Maybe set item meta if posted. - * - * @param WC_Order_Item $item Order item data. - * @param array $posted Request data. - */ - protected function maybe_set_item_meta_data( $item, $posted ) { - if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { - foreach ( $posted['meta_data'] as $meta ) { - if ( isset( $meta['key'] ) ) { - $value = isset( $meta['value'] ) ? $meta['value'] : null; - $item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - } - } - - /** - * Create or update a line item. - * - * @param array $posted Line item data. - * @param string $action 'create' to add line item or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Product - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_line_items( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new \WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - $product = wc_get_product( $this->get_product_id( $posted ) ); - - if ( $product !== $item->get_product() ) { - $item->set_product( $product ); - - if ( 'create' === $action ) { - $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; - $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); - $item->set_total( $total ); - $item->set_subtotal( $total ); - } - } - - $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Create or update an order shipping method. - * - * @param array $posted $shipping Item data. - * @param string $action 'create' to add shipping or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return \WC_Order_Item_Shipping - * @throws \WC_REST_Exception Invalid data, server error. - */ - protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new \WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - - if ( 'create' === $action ) { - if ( empty( $posted['method_id'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Create or update an order fee. - * - * @param array $posted Item data. - * @param string $action 'create' to add fee or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return \WC_Order_Item_Fee - * @throws \WC_REST_Exception Invalid data, server error. - */ - protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new \WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - - if ( 'create' === $action ) { - if ( empty( $posted['name'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Create or update an order coupon. - * - * @param array $posted Item data. - * @param string $action 'create' to add coupon or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return \WC_Order_Item_Coupon - * @throws \WC_REST_Exception Invalid data, server error. - */ - protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new \WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - - if ( 'create' === $action ) { - if ( empty( $posted['code'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Wrapper method to create/update order items. - * When updating, the item ID provided is checked to ensure it is associated - * with the order. - * - * @param \WC_Order $order order object. - * @param string $item_type The item type. - * @param array $posted item provided in the request body. - * @throws \WC_REST_Exception If item ID is not associated with order. - */ - protected function set_item( $order, $item_type, $posted ) { - global $wpdb; - - if ( ! empty( $posted['id'] ) ) { - $action = 'update'; - } else { - $action = 'create'; - } - - $method = 'prepare_' . $item_type; - $item = null; - - // Verify provided line item ID is associated with order. - if ( 'update' === $action ) { - $item = $order->get_item( absint( $posted['id'] ), false ); - - if ( ! $item ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); - } - } - - // Prepare item data. - $item = $this->$method( $posted, $action, $item ); - - do_action( 'woocommerce_rest_set_order_item', $item, $posted ); - - // If creating the order, add the item to it. - if ( 'create' === $action ) { - $order->add_item( $item ); - } else { - $item->save(); - } - } - - /** - * Helper method to check if the resource ID associated with the provided item is null. - * Items can be deleted by setting the resource ID to null. - * - * @param array $item Item provided in the request body. - * @return bool True if the item resource ID is null, false otherwise. - */ - protected function item_is_null( $item ) { - $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); - - foreach ( $keys as $key ) { - if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { - return true; - } - } - - return false; - } - /** * Get order statuses without prefixes. * @@ -1663,42 +1258,4 @@ class Orders extends AbstractObjectsController { return $params; } - - /** - * Calculate coupons. - * - * @throws \WC_REST_Exception When fails to set any item. - * - * @param \WP_REST_Request $request Request object. - * @param \WC_Order $order Order data. - * @return bool - */ - protected function calculate_coupons( $request, $order ) { - if ( ! isset( $request['coupon_lines'] ) || ! is_array( $request['coupon_lines'] ) ) { - return false; - } - - // Remove all coupons first to ensure calculation is correct. - foreach ( $order->get_items( 'coupon' ) as $coupon ) { - $order->remove_coupon( $coupon->get_code() ); - } - - foreach ( $request['coupon_lines'] as $item ) { - if ( is_array( $item ) ) { - if ( empty( $item['id'] ) ) { - if ( empty( $item['code'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); - } - - $results = $order->apply_coupon( wc_clean( $item['code'] ) ); - - if ( is_wp_error( $results ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); - } - } - } - } - - return true; - } } diff --git a/src/Controllers/Version4/Schema/OrderRequest.php b/src/Controllers/Version4/Schema/OrderRequest.php new file mode 100644 index 00000000000..f1a8d57b70f --- /dev/null +++ b/src/Controllers/Version4/Schema/OrderRequest.php @@ -0,0 +1,387 @@ +get_param( 'id', 0 ); + $object = new \WC_Order( $id ); + + $this->set_props( $object ); + $this->set_meta_data( $object ); + $this->set_line_items( $object ); + $this->calculate_coupons( $object ); + + return $object; + } + + /** + * Set order props. + * + * @param \WC_Order $object Order object reference. + */ + protected function set_props( &$object ) { + $props = [ + 'parent_id', + 'currency', + 'customer_id', + 'customer_note', + 'payment_method', + 'payment_method_title', + 'transaction_id', + 'billing', + 'shipping', + 'status', + ]; + + $request_props = array_intersect_key( $this->request, array_flip( $props ) ); + $prop_values = []; + + foreach ( $request_props as $prop => $value ) { + switch ( $prop ) { + case 'customer_id': + $prop_values[ $prop ] = $this->parse_customer_id_field( $value ); + break; + case 'billing': + case 'shipping': + $address = $this->parse_address_field( $value, $object, $prop ); + $prop_values = array_merge( $prop_values, $address ); + break; + default: + $prop_values[ $prop ] = $value; + } + } + + foreach ( $prop_values as $prop => $value ) { + $object->{"set_$prop"}( $value ); + } + } + + /** + * Set order line items. + * + * @param \WC_Order $object Order object reference. + */ + protected function set_line_items( &$object ) { + $types = [ + 'line_items', + 'shipping_lines', + 'fee_lines', + ]; + + foreach ( $types as $type ) { + if ( ! isset( $this->request[ $type ] ) || ! is_array( $this->request[ $type ] ) ) { + continue; + } + $items = $this->request[ $type ]; + + foreach ( $items as $item ) { + if ( ! is_array( $item ) ) { + continue; + } + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $object->remove_item( $item['id'] ); + } else { + $this->set_item( $object, $type, $item ); + } + } + } + } + + /** + * Helper method to check if the resource ID associated with the provided item is null. + * Items can be deleted by setting the resource ID to null. + * + * @param array $item Item provided in the request body. + * @return bool True if the item resource ID is null, false otherwise. + */ + protected function item_is_null( $item ) { + $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); + + foreach ( $keys as $key ) { + if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { + return true; + } + } + + return false; + } + + /** + * Maybe set an item prop if the value was posted. + * + * @param WC_Order_Item $item Order item. + * @param string $prop Order property. + * @param array $posted Request data. + */ + protected function maybe_set_item_prop( $item, $prop, $posted ) { + if ( isset( $posted[ $prop ] ) ) { + $item->{"set_$prop"}( $posted[ $prop ] ); + } + } + + /** + * Maybe set item props if the values were posted. + * + * @param WC_Order_Item $item Order item data. + * @param string[] $props Properties. + * @param array $posted Request data. + */ + protected function maybe_set_item_props( $item, $props, $posted ) { + foreach ( $props as $prop ) { + $this->maybe_set_item_prop( $item, $prop, $posted ); + } + } + + /** + * Maybe set item meta if posted. + * + * @param WC_Order_Item $item Order item data. + * @param array $posted Request data. + */ + protected function maybe_set_item_meta_data( $item, $posted ) { + if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { + foreach ( $posted['meta_data'] as $meta ) { + if ( isset( $meta['key'] ) ) { + $value = isset( $meta['value'] ) ? $meta['value'] : null; + $item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } + } + + /** + * Gets the product ID from the SKU or posted ID. + * + * @param array $posted Request data. + * @return int + * @throws \WC_REST_Exception When SKU or ID is not valid. + */ + protected function get_product_id_from_line_item( $posted ) { + if ( ! empty( $posted['sku'] ) ) { + $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); + } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['product_id']; + } elseif ( ! empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['variation_id']; + } else { + throw new \WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + } + return $product_id; + } + + /** + * Create or update a line item. + * + * @param array $posted Line item data. + * @param string $action 'create' to add line item or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Product + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_line_items( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new \WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + $product = wc_get_product( $this->get_product_id_from_line_item( $posted ) ); + + if ( $product !== $item->get_product() ) { + $item->set_product( $product ); + + if ( 'create' === $action ) { + $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; + $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); + $item->set_total( $total ); + $item->set_subtotal( $total ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Create or update an order shipping method. + * + * @param array $posted $shipping Item data. + * @param string $action 'create' to add shipping or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return \WC_Order_Item_Shipping + * @throws \WC_REST_Exception Invalid data, server error. + */ + protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new \WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + + if ( 'create' === $action ) { + if ( empty( $posted['method_id'] ) ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Create or update an order fee. + * + * @param array $posted Item data. + * @param string $action 'create' to add fee or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return \WC_Order_Item_Fee + * @throws \WC_REST_Exception Invalid data, server error. + */ + protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new \WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + + if ( 'create' === $action ) { + if ( empty( $posted['name'] ) ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Wrapper method to create/update order items. + * When updating, the item ID provided is checked to ensure it is associated + * with the order. + * + * @param \WC_Order $order order object. + * @param string $item_type The item type. + * @param array $posted item provided in the request body. + * @throws \WC_REST_Exception If item ID is not associated with order. + */ + protected function set_item( &$order, $item_type, $posted ) { + if ( ! empty( $posted['id'] ) ) { + $action = 'update'; + } else { + $action = 'create'; + } + + $method = 'prepare_' . $item_type; + $item = null; + + // Verify provided line item ID is associated with order. + if ( 'update' === $action ) { + $item = $order->get_item( absint( $posted['id'] ), false ); + + if ( ! $item ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + } + } + + // Prepare item data. + $item = $this->$method( $posted, $action, $item ); + + do_action( 'woocommerce_rest_set_order_item', $item, $posted ); + + // If creating the order, add the item to it. + if ( 'create' === $action ) { + $order->add_item( $item ); + } else { + $item->save(); + } + } + + /** + * Parse address data. + * + * @param array $data Posted data. + * @param \WC_Order $object Order object reference. + * @param string $type Address type. + * @return array + */ + protected function parse_address_field( $data, $object, $type = 'billing' ) { + $address = []; + foreach ( $data as $key => $value ) { + if ( is_callable( array( $object, "set_{$type}_{$key}" ) ) ) { + $address[ "{$type}_{$key}" ] = $value; + } + } + return $address; + } + + /** + * Parse customer ID. + * + * @throws \WC_REST_Exception Will throw an exception if the customer is invalid. + * @param int $customer_id Customer ID to set. + * @return int + */ + protected function parse_customer_id_field( $customer_id ) { + if ( 0 !== $customer_id ) { + // Make sure customer exists. + if ( false === get_user_by( 'id', $customer_id ) ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $customer_id ) ) { + add_user_to_blog( get_current_blog_id(), $customer_id, 'customer' ); + } + } + return $customer_id; + } + + /** + * Calculate coupons. + * + * @throws \WC_REST_Exception When fails to set any item. + * + * @param \WC_Order $order Order data. + * @return bool + */ + protected function calculate_coupons( &$order ) { + $coupon_lines = $this->get_param( 'coupon_lines', false ); + + if ( ! is_array( $coupon_lines ) ) { + return false; + } + + // Remove all coupons first to ensure calculation is correct. + foreach ( $order->get_items( 'coupon' ) as $coupon ) { + $order->remove_coupon( $coupon->get_code() ); + } + + foreach ( $coupon_lines as $item ) { + if ( is_array( $item ) ) { + if ( empty( $item['id'] ) ) { + if ( empty( $item['code'] ) ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + + $results = $order->apply_coupon( wc_clean( $item['code'] ) ); + + if ( is_wp_error( $results ) ) { + throw new \WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); + } + } + } + } + + return true; + } +} diff --git a/src/Controllers/Version4/Schema/OrderResponse.php b/src/Controllers/Version4/Schema/OrderResponse.php new file mode 100644 index 00000000000..8cfc40cac54 --- /dev/null +++ b/src/Controllers/Version4/Schema/OrderResponse.php @@ -0,0 +1,183 @@ +dp = wc_get_price_decimals(); + } + + /** + * Set decimal places. + * + * @param int $dp Decimals. + */ + public function set_dp( $dp ) { + $this->dp = (int) $dp; + } + + /** + * Convert object to match data in the schema. + * + * @param \WC_Order $object Product data. + * @param string $context Request context. Options: 'view' and 'edit'. + * @return array + */ + public function prepare_response( $object, $context ) { + $data = $object->get_data(); + $format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' ); + $format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' ); + $format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->dp ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format the order status. + $data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status']; + + // Format line items. + foreach ( $format_line_items as $key ) { + $data[ $key ] = array_values( array_map( array( $this, 'prepare_order_item_data' ), $data[ $key ] ) ); + } + + // Refunds. + $data['refunds'] = array(); + foreach ( $object->get_refunds() as $refund ) { + $data['refunds'][] = array( + 'id' => $refund->get_id(), + 'reason' => $refund->get_reason() ? $refund->get_reason() : '', + 'total' => '-' . wc_format_decimal( $refund->get_amount(), $this->dp ), + ); + } + + // Currency symbols. + $currency_symbol = get_woocommerce_currency_symbol( $data['currency'] ); + $data['currency_symbol'] = html_entity_decode( $currency_symbol ); + + return array( + 'id' => $object->get_id(), + 'parent_id' => $data['parent_id'], + 'number' => $data['number'], + 'order_key' => $data['order_key'], + 'created_via' => $data['created_via'], + 'version' => $data['version'], + 'status' => $data['status'], + 'currency' => $data['currency'], + 'currency_symbol' => $data['currency_symbol'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_total' => $data['discount_total'], + 'discount_tax' => $data['discount_tax'], + 'shipping_total' => $data['shipping_total'], + 'shipping_tax' => $data['shipping_tax'], + 'cart_tax' => $data['cart_tax'], + 'total' => $data['total'], + 'total_tax' => $data['total_tax'], + 'prices_include_tax' => $data['prices_include_tax'], + 'customer_id' => $data['customer_id'], + 'customer_ip_address' => $data['customer_ip_address'], + 'customer_user_agent' => $data['customer_user_agent'], + 'customer_note' => $data['customer_note'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'payment_method' => $data['payment_method'], + 'payment_method_title' => $data['payment_method_title'], + 'transaction_id' => $data['transaction_id'], + 'date_paid' => $data['date_paid'], + 'date_paid_gmt' => $data['date_paid_gmt'], + 'date_completed' => $data['date_completed'], + 'date_completed_gmt' => $data['date_completed_gmt'], + 'cart_hash' => $data['cart_hash'], + 'meta_data' => $data['meta_data'], + 'line_items' => $data['line_items'], + 'tax_lines' => $data['tax_lines'], + 'shipping_lines' => $data['shipping_lines'], + 'fee_lines' => $data['fee_lines'], + 'coupon_lines' => $data['coupon_lines'], + 'refunds' => $data['refunds'], + ); + } + + /** + * Expands an order item to get its data. + * + * @param \WC_Order_item $item Order item data. + * @return array + */ + protected function prepare_order_item_data( $item ) { + $data = $item->get_data(); + $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + if ( isset( $data[ $key ] ) ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->dp ); + } + } + + // Add SKU and PRICE to products. + if ( is_callable( array( $item, 'get_product' ) ) ) { + $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; + $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; + } + + // Format taxes. + if ( ! empty( $data['taxes']['total'] ) ) { + $taxes = array(); + + foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { + $taxes[] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', + ); + } + $data['taxes'] = $taxes; + } elseif ( isset( $data['taxes'] ) ) { + $data['taxes'] = array(); + } + + // Remove names for coupons, taxes and shipping. + if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { + unset( $data['name'] ); + } + + // Remove props we don't want to expose. + unset( $data['order_id'] ); + unset( $data['type'] ); + + return $data; + } +} diff --git a/src/Controllers/Version4/Schema/ProductRequest.php b/src/Controllers/Version4/Schema/ProductRequest.php index b4f01d34922..95a0921ea9d 100644 --- a/src/Controllers/Version4/Schema/ProductRequest.php +++ b/src/Controllers/Version4/Schema/ProductRequest.php @@ -144,10 +144,10 @@ class ProductRequest extends AbstractRequest { $prop_values = array_merge( $prop_values, $images ); break; case 'categories': - $prop_values['category_ids'] = $this->parse_terms_field( $value ); + $prop_values['category_ids'] = wp_list_pluck( $value, 'id' ); break; case 'tags': - $prop_values['tag_ids'] = $this->parse_terms_field( $value ); + $prop_values['tag_ids'] = wp_list_pluck( $value, 'id' ); break; case 'attributes': $prop_values['attributes'] = $this->parse_attributes_field( $value ); @@ -246,7 +246,6 @@ class ProductRequest extends AbstractRequest { $attributes = array(); foreach ( $raw_attributes as $attribute ) { - // Check ID for global attributes or name for product attributes. if ( ! empty( $attribute['id'] ) ) { $attribute_id = absint( $attribute['id'] ); $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); @@ -260,7 +259,6 @@ class ProductRequest extends AbstractRequest { } if ( ! is_array( $attribute['options'] ) ) { - // Text based attributes - Posted values are term names. $attribute['options'] = explode( \WC_DELIMITER, $attribute['options'] ); } @@ -405,16 +403,6 @@ class ProductRequest extends AbstractRequest { return $files; } - /** - * Save taxonomy terms. - * - * @param array $terms Terms data. - * @return array - */ - protected function parse_terms_field( $terms ) { - return wp_list_pluck( $terms, 'id' ); - } - /** * Save default attributes. * From ab42dc41b39a4edd40ef1857a1a522d8e7882896 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 15:23:55 +0100 Subject: [PATCH 147/440] ImageAttachment utility --- .../Version4/Schema/ProductRequest.php | 45 +++------ .../Schema/ProductVariationRequest.php | 33 ++----- src/Utilities/ImageAttachment.php | 93 +++++++++++++++++++ 3 files changed, 114 insertions(+), 57 deletions(-) create mode 100644 src/Utilities/ImageAttachment.php diff --git a/src/Controllers/Version4/Schema/ProductRequest.php b/src/Controllers/Version4/Schema/ProductRequest.php index 95a0921ea9d..0be60ff2142 100644 --- a/src/Controllers/Version4/Schema/ProductRequest.php +++ b/src/Controllers/Version4/Schema/ProductRequest.php @@ -9,6 +9,8 @@ namespace WooCommerce\RestApi\Controllers\Version4\Schema; defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Utilities\ImageAttachment; + /** * ProductRequest class. */ @@ -300,45 +302,24 @@ class ProductRequest extends AbstractRequest { foreach ( $images as $index => $image ) { $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + $attachment = new ImageAttachment( $attachment_id, $object->get_id() ); - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), $images ) ) { - throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); - } else { - continue; - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); + if ( 0 === $attachment->id && ! empty( $image['src'] ) ) { + $attachment->upload_image_from_src( $image['src'] ); } - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: image ID */ - throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + if ( ! empty( $image['alt'] ) ) { + $attachment->update_alt_text( $image['alt'] ); + } + + if ( ! empty( $image['name'] ) ) { + $attachment->update_name( $image['name'] ); } if ( 0 === $index ) { - $response['image_id'] = $attachment_id; + $response['image_id'] = $attachment->id; } else { - $response['gallery_image_ids'][] = $attachment_id; - } - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); + $response['gallery_image_ids'][] = $attachment->id; } } diff --git a/src/Controllers/Version4/Schema/ProductVariationRequest.php b/src/Controllers/Version4/Schema/ProductVariationRequest.php index 186a953b266..4f9d98fb8ab 100644 --- a/src/Controllers/Version4/Schema/ProductVariationRequest.php +++ b/src/Controllers/Version4/Schema/ProductVariationRequest.php @@ -9,6 +9,8 @@ namespace WooCommerce\RestApi\Controllers\Version4\Schema; defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Utilities\ImageAttachment; + /** * ProductVariationRequest class. */ @@ -167,39 +169,20 @@ class ProductVariationRequest extends ProductRequest { } $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + $attachment = new ImageAttachment( $attachment_id, $object->get_id() ); - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), array( $image ) ) ) { - throw new \WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $object->get_id() ); + if ( 0 === $attachment->id && ! empty( $image['src'] ) ) { + $attachment->upload_image_from_src( $image['src'] ); } - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: attachment ID */ - throw new \WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); - } - - // Set the image alt if present. if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + $attachment->update_alt_text( $image['alt'] ); } - // Set the image name if present. if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); + $attachment->update_name( $image['name'] ); } - return $attachment_id; + return $attachment->id; } } diff --git a/src/Utilities/ImageAttachment.php b/src/Utilities/ImageAttachment.php new file mode 100644 index 00000000000..27367fa535a --- /dev/null +++ b/src/Utilities/ImageAttachment.php @@ -0,0 +1,93 @@ +id = (int) $id; + $this->object_id = (int) $object_id; + } + + /** + * Upload an attachment file. + * + * @throws \WC_REST_Exception REST API exceptions. + * @param string $src URL to file. + */ + public function upload_image_from_src( $src ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $src ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), $images ) ) { + throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + return; + } + } + + $this->id = wc_rest_set_uploaded_image_as_attachment( $upload, $this->object_id ); + + if ( ! wp_attachment_is_image( $this->id ) ) { + /* translators: %s: image ID */ + throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $this->attachment_id ), 400 ); + } + } + + /** + * Update attachment alt text. + * + * @param string $text Text to set. + */ + public function update_alt_text( $text ) { + if ( ! $this->id ) { + return; + } + update_post_meta( $this->id, '_wp_attachment_image_alt', wc_clean( $text ) ); + } + + /** + * Update attachment name. + * + * @param string $text Text to set. + */ + public function update_name( $text ) { + if ( ! $this->id ) { + return; + } + wp_update_post( + array( + 'ID' => $this->id, + 'post_title' => $text, + ) + ); + } +} From 31131bf500e8391944d8b7b4fd1bce3f2d9075e1 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 15:29:11 +0100 Subject: [PATCH 148/440] wrong property --- src/Utilities/ImageAttachment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utilities/ImageAttachment.php b/src/Utilities/ImageAttachment.php index 27367fa535a..14408376a0a 100644 --- a/src/Utilities/ImageAttachment.php +++ b/src/Utilities/ImageAttachment.php @@ -58,7 +58,7 @@ class ImageAttachment { if ( ! wp_attachment_is_image( $this->id ) ) { /* translators: %s: image ID */ - throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $this->attachment_id ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $this->id ), 400 ); } } From 6176aaf12c1dfbedbe246cb7842d064663fe20c6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 17:30:31 +0100 Subject: [PATCH 149/440] Break up system status into utilities --- src/Controllers/Version4/Orders.php | 4 +- .../Version4/ProductVariations.php | 4 +- src/Controllers/Version4/Products.php | 4 +- .../AbstractObjectRequest.php} | 6 +- .../{Schema => Requests}/OrderRequest.php | 24 +- .../{Schema => Requests}/ProductRequest.php | 4 +- .../ProductVariationRequest.php | 2 +- .../AbstractObjectResponse.php} | 6 +- .../{Schema => Responses}/OrderResponse.php | 4 +- .../{Schema => Responses}/ProductResponse.php | 4 +- .../ProductVariationResponse.php | 2 +- src/Controllers/Version4/SystemStatus.php | 685 +----------------- src/Utilities/DatabaseInformation.php | 118 +++ src/Utilities/PluginInformation.php | 149 ++++ src/Utilities/ServerEnvironment.php | 187 +++++ src/Utilities/ThemeInformation.php | 96 +++ src/Utilities/WPEnvironment.php | 115 +++ src/Utilities/WooEnvironment.php | 59 ++ 18 files changed, 775 insertions(+), 698 deletions(-) rename src/Controllers/Version4/{Schema/AbstractRequest.php => Requests/AbstractObjectRequest.php} (91%) rename src/Controllers/Version4/{Schema => Requests}/OrderRequest.php (94%) rename src/Controllers/Version4/{Schema => Requests}/ProductRequest.php (99%) rename src/Controllers/Version4/{Schema => Requests}/ProductVariationRequest.php (98%) rename src/Controllers/Version4/{Schema/AbstractResponse.php => Responses/AbstractObjectResponse.php} (74%) rename src/Controllers/Version4/{Schema => Responses}/OrderResponse.php (98%) rename src/Controllers/Version4/{Schema => Responses}/ProductResponse.php (99%) rename src/Controllers/Version4/{Schema => Responses}/ProductVariationResponse.php (98%) create mode 100644 src/Utilities/DatabaseInformation.php create mode 100644 src/Utilities/PluginInformation.php create mode 100644 src/Utilities/ServerEnvironment.php create mode 100644 src/Utilities/ThemeInformation.php create mode 100644 src/Utilities/WPEnvironment.php create mode 100644 src/Utilities/WooEnvironment.php diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index 2da5eab1caa..caf8061ba4c 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -11,8 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Schema\OrderRequest; -use WooCommerce\RestApi\Controllers\Version4\Schema\OrderResponse; +use WooCommerce\RestApi\Controllers\Version4\Requests\OrderRequest; +use WooCommerce\RestApi\Controllers\Version4\Responses\OrderResponse; /** * REST API Orders controller class. diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index 1e501b20398..868adecc3cd 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -11,8 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Schema\ProductVariationRequest; -use WooCommerce\RestApi\Controllers\Version4\Schema\ProductVariationResponse; +use WooCommerce\RestApi\Controllers\Version4\Requests\ProductVariationRequest; +use WooCommerce\RestApi\Controllers\Version4\Responses\ProductVariationResponse; /** * REST API variations controller class. diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 14937eb7cbc..7b4e0b09d2c 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -11,8 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Schema\ProductRequest; -use WooCommerce\RestApi\Controllers\Version4\Schema\ProductResponse; +use WooCommerce\RestApi\Controllers\Version4\Requests\ProductRequest; +use WooCommerce\RestApi\Controllers\Version4\Responses\ProductResponse; /** * REST API Products controller class. diff --git a/src/Controllers/Version4/Schema/AbstractRequest.php b/src/Controllers/Version4/Requests/AbstractObjectRequest.php similarity index 91% rename from src/Controllers/Version4/Schema/AbstractRequest.php rename to src/Controllers/Version4/Requests/AbstractObjectRequest.php index e7b64799477..f3d6b984ebb 100644 --- a/src/Controllers/Version4/Schema/AbstractRequest.php +++ b/src/Controllers/Version4/Requests/AbstractObjectRequest.php @@ -5,14 +5,14 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Schema; +namespace WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; /** - * AbstractRequest class. + * AbstractObjectRequest class. */ -abstract class AbstractRequest { +abstract class AbstractObjectRequest { /** * Request data. diff --git a/src/Controllers/Version4/Schema/OrderRequest.php b/src/Controllers/Version4/Requests/OrderRequest.php similarity index 94% rename from src/Controllers/Version4/Schema/OrderRequest.php rename to src/Controllers/Version4/Requests/OrderRequest.php index f1a8d57b70f..7593182a2b1 100644 --- a/src/Controllers/Version4/Schema/OrderRequest.php +++ b/src/Controllers/Version4/Requests/OrderRequest.php @@ -5,14 +5,14 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Schema; +namespace WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; /** * OrderRequest class. */ -class OrderRequest extends AbstractRequest { +class OrderRequest extends AbstractObjectRequest { /** * Convert request to object. @@ -126,9 +126,9 @@ class OrderRequest extends AbstractRequest { /** * Maybe set an item prop if the value was posted. * - * @param WC_Order_Item $item Order item. - * @param string $prop Order property. - * @param array $posted Request data. + * @param \WC_Order_Item $item Order item. + * @param string $prop Order property. + * @param array $posted Request data. */ protected function maybe_set_item_prop( $item, $prop, $posted ) { if ( isset( $posted[ $prop ] ) ) { @@ -139,9 +139,9 @@ class OrderRequest extends AbstractRequest { /** * Maybe set item props if the values were posted. * - * @param WC_Order_Item $item Order item data. - * @param string[] $props Properties. - * @param array $posted Request data. + * @param \WC_Order_Item $item Order item data. + * @param string[] $props Properties. + * @param array $posted Request data. */ protected function maybe_set_item_props( $item, $props, $posted ) { foreach ( $props as $prop ) { @@ -152,8 +152,8 @@ class OrderRequest extends AbstractRequest { /** * Maybe set item meta if posted. * - * @param WC_Order_Item $item Order item data. - * @param array $posted Request data. + * @param \WC_Order_Item $item Order item data. + * @param array $posted Request data. */ protected function maybe_set_item_meta_data( $item, $posted ) { if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { @@ -192,8 +192,8 @@ class OrderRequest extends AbstractRequest { * @param array $posted Line item data. * @param string $action 'create' to add line item or 'update' to update it. * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Product - * @throws WC_REST_Exception Invalid data, server error. + * @return \WC_Order_Item_Product + * @throws \WC_REST_Exception Invalid data, server error. */ protected function prepare_line_items( $posted, $action = 'create', $item = null ) { $item = is_null( $item ) ? new \WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; diff --git a/src/Controllers/Version4/Schema/ProductRequest.php b/src/Controllers/Version4/Requests/ProductRequest.php similarity index 99% rename from src/Controllers/Version4/Schema/ProductRequest.php rename to src/Controllers/Version4/Requests/ProductRequest.php index 0be60ff2142..892055cd680 100644 --- a/src/Controllers/Version4/Schema/ProductRequest.php +++ b/src/Controllers/Version4/Requests/ProductRequest.php @@ -5,7 +5,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Schema; +namespace WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; @@ -14,7 +14,7 @@ use \WooCommerce\RestApi\Utilities\ImageAttachment; /** * ProductRequest class. */ -class ProductRequest extends AbstractRequest { +class ProductRequest extends AbstractObjectRequest { /** * Convert request to object. diff --git a/src/Controllers/Version4/Schema/ProductVariationRequest.php b/src/Controllers/Version4/Requests/ProductVariationRequest.php similarity index 98% rename from src/Controllers/Version4/Schema/ProductVariationRequest.php rename to src/Controllers/Version4/Requests/ProductVariationRequest.php index 4f9d98fb8ab..75d5b9922e1 100644 --- a/src/Controllers/Version4/Schema/ProductVariationRequest.php +++ b/src/Controllers/Version4/Requests/ProductVariationRequest.php @@ -5,7 +5,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Schema; +namespace WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Schema/AbstractResponse.php b/src/Controllers/Version4/Responses/AbstractObjectResponse.php similarity index 74% rename from src/Controllers/Version4/Schema/AbstractResponse.php rename to src/Controllers/Version4/Responses/AbstractObjectResponse.php index 0e49e14700f..174a16ab833 100644 --- a/src/Controllers/Version4/Schema/AbstractResponse.php +++ b/src/Controllers/Version4/Responses/AbstractObjectResponse.php @@ -5,14 +5,14 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Schema; +namespace WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; /** - * AbstractResponse class. + * AbstractObjectResponse class. */ -abstract class AbstractResponse { +abstract class AbstractObjectResponse { /** * Convert object to match data in the schema. diff --git a/src/Controllers/Version4/Schema/OrderResponse.php b/src/Controllers/Version4/Responses/OrderResponse.php similarity index 98% rename from src/Controllers/Version4/Schema/OrderResponse.php rename to src/Controllers/Version4/Responses/OrderResponse.php index 8cfc40cac54..83dadbd2238 100644 --- a/src/Controllers/Version4/Schema/OrderResponse.php +++ b/src/Controllers/Version4/Responses/OrderResponse.php @@ -5,14 +5,14 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Schema; +namespace WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; /** * OrderResponse class. */ -class OrderResponse extends AbstractResponse { +class OrderResponse extends AbstractObjectResponse { /** * Decimal places to round to. diff --git a/src/Controllers/Version4/Schema/ProductResponse.php b/src/Controllers/Version4/Responses/ProductResponse.php similarity index 99% rename from src/Controllers/Version4/Schema/ProductResponse.php rename to src/Controllers/Version4/Responses/ProductResponse.php index b85da38eb06..cb8dd981d75 100644 --- a/src/Controllers/Version4/Schema/ProductResponse.php +++ b/src/Controllers/Version4/Responses/ProductResponse.php @@ -5,14 +5,14 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Schema; +namespace WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; /** * ProductResponse class. */ -class ProductResponse extends AbstractResponse { +class ProductResponse extends AbstractObjectResponse { /** * Convert object to match data in the schema. diff --git a/src/Controllers/Version4/Schema/ProductVariationResponse.php b/src/Controllers/Version4/Responses/ProductVariationResponse.php similarity index 98% rename from src/Controllers/Version4/Schema/ProductVariationResponse.php rename to src/Controllers/Version4/Responses/ProductVariationResponse.php index e2f155b36eb..744f63dcbcc 100644 --- a/src/Controllers/Version4/Schema/ProductVariationResponse.php +++ b/src/Controllers/Version4/Responses/ProductVariationResponse.php @@ -5,7 +5,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Schema; +namespace WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index 60ac351b5c2..a0de8867075 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -23,13 +23,6 @@ class SystemStatus extends AbstractController { */ protected $rest_base = 'system_status'; - /** - * Store available updates. - * - * @var array - */ - protected $available_updates = array(); - /** * Register the route for /system_status */ @@ -75,12 +68,6 @@ class SystemStatus extends AbstractController { $response = array(); foreach ( $mappings as $section => $values ) { - foreach ( $values as $key => $value ) { - if ( isset( $schema['properties'][ $section ]['properties'][ $key ]['type'] ) ) { - settype( $values[ $key ], $schema['properties'][ $section ]['properties'][ $key ]['type'] ); - } - } - settype( $values, $schema['properties'][ $section ]['type'] ); $response[ $section ] = $values; } @@ -573,660 +560,27 @@ class SystemStatus extends AbstractController { * @return array */ public function get_item_mappings() { - return array( - 'environment' => $this->get_environment_info(), - 'database' => $this->get_database_info(), - 'active_plugins' => $this->get_active_plugins(), - 'inactive_plugins' => $this->get_inactive_plugins(), - 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(), - 'theme' => $this->get_theme_info(), - 'settings' => $this->get_settings(), - 'security' => $this->get_security_info(), - 'pages' => $this->get_pages(), - 'post_type_counts' => $this->get_post_type_counts(), - ); - } - - /** - * Get array of environment information. Includes thing like software - * versions, and various server settings. - * - * @return array - */ - public function get_environment_info() { - $post_request = $this->test_post_request(); - $get_request = $this->test_get_request(); - $database_version = wc_get_server_database_version(); - - // Return all environment info. Described by JSON Schema. - return array( - 'home_url' => get_option( 'home' ), - 'site_url' => get_option( 'siteurl' ), - 'version' => WC()->version, - 'log_directory' => WC_LOG_DIR, - 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore - 'wp_version' => get_bloginfo( 'version' ), - 'wp_multisite' => is_multisite(), - 'wp_memory_limit' => $this->get_wp_memory_limit(), - 'wp_debug_mode' => $this->is_constant_true( 'WP_DEBUG' ), - 'wp_cron' => ! $this->is_constant_true( 'DISABLE_WP_CRON' ), - 'language' => get_locale(), - 'external_object_cache' => wp_using_ext_object_cache(), - 'server_info' => $this->get_server_software(), - 'php_version' => phpversion(), - 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), - 'php_max_execution_time' => ini_get( 'max_execution_time' ), - 'php_max_input_vars' => ini_get( 'max_input_vars' ), - 'curl_version' => $this->get_curl_version(), - 'suhosin_installed' => extension_loaded( 'suhosin' ), - 'max_upload_size' => wp_max_upload_size(), - 'mysql_version' => $database_version['number'], - 'mysql_version_string' => $database_version['string'], - 'default_timezone' => date_default_timezone_get(), - 'fsockopen_or_curl_enabled' => $this->fsockopen_or_curl_enabled(), - 'soapclient_enabled' => class_exists( 'SoapClient' ), - 'domdocument_enabled' => class_exists( 'DOMDocument' ), - 'gzip_enabled' => is_callable( 'gzopen' ), - 'mbstring_enabled' => extension_loaded( 'mbstring' ), - 'remote_post_successful' => $post_request['success'], - 'remote_post_response' => $post_request['response'], - 'remote_get_successful' => $get_request['success'], - 'remote_get_response' => $get_request['response'], - ); - } - - /** - * Test POST to an external server. - * - * @return array - */ - protected function test_post_request() { - $post_response_code = get_transient( 'woocommerce_test_remote_post' ); - - if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { - $response = wp_safe_remote_post( - 'https://www.paypal.com/cgi-bin/webscr', - array( - 'timeout' => 10, - 'user-agent' => 'WooCommerce/' . WC()->version, - 'httpversion' => '1.1', - 'body' => array( - 'cmd' => '_notify-validate', - ), - ) - ); - if ( ! is_wp_error( $response ) ) { - $post_response_code = $response['response']['code']; - } - set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); - } - - if ( is_wp_error( $post_response_code ) ) { - return array( - 'success' => false, - 'response' => $post_response_code->get_error_message(), - ); - } + $plugin_info = new \WooCommerce\RestApi\Utilities\PluginInformation(); + $theme_info = new \WooCommerce\RestApi\Utilities\ThemeInformation(); + $server = new \WooCommerce\RestApi\Utilities\ServerEnvironment(); + $database = new \WooCommerce\RestApi\Utilities\DatabaseInformation(); + $wp_environment = new \WooCommerce\RestApi\Utilities\WPEnvironment(); + $woo_environment = new \WooCommerce\RestApi\Utilities\WooEnvironment(); return array( - 'success' => $post_response_code >= 200 && $post_response_code < 300, - 'response' => $post_response_code, + 'environment' => $server->get_environment_info(), + 'database' => $database->get_database_info(), + 'active_plugins' => $plugin_info->get_active_plugin_data(), + 'inactive_plugins' => $plugin_info->get_inactive_plugin_data(), + 'dropins_mu_plugins' => $plugin_info->get_dropin_and_mu_plugin_data(), + 'theme' => $theme_info->get_theme_info(), + 'settings' => $woo_environment->get_settings(), + 'security' => $wp_environment->get_security_info(), + 'pages' => $wp_environment->get_pages(), + 'post_type_counts' => $wp_environment->get_post_type_counts(), ); } - /** - * Test GET to an external server. - * - * @return array - */ - protected function test_get_request() { - $get_response_code = get_transient( 'woocommerce_test_remote_get' ); - - if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { - $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); - if ( ! is_wp_error( $response ) ) { - $get_response_code = $response['response']['code']; - } - set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); - } - - if ( is_wp_error( $get_response_code ) ) { - return array( - 'success' => false, - 'response' => $get_response_code->get_error_message(), - ); - } - - return array( - 'success' => $get_response_code >= 200 && $get_response_code < 300, - 'response' => $get_response_code, - ); - } - - /** - * Return if a constant is defined and true. - * - * @param string $name Constant name. - * @return bool - */ - protected function is_constant_true( $name ) { - return defined( $name ) && (bool) constant( $name ); - } - - /** - * Return info about server software running. - * - * @return string - */ - protected function get_server_software() { - return isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : ''; - } - - /** - * Get CURL version running on server. - * - * @return string - */ - protected function get_curl_version() { - $curl_version = ''; - if ( function_exists( 'curl_version' ) ) { - $curl_version = curl_version(); - $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; - } elseif ( extension_loaded( 'curl' ) ) { - $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); - } - return $curl_version; - } - - /** - * Get WP memory limit. - * - * @return string - */ - protected function get_wp_memory_limit() { - $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); - if ( function_exists( 'memory_get_usage' ) ) { - $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); - } - return (string) $wp_memory_limit; - } - - /** - * See if modules are enabled. - * - * @return bool - */ - protected function fsockopen_or_curl_enabled() { - return function_exists( 'fsockopen' ) || function_exists( 'curl_init' ); - } - - /** - * Add prefix to table. - * - * @param string $table Table name. - * @return stromg - */ - protected function add_db_table_prefix( $table ) { - global $wpdb; - return $wpdb->prefix . $table; - } - - /** - * Get array of database information. Version, prefix, and table existence. - * - * @return array - */ - public function get_database_info() { - global $wpdb; - - $database_table_information = $wpdb->get_results( - $wpdb->prepare( - "SELECT - table_name AS 'name', - engine, - round( ( data_length / 1024 / 1024 ), 2 ) 'data', - round( ( index_length / 1024 / 1024 ), 2 ) 'index' - FROM information_schema.TABLES - WHERE table_schema = %s - ORDER BY name ASC;", - DB_NAME - ) - ); - - // WC Core tables to check existence of. - $core_tables = apply_filters( - 'woocommerce_database_tables', - array( - 'woocommerce_sessions', - 'woocommerce_api_keys', - 'woocommerce_attribute_taxonomies', - 'woocommerce_downloadable_product_permissions', - 'woocommerce_order_items', - 'woocommerce_order_itemmeta', - 'woocommerce_tax_rates', - 'woocommerce_tax_rate_locations', - 'woocommerce_shipping_zones', - 'woocommerce_shipping_zone_locations', - 'woocommerce_shipping_zone_methods', - 'woocommerce_payment_tokens', - 'woocommerce_payment_tokenmeta', - 'woocommerce_log', - ) - ); - - /** - * Adding the prefix to the tables array, for backwards compatibility. - * - * If we changed the tables above to include the prefix, then any filters against that table could break. - */ - $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); - - /** - * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. - * - * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. - */ - $tables = array( - 'woocommerce' => array_fill_keys( $core_tables, false ), - 'other' => array(), - ); - - $database_size = array( - 'data' => 0, - 'index' => 0, - ); - - $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); - $global_tables = $wpdb->tables( 'global', true ); - foreach ( $database_table_information as $table ) { - // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. - if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { - continue; - } - $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; - - $tables[ $table_type ][ $table->name ] = array( - 'data' => $table->data, - 'index' => $table->index, - 'engine' => $table->engine, - ); - - $database_size['data'] += $table->data; - $database_size['index'] += $table->index; - } - - // Return all database info. Described by JSON Schema. - return array( - 'wc_database_version' => get_option( 'woocommerce_db_version' ), - 'database_prefix' => $wpdb->prefix, - 'maxmind_geoip_database' => \WC_Geolocation::get_local_database_path(), - 'database_tables' => $tables, - 'database_size' => $database_size, - ); - } - - /** - * Get array of counts of objects. Orders, products, etc. - * - * @return array - */ - public function get_post_type_counts() { - global $wpdb; - - $post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" ); - - return is_array( $post_type_counts ) ? $post_type_counts : array(); - } - - /** - * Get a list of plugins active on the site. - * - * @return array - */ - public function get_active_plugins() { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - if ( ! function_exists( 'get_plugin_data' ) ) { - return array(); - } - - $active_plugins = (array) get_option( 'active_plugins', array() ); - if ( is_multisite() ) { - $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); - $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); - } - - $active_plugins_data = array(); - - foreach ( $active_plugins as $plugin ) { - $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); - $active_plugins_data[] = $this->format_plugin_data( $plugin, $data ); - } - - return $active_plugins_data; - } - - /** - * Get a list of inplugins active on the site. - * - * @return array - */ - public function get_inactive_plugins() { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - if ( ! function_exists( 'get_plugins' ) ) { - return array(); - } - - $plugins = get_plugins(); - $active_plugins = (array) get_option( 'active_plugins', array() ); - - if ( is_multisite() ) { - $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); - $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); - } - - $plugins_data = array(); - - foreach ( $plugins as $plugin => $data ) { - if ( in_array( $plugin, $active_plugins, true ) ) { - continue; - } - $plugins_data[] = $this->format_plugin_data( $plugin, $data ); - } - - return $plugins_data; - } - - /** - * Format plugin data, including data on updates, into a standard format. - * - * @since 3.6.0 - * @param string $plugin Plugin directory/file. - * @param array $data Plugin data from WP. - * @return array Formatted data. - */ - protected function format_plugin_data( $plugin, $data ) { - require_once ABSPATH . 'wp-admin/includes/update.php'; - - if ( ! function_exists( 'get_plugin_updates' ) ) { - return array(); - } - - // Use WP API to lookup latest updates for plugins. WC_Helper injects updates for premium plugins. - if ( empty( $this->available_updates ) ) { - $this->available_updates = get_plugin_updates(); - } - - $version_latest = $data['Version']; - - // Find latest version. - if ( isset( $this->available_updates[ $plugin ]->update->new_version ) ) { - $version_latest = $this->available_updates[ $plugin ]->update->new_version; - } - - return array( - 'plugin' => $plugin, - 'name' => $data['Name'], - 'version' => $data['Version'], - 'version_latest' => $version_latest, - 'url' => $data['PluginURI'], - 'author_name' => $data['AuthorName'], - 'author_url' => esc_url_raw( $data['AuthorURI'] ), - 'network_activated' => $data['Network'], - ); - } - - /** - * Get a list of Dropins and MU plugins. - * - * @since 3.6.0 - * @return array - */ - public function get_dropins_mu_plugins() { - $dropins = get_dropins(); - $plugins = array( - 'dropins' => array(), - 'mu_plugins' => array(), - ); - foreach ( $dropins as $key => $dropin ) { - $plugins['dropins'][] = array( - 'plugin' => $key, - 'name' => $dropin['Name'], - ); - } - - $mu_plugins = get_mu_plugins(); - foreach ( $mu_plugins as $plugin => $mu_plugin ) { - $plugins['mu_plugins'][] = array( - 'plugin' => $plugin, - 'name' => $mu_plugin['Name'], - 'version' => $mu_plugin['Version'], - 'url' => $mu_plugin['PluginURI'], - 'author_name' => $mu_plugin['AuthorName'], - 'author_url' => esc_url_raw( $mu_plugin['AuthorURI'] ), - ); - } - return $plugins; - } - - /** - * Get info on the current active theme, info on parent theme (if presnet) - * and a list of template overrides. - * - * @return array - */ - public function get_theme_info() { - $active_theme = wp_get_theme(); - - // Get parent theme info if this theme is a child theme, otherwise - // pass empty info in the response. - if ( is_child_theme() ) { - $parent_theme = wp_get_theme( $active_theme->template ); - $parent_theme_info = array( - 'parent_name' => $parent_theme->name, - 'parent_version' => $parent_theme->version, - 'parent_version_latest' => \WC_Admin_Status::get_latest_theme_version( $parent_theme ), - 'parent_author_url' => $parent_theme->{'Author URI'}, - ); - } else { - $parent_theme_info = array( - 'parent_name' => '', - 'parent_version' => '', - 'parent_version_latest' => '', - 'parent_author_url' => '', - ); - } - - /** - * Scan the theme directory for all WC templates to see if our theme - * overrides any of them. - */ - $override_files = array(); - $outdated_templates = false; - $scan_files = \WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); - foreach ( $scan_files as $file ) { - $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' ); - - if ( file_exists( $located ) ) { - $theme_file = $located; - } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { - $theme_file = get_stylesheet_directory() . '/' . $file; - } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { - $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; - } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { - $theme_file = get_template_directory() . '/' . $file; - } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { - $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; - } else { - $theme_file = false; - } - - if ( ! empty( $theme_file ) ) { - $core_version = \WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); - $theme_version = \WC_Admin_Status::get_file_version( $theme_file ); - if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { - if ( ! $outdated_templates ) { - $outdated_templates = true; - } - } - $override_files[] = array( - 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), - 'version' => $theme_version, - 'core_version' => $core_version, - ); - } - } - - $active_theme_info = array( - 'name' => $active_theme->name, - 'version' => $active_theme->version, - 'version_latest' => \WC_Admin_Status::get_latest_theme_version( $active_theme ), - 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), - 'is_child_theme' => is_child_theme(), - 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), - 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), - 'has_outdated_templates' => $outdated_templates, - 'overrides' => $override_files, - ); - - return array_merge( $active_theme_info, $parent_theme_info ); - } - - /** - * Get some setting values for the site that are useful for debugging - * purposes. For full settings access, use the settings api. - * - * @return array - */ - public function get_settings() { - // Get a list of terms used for product/order taxonomies. - $term_response = array(); - $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); - foreach ( $terms as $term ) { - $term_response[ $term->slug ] = strtolower( $term->name ); - } - - // Get a list of terms used for product visibility. - $product_visibility_terms = array(); - $terms = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) ); - foreach ( $terms as $term ) { - $product_visibility_terms[ $term->slug ] = strtolower( $term->name ); - } - - // Check if WooCommerce.com account is connected. - $woo_com_connected = 'no'; - $helper_options = get_option( 'woocommerce_helper_data', array() ); - if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) { - $woo_com_connected = 'yes'; - } - - // Return array of useful settings for debugging. - return array( - 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ), - 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ), - 'currency' => get_woocommerce_currency(), - 'currency_symbol' => get_woocommerce_currency_symbol(), - 'currency_position' => get_option( 'woocommerce_currency_pos' ), - 'thousand_separator' => wc_get_price_thousand_separator(), - 'decimal_separator' => wc_get_price_decimal_separator(), - 'number_of_decimals' => wc_get_price_decimals(), - 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ), - 'taxonomies' => $term_response, - 'product_visibility_terms' => $product_visibility_terms, - 'woocommerce_com_connected' => $woo_com_connected, - ); - } - - /** - * Returns security tips. - * - * @return array - */ - public function get_security_info() { - $check_page = wc_get_page_permalink( 'shop' ); - return array( - 'secure_connection' => 'https' === substr( $check_page, 0, 5 ), - 'hide_errors' => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), - ); - } - - /** - * Returns a mini-report on WC pages and if they are configured correctly: - * Present, visible, and including the correct shortcode. - * - * @return array - */ - public function get_pages() { - // WC pages to check against. - $check_pages = array( - _x( 'Shop base', 'Page setting', 'woocommerce' ) => array( - 'option' => 'woocommerce_shop_page_id', - 'shortcode' => '', - ), - _x( 'Cart', 'Page setting', 'woocommerce' ) => array( - 'option' => 'woocommerce_cart_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', - ), - _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( - 'option' => 'woocommerce_checkout_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', - ), - _x( 'My account', 'Page setting', 'woocommerce' ) => array( - 'option' => 'woocommerce_myaccount_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', - ), - _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( - 'option' => 'woocommerce_terms_page_id', - 'shortcode' => '', - ), - ); - - $pages_output = array(); - foreach ( $check_pages as $page_name => $values ) { - $page_id = get_option( $values['option'] ); - $page_set = false; - $page_exists = false; - $page_visible = false; - $shortcode_present = false; - $shortcode_required = false; - - // Page checks. - if ( $page_id ) { - $page_set = true; - } - if ( get_post( $page_id ) ) { - $page_exists = true; - } - if ( 'publish' === get_post_status( $page_id ) ) { - $page_visible = true; - } - - // Shortcode checks. - if ( $values['shortcode'] && get_post( $page_id ) ) { - $shortcode_required = true; - $page = get_post( $page_id ); - if ( strstr( $page->post_content, $values['shortcode'] ) ) { - $shortcode_present = true; - } - } - - // Wrap up our findings into an output array. - $pages_output[] = array( - 'page_name' => $page_name, - 'page_id' => $page_id, - 'page_set' => $page_set, - 'page_exists' => $page_exists, - 'page_visible' => $page_visible, - 'shortcode' => $values['shortcode'], - 'shortcode_required' => $shortcode_required, - 'shortcode_present' => $shortcode_present, - ); - } - - return $pages_output; - } - /** * Get any query params needed. * @@ -1241,14 +595,13 @@ class SystemStatus extends AbstractController { /** * Prepare the system status response * - * @param array $system_status System status data. + * @param array $system_status System status data. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response */ public function prepare_item_for_response( $system_status, $request ) { - $data = $this->add_additional_fields_to_object( $system_status, $request ); - $data = $this->filter_response_by_context( $data, 'view' ); - + $data = $this->add_additional_fields_to_object( $system_status, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); $response = rest_ensure_response( $data ); /** diff --git a/src/Utilities/DatabaseInformation.php b/src/Utilities/DatabaseInformation.php new file mode 100644 index 00000000000..caed00ecfaf --- /dev/null +++ b/src/Utilities/DatabaseInformation.php @@ -0,0 +1,118 @@ +prefix . $table; + } + + /** + * Get array of database information. Version, prefix, and table existence. + * + * @return array + */ + public function get_database_info() { + global $wpdb; + + $database_table_information = $wpdb->get_results( + $wpdb->prepare( + "SELECT + table_name AS 'name', + engine, + round( ( data_length / 1024 / 1024 ), 2 ) 'data', + round( ( index_length / 1024 / 1024 ), 2 ) 'index' + FROM information_schema.TABLES + WHERE table_schema = %s + ORDER BY name ASC;", + DB_NAME + ) + ); + + // WC Core tables to check existence of. + $core_tables = apply_filters( + 'woocommerce_database_tables', + array( + 'woocommerce_sessions', + 'woocommerce_api_keys', + 'woocommerce_attribute_taxonomies', + 'woocommerce_downloadable_product_permissions', + 'woocommerce_order_items', + 'woocommerce_order_itemmeta', + 'woocommerce_tax_rates', + 'woocommerce_tax_rate_locations', + 'woocommerce_shipping_zones', + 'woocommerce_shipping_zone_locations', + 'woocommerce_shipping_zone_methods', + 'woocommerce_payment_tokens', + 'woocommerce_payment_tokenmeta', + 'woocommerce_log', + ) + ); + + /** + * Adding the prefix to the tables array, for backwards compatibility. + * + * If we changed the tables above to include the prefix, then any filters against that table could break. + */ + $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); + + /** + * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. + * + * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. + */ + $tables = array( + 'woocommerce' => array_fill_keys( $core_tables, false ), + 'other' => array(), + ); + + $database_size = array( + 'data' => 0, + 'index' => 0, + ); + + $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); + $global_tables = $wpdb->tables( 'global', true ); + foreach ( $database_table_information as $table ) { + // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. + if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { + continue; + } + $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; + + $tables[ $table_type ][ $table->name ] = array( + 'data' => $table->data, + 'index' => $table->index, + 'engine' => $table->engine, + ); + + $database_size['data'] += $table->data; + $database_size['index'] += $table->index; + } + + // Return all database info. Described by JSON Schema. + return array( + 'wc_database_version' => get_option( 'woocommerce_db_version' ), + 'database_prefix' => $wpdb->prefix, + 'maxmind_geoip_database' => \WC_Geolocation::get_local_database_path(), + 'database_tables' => $tables, + 'database_size' => $database_size, + ); + } +} diff --git a/src/Utilities/PluginInformation.php b/src/Utilities/PluginInformation.php new file mode 100644 index 00000000000..925d44ca121 --- /dev/null +++ b/src/Utilities/PluginInformation.php @@ -0,0 +1,149 @@ +available_updates = get_plugin_updates(); + } + + /** + * Get formatted active plugin data. + * + * @return array + */ + public function get_active_plugin_data() { + return array_map( [ $this, 'format_plugin_data' ], array_map( [ $this, 'get_plugin_data' ], $this->get_active_plugins() ) ); + } + + /** + * Get formatted inactive plugin data. + * + * @return array + */ + public function get_inactive_plugin_data() { + return array_map( [ $this, 'format_plugin_data' ], array_map( [ $this, 'get_plugin_data' ], $this->get_inactive_plugins() ) ); + } + + /** + * Get a list of Dropins and MU plugins. + * + * @since 3.6.0 + * @return array + */ + public function get_dropin_and_mu_plugin_data() { + $plugins = [ + 'dropins' => [], + 'mu_plugins' => [], + ]; + + foreach ( get_dropins() as $plugin => $data ) { + $data['plugin_file'] = $plugin; + $plugins['dropins'][] = $this->format_plugin_data( $data ); + } + + foreach ( get_mu_plugins() as $plugin => $data ) { + $data['plugin_file'] = $plugin; + $plugins['mu_plugins'][] = $this->format_plugin_data( $data ); + } + + return $plugins; + } + + /** + * Get a list of plugins active on the site. + * + * @return array + */ + protected function get_active_plugins() { + $active_plugins = (array) get_option( 'active_plugins', array() ); + + if ( is_multisite() ) { + $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); + } + + return $active_plugins; + } + + /** + * Get a list of inplugins active on the site. + * + * @return array + */ + protected function get_inactive_plugins() { + $plugins = get_plugins(); + $active_plugins = $this->get_active_plugins(); + $inactive_plugins = []; + + foreach ( $plugins as $plugin => $data ) { + if ( in_array( $plugin, $active_plugins, true ) ) { + continue; + } + $inactive_plugins[] = $plugin; + } + + return $inactive_plugins; + } + + /** + * Undocumented function + * + * @param string $plugin Plugin directory/file. + * @return array Data. + */ + protected function get_plugin_data( $plugin ) { + $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + $data['plugin_file'] = $plugin; + return $data; + } + + /** + * Format plugin data, including data on updates, into a standard format. + * + * @param array $data Plugin data. + * @return array Formatted data. + */ + protected function format_plugin_data( $data ) { + $version_latest = $data['Version']; + + // Find latest version. + if ( isset( $this->available_updates[ $data['plugin_file'] ]->update->new_version ) ) { + $version_latest = $this->available_updates[ $data['plugin_file'] ]->update->new_version; + } + + return array( + 'plugin' => $data['plugin_file'], + 'name' => $data['Name'], + 'version' => $data['Version'], + 'version_latest' => $version_latest, + 'url' => $data['PluginURI'], + 'author_name' => $data['AuthorName'], + 'author_url' => esc_url_raw( $data['AuthorURI'] ), + 'network_activated' => $data['Network'], + ); + } +} diff --git a/src/Utilities/ServerEnvironment.php b/src/Utilities/ServerEnvironment.php new file mode 100644 index 00000000000..7bf4207ec46 --- /dev/null +++ b/src/Utilities/ServerEnvironment.php @@ -0,0 +1,187 @@ +test_post_request(); + $get_request = $this->test_get_request(); + $database_version = wc_get_server_database_version(); + + // Return all environment info. Described by JSON Schema. + return array( + 'home_url' => get_option( 'home' ), + 'site_url' => get_option( 'siteurl' ), + 'version' => WC()->version, + 'log_directory' => \WC_LOG_DIR, + 'log_directory_writable' => (bool) @fopen( \WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore + 'wp_version' => get_bloginfo( 'version' ), + 'wp_multisite' => is_multisite(), + 'wp_memory_limit' => $this->get_wp_memory_limit(), + 'wp_debug_mode' => $this->is_constant_true( 'WP_DEBUG' ), + 'wp_cron' => ! $this->is_constant_true( 'DISABLE_WP_CRON' ), + 'language' => get_locale(), + 'external_object_cache' => wp_using_ext_object_cache(), + 'server_info' => $this->get_server_software(), + 'php_version' => phpversion(), + 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), + 'php_max_execution_time' => ini_get( 'max_execution_time' ), + 'php_max_input_vars' => ini_get( 'max_input_vars' ), + 'curl_version' => $this->get_curl_version(), + 'suhosin_installed' => extension_loaded( 'suhosin' ), + 'max_upload_size' => wp_max_upload_size(), + 'mysql_version' => $database_version['number'], + 'mysql_version_string' => $database_version['string'], + 'default_timezone' => date_default_timezone_get(), + 'fsockopen_or_curl_enabled' => $this->fsockopen_or_curl_enabled(), + 'soapclient_enabled' => class_exists( 'SoapClient' ), + 'domdocument_enabled' => class_exists( 'DOMDocument' ), + 'gzip_enabled' => is_callable( 'gzopen' ), + 'mbstring_enabled' => extension_loaded( 'mbstring' ), + 'remote_post_successful' => $post_request['success'], + 'remote_post_response' => $post_request['response'], + 'remote_get_successful' => $get_request['success'], + 'remote_get_response' => $get_request['response'], + ); + } + + /** + * Test POST to an external server. + * + * @return array + */ + protected function test_post_request() { + $post_response_code = get_transient( 'woocommerce_test_remote_post' ); + + if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { + $response = wp_safe_remote_post( + 'https://www.paypal.com/cgi-bin/webscr', + array( + 'timeout' => 10, + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', + 'body' => array( + 'cmd' => '_notify-validate', + ), + ) + ); + if ( ! is_wp_error( $response ) ) { + $post_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); + } + + if ( is_wp_error( $post_response_code ) ) { + return array( + 'success' => false, + 'response' => $post_response_code->get_error_message(), + ); + } + + return array( + 'success' => $post_response_code >= 200 && $post_response_code < 300, + 'response' => $post_response_code, + ); + } + + /** + * Test GET to an external server. + * + * @return array + */ + protected function test_get_request() { + $get_response_code = get_transient( 'woocommerce_test_remote_get' ); + + if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { + $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); + if ( ! is_wp_error( $response ) ) { + $get_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); + } + + if ( is_wp_error( $get_response_code ) ) { + return array( + 'success' => false, + 'response' => $get_response_code->get_error_message(), + ); + } + + return array( + 'success' => $get_response_code >= 200 && $get_response_code < 300, + 'response' => $get_response_code, + ); + } + + /** + * Return if a constant is defined and true. + * + * @param string $name Constant name. + * @return bool + */ + protected function is_constant_true( $name ) { + return defined( $name ) && (bool) constant( $name ); + } + + /** + * Return info about server software running. + * + * @return string + */ + protected function get_server_software() { + return isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : ''; + } + + /** + * Get CURL version running on server. + * + * @return string + */ + protected function get_curl_version() { + $curl_version = ''; + if ( function_exists( 'curl_version' ) ) { + $curl_version = curl_version(); + $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; + } elseif ( extension_loaded( 'curl' ) ) { + $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); + } + return $curl_version; + } + + /** + * Get WP memory limit. + * + * @return string + */ + protected function get_wp_memory_limit() { + $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); + if ( function_exists( 'memory_get_usage' ) ) { + $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); + } + return (string) $wp_memory_limit; + } + + /** + * See if modules are enabled. + * + * @return bool + */ + protected function fsockopen_or_curl_enabled() { + return function_exists( 'fsockopen' ) || function_exists( 'curl_init' ); + } + +} diff --git a/src/Utilities/ThemeInformation.php b/src/Utilities/ThemeInformation.php new file mode 100644 index 00000000000..001f2849d0b --- /dev/null +++ b/src/Utilities/ThemeInformation.php @@ -0,0 +1,96 @@ +template ); + $parent_theme_info = array( + 'parent_name' => $parent_theme->name, + 'parent_version' => $parent_theme->version, + 'parent_version_latest' => \WC_Admin_Status::get_latest_theme_version( $parent_theme ), + 'parent_author_url' => $parent_theme->{'Author URI'}, + ); + } else { + $parent_theme_info = array( + 'parent_name' => '', + 'parent_version' => '', + 'parent_version_latest' => '', + 'parent_author_url' => '', + ); + } + + /** + * Scan the theme directory for all WC templates to see if our theme + * overrides any of them. + */ + $override_files = array(); + $outdated_templates = false; + $scan_files = \WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); + foreach ( $scan_files as $file ) { + $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' ); + + if ( file_exists( $located ) ) { + $theme_file = $located; + } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . $file; + } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; + } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { + $theme_file = get_template_directory() . '/' . $file; + } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; + } else { + $theme_file = false; + } + + if ( ! empty( $theme_file ) ) { + $core_version = \WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); + $theme_version = \WC_Admin_Status::get_file_version( $theme_file ); + if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { + if ( ! $outdated_templates ) { + $outdated_templates = true; + } + } + $override_files[] = array( + 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), + 'version' => $theme_version, + 'core_version' => $core_version, + ); + } + } + + $active_theme_info = array( + 'name' => $active_theme->name, + 'version' => $active_theme->version, + 'version_latest' => \WC_Admin_Status::get_latest_theme_version( $active_theme ), + 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), + 'is_child_theme' => is_child_theme(), + 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), + 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), + 'has_outdated_templates' => $outdated_templates, + 'overrides' => $override_files, + ); + + return array_merge( $active_theme_info, $parent_theme_info ); + } +} diff --git a/src/Utilities/WPEnvironment.php b/src/Utilities/WPEnvironment.php new file mode 100644 index 00000000000..88d0571aa66 --- /dev/null +++ b/src/Utilities/WPEnvironment.php @@ -0,0 +1,115 @@ + 'https' === substr( $check_page, 0, 5 ), + 'hide_errors' => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), + ); + } + + /** + * Get array of counts of objects. Orders, products, etc. + * + * @return array + */ + public function get_post_type_counts() { + global $wpdb; + + $post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" ); + + return is_array( $post_type_counts ) ? $post_type_counts : array(); + } + + /** + * Returns a mini-report on WC pages and if they are configured correctly: + * Present, visible, and including the correct shortcode. + * + * @return array + */ + public function get_pages() { + // WC pages to check against. + $check_pages = array( + _x( 'Shop base', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_shop_page_id', + 'shortcode' => '', + ), + _x( 'Cart', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_cart_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', + ), + _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_checkout_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', + ), + _x( 'My account', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_myaccount_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', + ), + _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_terms_page_id', + 'shortcode' => '', + ), + ); + + $pages_output = array(); + foreach ( $check_pages as $page_name => $values ) { + $page_id = get_option( $values['option'] ); + $page_set = false; + $page_exists = false; + $page_visible = false; + $shortcode_present = false; + $shortcode_required = false; + + // Page checks. + if ( $page_id ) { + $page_set = true; + } + if ( get_post( $page_id ) ) { + $page_exists = true; + } + if ( 'publish' === get_post_status( $page_id ) ) { + $page_visible = true; + } + + // Shortcode checks. + if ( $values['shortcode'] && get_post( $page_id ) ) { + $shortcode_required = true; + $page = get_post( $page_id ); + if ( strstr( $page->post_content, $values['shortcode'] ) ) { + $shortcode_present = true; + } + } + + // Wrap up our findings into an output array. + $pages_output[] = array( + 'page_name' => $page_name, + 'page_id' => $page_id, + 'page_set' => $page_set, + 'page_exists' => $page_exists, + 'page_visible' => $page_visible, + 'shortcode' => $values['shortcode'], + 'shortcode_required' => $shortcode_required, + 'shortcode_present' => $shortcode_present, + ); + } + + return $pages_output; + } +} diff --git a/src/Utilities/WooEnvironment.php b/src/Utilities/WooEnvironment.php new file mode 100644 index 00000000000..47882cf7eff --- /dev/null +++ b/src/Utilities/WooEnvironment.php @@ -0,0 +1,59 @@ + 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + // Get a list of terms used for product visibility. + $product_visibility_terms = array(); + $terms = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $product_visibility_terms[ $term->slug ] = strtolower( $term->name ); + } + + // Check if WooCommerce.com account is connected. + $woo_com_connected = 'no'; + $helper_options = get_option( 'woocommerce_helper_data', array() ); + if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) { + $woo_com_connected = 'yes'; + } + + // Return array of useful settings for debugging. + return array( + 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ), + 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ), + 'currency' => get_woocommerce_currency(), + 'currency_symbol' => get_woocommerce_currency_symbol(), + 'currency_position' => get_option( 'woocommerce_currency_pos' ), + 'thousand_separator' => wc_get_price_thousand_separator(), + 'decimal_separator' => wc_get_price_decimal_separator(), + 'number_of_decimals' => wc_get_price_decimals(), + 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ), + 'taxonomies' => $term_response, + 'product_visibility_terms' => $product_visibility_terms, + 'woocommerce_com_connected' => $woo_com_connected, + ); + } +} From f35e5461fa3ff9479bc581bee8d1b109e20cee58 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 22:44:01 +0100 Subject: [PATCH 150/440] Move permission checks to version4 --- .../Version4/AbstractController.php | 96 +++++++++++++++ .../Version4/AbstractObjectsController.php | 23 ++-- .../AbstractShippingZonesController.php | 40 ++----- .../Version4/AbstractTermsContoller.php | 81 ++----------- src/Controllers/Version4/BatchTrait.php | 2 +- .../Version4/CustomerDownloads.php | 11 +- src/Controllers/Version4/Customers.php | 113 ++---------------- src/Controllers/Version4/Data.php | 35 ++---- src/Controllers/Version4/OrderNotes.php | 10 +- src/Controllers/Version4/PaymentGateways.php | 50 ++------ .../Version4/ProductAttributes.php | 104 ++-------------- src/Controllers/Version4/ProductReviews.php | 100 ++-------------- src/Controllers/Version4/ProductTags.php | 2 +- .../Version4/ProductVariations.php | 5 +- src/Controllers/Version4/Products.php | 3 +- src/Controllers/Version4/Settings.php | 36 ++---- src/Controllers/Version4/SettingsOptions.php | 43 ++----- src/Controllers/Version4/ShippingMethods.php | 33 ++--- .../Version4/ShippingZoneLocations.php | 2 +- .../Version4/ShippingZoneMethods.php | 6 +- src/Controllers/Version4/ShippingZones.php | 4 +- src/Controllers/Version4/SystemStatus.php | 20 ++-- .../Version4/SystemStatusTools.php | 46 ++----- src/Controllers/Version4/TaxClasses.php | 51 ++------ src/Controllers/Version4/Taxes.php | 95 ++------------- .../Version4/Utilities/Permissions.php | 110 +++++++++++++++++ .../{ => Utilities}/SettingsTrait.php | 2 +- src/Controllers/Version4/Webhooks.php | 95 ++------------- 28 files changed, 379 insertions(+), 839 deletions(-) create mode 100644 src/Controllers/Version4/Utilities/Permissions.php rename src/Controllers/Version4/{ => Utilities}/SettingsTrait.php (98%) diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index d10479673e2..6d8ef36d718 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -15,6 +15,7 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; use \WP_REST_Controller; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; /** * Abstract Rest Controller Class @@ -40,6 +41,13 @@ abstract class AbstractController extends WP_REST_Controller { */ protected $rest_base = ''; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = ''; + /** * Register route for items requests. * @@ -149,4 +157,92 @@ abstract class AbstractController extends WP_REST_Controller { $schema['properties'] = apply_filters( 'woocommerce_rest_' . $object_type . '_schema', $schema['properties'] ); return $schema; } + + /** + * Check whether a given request has permission to read webhooks. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! Permissions::check_resource( $this->resource_type, 'read' ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access create webhooks. + * + * @param \WP_REST_Request $request Full details about the request. + * + * @return bool|\WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! Permissions::check_resource( $this->resource_type, 'create' ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to read a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + + if ( 0 !== $id && ! Permissions::check_resource( $this->resource_type, 'read', $id ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access update a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * + * @return bool|\WP_Error + */ + public function update_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + + if ( 0 !== $id && ! Permissions::check_resource( $this->resource_type, 'edit', $id ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access delete a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * + * @return bool|\WP_Error + */ + public function delete_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + + if ( 0 !== $id && ! Permissions::check_resource( $this->resource_type, 'delete', $id ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param \WP_REST_Request $request Full details about the request. + * + * @return bool|\WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! Permissions::check_resource( $this->resource_type, 'batch' ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } } diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index f3eb35c278b..fd95fea5d27 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -9,6 +9,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; + /** * CRUD Object Controller. */ @@ -72,7 +74,7 @@ abstract class AbstractObjectsController extends AbstractController { * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'read' ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -86,9 +88,10 @@ abstract class AbstractObjectsController extends AbstractController { * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { - $object = $this->get_object( (int) $request['id'] ); + $id = $request->get_param( 'id' ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { + if ( 0 !== $id && ! Permissions::check_post_object( $this->post_type, 'read', $id ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -102,7 +105,7 @@ abstract class AbstractObjectsController extends AbstractController { * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'create' ) ) { return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -116,9 +119,9 @@ abstract class AbstractObjectsController extends AbstractController { * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { - $object = $this->get_object( (int) $request['id'] ); + $id = $request->get_param( 'id' ); - if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { + if ( 0 !== $id && ! Permissions::check_post_object( $this->post_type, 'edit', $id ) ) { return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -132,9 +135,9 @@ abstract class AbstractObjectsController extends AbstractController { * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { - $object = $this->get_object( (int) $request['id'] ); + $id = $request->get_param( 'id' ); - if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + if ( 0 !== $id && ! Permissions::check_post_object( $this->post_type, 'delete', $id ) ) { return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -149,7 +152,7 @@ abstract class AbstractObjectsController extends AbstractController { * @return boolean|\WP_Error */ public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'batch' ) ) { return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -387,7 +390,7 @@ abstract class AbstractObjectsController extends AbstractController { $objects = array(); foreach ( $query_results['objects'] as $object ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'read', $object->get_id() ) ) { continue; } @@ -452,7 +455,7 @@ abstract class AbstractObjectsController extends AbstractController { $supports_trash = $this->supports_trash( $object ); - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'delete', $object->get_id() ) ) { /* translators: %s: post type */ return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } diff --git a/src/Controllers/Version4/AbstractShippingZonesController.php b/src/Controllers/Version4/AbstractShippingZonesController.php index aa10f02f4a0..42db4365326 100644 --- a/src/Controllers/Version4/AbstractShippingZonesController.php +++ b/src/Controllers/Version4/AbstractShippingZonesController.php @@ -27,6 +27,13 @@ abstract class AbstractShippingZonesController extends AbstractController { */ protected $rest_base = 'shipping/zones'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'settings'; + /** * Retrieve a Shipping Zone by it's ID. * @@ -53,12 +60,7 @@ abstract class AbstractShippingZonesController extends AbstractController { if ( ! wc_shipping_enabled() ) { return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; + return parent::get_items_permissions_check( $request ); } /** @@ -71,12 +73,7 @@ abstract class AbstractShippingZonesController extends AbstractController { if ( ! wc_shipping_enabled() ) { return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; + return parent::create_item_permissions_check( $request ); } /** @@ -85,16 +82,11 @@ abstract class AbstractShippingZonesController extends AbstractController { * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ - public function update_items_permissions_check( $request ) { + public function update_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; + return parent::update_item_permissions_check( $request ); } /** @@ -103,16 +95,10 @@ abstract class AbstractShippingZonesController extends AbstractController { * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ - public function delete_items_permissions_check( $request ) { + public function delete_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; + return parent::delete_item_permissions_check( $request ); } - } diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index 956d83c9474..6ec5b8ee705 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -9,6 +9,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; + /** * Terms controller class. */ @@ -127,15 +129,9 @@ abstract class AbstractTermsContoller extends AbstractController { * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'read' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { + if ( ! Permissions::check_taxonomy( $this->taxonomy, 'read' ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; } @@ -146,15 +142,9 @@ abstract class AbstractTermsContoller extends AbstractController { * @return \WP_Error|boolean */ public function create_item_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'create' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { + if ( ! Permissions::check_taxonomy( $this->taxonomy, 'create' ) ) { return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; } @@ -165,15 +155,11 @@ abstract class AbstractTermsContoller extends AbstractController { * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'read' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } + $id = $request->get_param( 'id' ); - if ( ! $permissions ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + if ( ! Permissions::check_taxonomy( $this->taxonomy, 'read', $id ) ) { + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you are not allowed to view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; } @@ -184,15 +170,11 @@ abstract class AbstractTermsContoller extends AbstractController { * @return \WP_Error|boolean */ public function update_item_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'edit' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } + $id = $request->get_param( 'id' ); - if ( ! $permissions ) { + if ( ! Permissions::check_taxonomy( $this->taxonomy, 'edit', $id ) ) { return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; } @@ -203,15 +185,11 @@ abstract class AbstractTermsContoller extends AbstractController { * @return \WP_Error|boolean */ public function delete_item_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'delete' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } + $id = $request->get_param( 'id' ); - if ( ! $permissions ) { + if ( ! Permissions::check_taxonomy( $this->taxonomy, 'delete', $id ) ) { return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; } @@ -222,47 +200,12 @@ abstract class AbstractTermsContoller extends AbstractController { * @return boolean|\WP_Error */ public function batch_items_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'batch' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { + if ( ! Permissions::check_taxonomy( $this->taxonomy, 'batch' ) ) { return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; } - /** - * Check permissions. - * - * @param \WP_REST_Request $request Full details about the request. - * @param string $context Request context. - * @return bool|\WP_Error - */ - protected function check_permissions( $request, $context = 'read' ) { - // Get taxonomy. - $taxonomy = $this->get_taxonomy( $request ); - if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new \WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - // Check permissions for a single term. - $id = intval( $request['id'] ); - if ( $id ) { - $term = get_term( $id, $taxonomy ); - - if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { - return new \WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id ); - } - - return wc_rest_check_product_term_permissions( $taxonomy, $context ); - } - /** * Get terms associated with a taxonomy. * diff --git a/src/Controllers/Version4/BatchTrait.php b/src/Controllers/Version4/BatchTrait.php index 40a50491d23..5ee4837d75d 100644 --- a/src/Controllers/Version4/BatchTrait.php +++ b/src/Controllers/Version4/BatchTrait.php @@ -59,7 +59,7 @@ trait BatchTrait { * @return boolean|\WP_Error */ public function batch_items_permissions_check( $request ) { - return update_items_permissions_check( $request ); + return update_item_permissions_check( $request ); } /** diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index 588da40d3b5..5b74e38cea7 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; + /** * REST API Customer Downloads controller class. */ @@ -23,6 +25,13 @@ class CustomerDownloads extends AbstractController { */ protected $rest_base = 'customers/(?P[\d]+)/downloads'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'customers'; + /** * Register the routes for customers. */ @@ -43,7 +52,7 @@ class CustomerDownloads extends AbstractController { return new \WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } - if ( ! wc_rest_check_user_permissions( 'read', $customer->ID ) ) { + if ( ! Permissions::user_can( $this->resource_type, 'read', $customer->ID ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 41d6a07f4a8..7d30b4c1db6 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -25,6 +25,13 @@ class Customers extends AbstractController { */ protected $rest_base = 'customers'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'customers'; + /** * Register the routes for customers. */ @@ -47,19 +54,19 @@ class Customers extends AbstractController { $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'email' => array( - 'required' => true, - 'type' => 'string', + 'required' => true, + 'type' => 'string', 'description' => __( 'New user email address.', 'woocommerce' ), ), 'username' => array( - 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), + 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), 'description' => __( 'New user username.', 'woocommerce' ), - 'type' => 'string', + 'type' => 'string', ), 'password' => array( - 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), + 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), 'description' => __( 'New user password.', 'woocommerce' ), - 'type' => 'string', + 'type' => 'string', ), ) ), @@ -118,100 +125,6 @@ class Customers extends AbstractController { $this->register_batch_route(); } - /** - * Check whether a given request has permission to read customers. - * - * @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_user_permissions( 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create customers. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_user_permissions( 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a customer. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = (int) $request['id']; - - if ( ! wc_rest_check_user_permissions( 'read', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access update a customer. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function update_item_permissions_check( $request ) { - $id = (int) $request['id']; - - if ( ! wc_rest_check_user_permissions( 'edit', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a customer. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - $id = (int) $request['id']; - - if ( ! wc_rest_check_user_permissions( 'delete', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_user_permissions( 'batch' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get formatted item data. * diff --git a/src/Controllers/Version4/Data.php b/src/Controllers/Version4/Data.php index 563987e48f5..45be1c8857e 100644 --- a/src/Controllers/Version4/Data.php +++ b/src/Controllers/Version4/Data.php @@ -23,6 +23,13 @@ class Data extends AbstractController { */ protected $rest_base = 'data'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'settings'; + /** * Register routes. * @@ -44,34 +51,6 @@ class Data extends AbstractController { ); } - /** - * Check whether a given request has permission to read site data. - * - * @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( 'settings', '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 site settings. - * - * @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( 'settings', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Return the list of data resources. * diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index 7e3f680266d..5e0ab83ebdd 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; + /** * REST API Order Notes controller class. */ @@ -117,7 +119,7 @@ class OrderNotes extends AbstractController { * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'read' ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -132,7 +134,7 @@ class OrderNotes extends AbstractController { * @return bool|\WP_Error */ public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'create' ) ) { return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -148,7 +150,7 @@ class OrderNotes extends AbstractController { public function get_item_permissions_check( $request ) { $order = wc_get_order( (int) $request['order_id'] ); - if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { + if ( $order && ! Permissions::check_post_object( $this->post_type, 'read', $order->get_id() ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -165,7 +167,7 @@ class OrderNotes extends AbstractController { public function delete_item_permissions_check( $request ) { $order = wc_get_order( (int) $request['order_id'] ); - if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { + if ( $order && ! Permissions::check_post_object( $this->post_type, 'delete', $order->get_id() ) ) { return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } diff --git a/src/Controllers/Version4/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php index 773b499e3cb..62ba3617e05 100644 --- a/src/Controllers/Version4/PaymentGateways.php +++ b/src/Controllers/Version4/PaymentGateways.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; + /** * Payment gateways controller class. */ @@ -24,6 +26,13 @@ class PaymentGateways extends AbstractController { */ protected $rest_base = 'payment_gateways'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'payment_gateways'; + /** * Register the route for /payment_gateways and /payment_gateways/ */ @@ -63,7 +72,7 @@ class PaymentGateways extends AbstractController { array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), @@ -72,45 +81,6 @@ class PaymentGateways extends AbstractController { ); } - /** - * Check whether a given request has permission to view payment gateways. - * - * @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( 'payment_gateways', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to read a payment gateway. - * - * @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( 'payment_gateways', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check whether a given request has permission to edit payment gateways. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - /** * Get payment gateways. * diff --git a/src/Controllers/Version4/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php index 53c9ef2aada..a07f9551d77 100644 --- a/src/Controllers/Version4/ProductAttributes.php +++ b/src/Controllers/Version4/ProductAttributes.php @@ -23,6 +23,13 @@ class ProductAttributes extends AbstractController { */ protected $rest_base = 'products/attributes'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'attributes'; + /** * Attribute name. * @@ -108,103 +115,6 @@ class ProductAttributes extends AbstractController { $this->register_batch_route(); } - /** - * Check if a given request has access to read the attributes. - * - * @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( 'attributes', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create a attribute. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'attributes', 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a attribute. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - if ( ! $this->get_taxonomy( $request ) ) { - return new \WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update a attribute. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - if ( ! $this->get_taxonomy( $request ) ) { - return new \WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'attributes', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete a attribute. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - if ( ! $this->get_taxonomy( $request ) ) { - return new \WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'attributes', 'batch' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get all attributes. * diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index f6eb8600bbb..d6a26c3e091 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -23,6 +23,13 @@ class ProductReviews extends AbstractController { */ protected $rest_base = 'products/reviews'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'product_reviews'; + /** * Register the routes for product reviews. */ @@ -116,99 +123,6 @@ class ProductReviews extends AbstractController { $this->register_batch_route(); } - /** - * Check whether a given request has permission to read webhook deliveries. - * - * @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_product_reviews_permissions( 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a product review. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = (int) $request['id']; - $review = get_comment( $id ); - - if ( $review && ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create a new product review. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update a product review. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $id = (int) $request['id']; - $review = get_comment( $id ); - - if ( $review && ! wc_rest_check_product_reviews_permissions( 'edit', $review->comment_ID ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete a product review. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $id = (int) $request['id']; - $review = get_comment( $id ); - - if ( $review && ! wc_rest_check_product_reviews_permissions( 'delete', $review->comment_ID ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * @return boolean|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get all reviews. * diff --git a/src/Controllers/Version4/ProductTags.php b/src/Controllers/Version4/ProductTags.php index ac4b08c586c..1144bae2b05 100644 --- a/src/Controllers/Version4/ProductTags.php +++ b/src/Controllers/Version4/ProductTags.php @@ -33,7 +33,7 @@ class ProductTags extends AbstractTermsContoller { /** * Prepare a single product tag output for response. * - * @param obj $item Term object. + * @param object $item Term object. * @param \WP_REST_Request $request Request params. * @return \WP_REST_Response $response */ diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index 868adecc3cd..bc4c08e3002 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -13,6 +13,7 @@ defined( 'ABSPATH' ) || exit; use WooCommerce\RestApi\Controllers\Version4\Requests\ProductVariationRequest; use WooCommerce\RestApi\Controllers\Version4\Responses\ProductVariationResponse; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; /** * REST API variations controller class. @@ -568,7 +569,7 @@ class ProductVariations extends Products { public function update_item_permissions_check( $request ) { $object = $this->get_object( (int) $request['id'] ); - if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { + if ( $object && 0 !== $object->get_id() && ! Permissions::check_post_object( $this->post_type, 'edit', $object->get_id() ) ) { return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -736,7 +737,7 @@ class ProductVariations extends Products { */ $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'delete', $object->get_id() ) ) { return new \WP_Error( /* translators: %s: post type */ "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 7b4e0b09d2c..44e975e0868 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -13,6 +13,7 @@ defined( 'ABSPATH' ) || exit; use WooCommerce\RestApi\Controllers\Version4\Requests\ProductRequest; use WooCommerce\RestApi\Controllers\Version4\Responses\ProductResponse; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; /** * REST API Products controller class. @@ -1160,7 +1161,7 @@ class Products extends AbstractObjectsController { */ $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + if ( ! Permissions::check_post_object( $this->post_type, 'delete', $object->get_id() ) ) { return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", /* translators: %s: post type */ diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index 8110ad64cae..23fa5d58e80 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -23,6 +23,13 @@ class Settings extends AbstractController { */ protected $rest_base = 'settings'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'settings'; + /** * Register routes. * @@ -45,20 +52,6 @@ class Settings extends AbstractController { $this->register_batch_route(); } - /** - * 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; - } - /** * Update a setting. * @@ -189,21 +182,6 @@ class Settings extends AbstractController { ); } - /** - * Makes sure the current user has access to READ the settings APIs. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full data about the request. - * @return \WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get the groups schema, conforming to JSON Schema. * diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index 6fba4a8ab1e..926e03cb7b3 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -11,12 +11,21 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; + /** * REST API Setting Options controller class. */ class SettingsOptions extends AbstractController { use SettingsTrait; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'settings'; + /** * Route base. * @@ -63,7 +72,7 @@ class SettingsOptions extends AbstractController { array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), @@ -93,7 +102,7 @@ class SettingsOptions extends AbstractController { array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), @@ -382,36 +391,6 @@ class SettingsOptions extends AbstractController { return $links; } - /** - * Makes sure the current user has access to READ the settings APIs. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full data about the request. - * @return \WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Makes sure the current user has access to WRITE the settings APIs. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full data about the request. - * @return \WP_Error|boolean - */ - 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; - } - /** * Filters out bad values from the settings array/filter so we * only return known values via the API. diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php index 63ff6c542b4..5358b507514 100644 --- a/src/Controllers/Version4/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -23,6 +23,13 @@ class ShippingMethods extends AbstractController { */ protected $rest_base = 'shipping_methods'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'shipping_methods'; + /** * Register the route for /shipping_methods and /shipping_methods/ */ @@ -65,32 +72,6 @@ class ShippingMethods extends AbstractController { ); } - /** - * Check whether a given request has permission to view shipping methods. - * - * @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( 'shipping_methods', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to read a shipping method. - * - * @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( 'shipping_methods', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - /** * Get shipping methods. * diff --git a/src/Controllers/Version4/ShippingZoneLocations.php b/src/Controllers/Version4/ShippingZoneLocations.php index c1f79d92f07..a653426f4bc 100644 --- a/src/Controllers/Version4/ShippingZoneLocations.php +++ b/src/Controllers/Version4/ShippingZoneLocations.php @@ -38,7 +38,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_items' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), diff --git a/src/Controllers/Version4/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php index 92e063891f7..84d920cd973 100644 --- a/src/Controllers/Version4/ShippingZoneMethods.php +++ b/src/Controllers/Version4/ShippingZoneMethods.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; + /** * REST API Shipping Zone Methods class. */ @@ -78,13 +80,13 @@ class ShippingZoneMethods extends AbstractShippingZonesController { array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_items_permissions_check' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'default' => false, diff --git a/src/Controllers/Version4/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php index 1c57fc75133..16170276d12 100644 --- a/src/Controllers/Version4/ShippingZones.php +++ b/src/Controllers/Version4/ShippingZones.php @@ -67,13 +67,13 @@ class ShippingZones extends AbstractShippingZonesController { array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), ), array( 'methods' => \WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_items_permissions_check' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'default' => false, diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index a0de8867075..cec20180f4b 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -23,6 +23,13 @@ class SystemStatus extends AbstractController { */ protected $rest_base = 'system_status'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'system_status'; + /** * Register the route for /system_status */ @@ -43,19 +50,6 @@ class SystemStatus extends AbstractController { ); } - /** - * Check whether a given request has permission to view system status. - * - * @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; - } - /** * Get a system status info, by section. * diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php index 51ead8897cf..04aa4ab8d53 100644 --- a/src/Controllers/Version4/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -23,6 +23,13 @@ class SystemStatusTools extends AbstractController { */ protected $rest_base = 'system_status/tools'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'system_status'; + /** * Register the routes for /system_status/tools/*. */ @@ -69,45 +76,6 @@ class SystemStatusTools extends AbstractController { ); } - /** - * Check whether a given request has permission to view system status tools. - * - * @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; - } - - /** - * Check whether a given request has permission to view a specific system status tool. - * - * @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 view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check whether a given request has permission to execute a specific system status tool. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - /** * A list of available tools for use in the system status section. * 'button' becomes 'action' in the API. diff --git a/src/Controllers/Version4/TaxClasses.php b/src/Controllers/Version4/TaxClasses.php index a6304b9fa74..6bd86c3bb71 100644 --- a/src/Controllers/Version4/TaxClasses.php +++ b/src/Controllers/Version4/TaxClasses.php @@ -23,6 +23,13 @@ class TaxClasses extends AbstractController { */ protected $rest_base = 'taxes/classes'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'settings'; + /** * Register the routes for tax classes. */ @@ -76,50 +83,6 @@ class TaxClasses extends AbstractController { ); } - /** - * Check whether a given request has permission to read tax classes. - * - * @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( 'settings', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create tax classes. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a tax. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get all tax classes. * diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php index 595cede149e..9c1e915a313 100644 --- a/src/Controllers/Version4/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -23,6 +23,13 @@ class Taxes extends AbstractController { */ protected $rest_base = 'taxes'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'settings'; + /** * Register the routes for taxes. */ @@ -92,94 +99,6 @@ class Taxes extends AbstractController { $this->register_batch_route(); } - /** - * Check whether a given request has permission to read taxes. - * - * @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( 'settings', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create taxes. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a tax. - * - * @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( 'settings', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access update a tax. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function update_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a tax. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get all taxes and allow filtering by tax code. * diff --git a/src/Controllers/Version4/Utilities/Permissions.php b/src/Controllers/Version4/Utilities/Permissions.php new file mode 100644 index 00000000000..c70c93573d0 --- /dev/null +++ b/src/Controllers/Version4/Utilities/Permissions.php @@ -0,0 +1,110 @@ + 'manage_woocommerce', + 'system_status' => 'manage_woocommerce', + 'attributes' => 'manage_product_terms', + 'shipping_methods' => 'manage_woocommerce', + 'payment_gateways' => 'manage_woocommerce', + 'webhooks' => 'manage_woocommerce', + 'product_reviews' => 'moderate_comments', + 'customers' => [ + 'read' => 'list_users', + 'create' => 'promote_users', // Check if current user can create users, shop managers are not allowed to create users. + 'edit' => 'edit_users', + 'delete' => 'delete_users', + 'batch' => 'promote_users', + ], + ]; + + /** + * See if the current user can do something to a resource. + * + * @param string $resource Type of permission required. + * @param string $context Context. One of read, edit, create, update, delete, batch. + * @param int $resource_id Optional resource ID. + * @return boolean + */ + public static function check_resource( $resource, $context = 'read', $resource_id = 0 ) { + if ( ! isset( self::$resource_permissions[ $resource ] ) ) { + return false; + } + $permissions = self::$resource_permissions[ $resource ]; + $capability = is_array( $permissions ) ? $permissions[ $context ] : $permissions; + $permission = current_user_can( $capability ); + + return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $resource_id, $resource ); + } + + /** + * See if the current user can do something to a resource. + * + * @param string $taxonomy Taxonomy name. + * @param string $context Context. One of read, edit, create, update, delete, batch. + * @param int $object_id Optional object ID. + * @return boolean + */ + public static function check_taxonomy( $taxonomy, $context = 'read', $object_id = 0 ) { + $contexts = array( + 'read' => 'manage_terms', + 'create' => 'edit_terms', + 'edit' => 'edit_terms', + 'delete' => 'delete_terms', + 'batch' => 'edit_terms', + ); + $cap = $contexts[ $context ]; + $taxonomy_object = get_taxonomy( $taxonomy ); + $permission = current_user_can( $taxonomy_object->cap->$cap, $object_id ); + + return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, $taxonomy ); + } + + /** + * Check permissions of posts on REST API. + * + * @param string $post_type Post type. + * @param string $context Request context. + * @param int $object_id Post ID. + * @return bool + */ + public static function check_post_object( $post_type, $context = 'read', $object_id = 0 ) { + $contexts = array( + 'read' => 'read_private_posts', + 'create' => 'publish_posts', + 'edit' => 'edit_post', + 'delete' => 'delete_post', + 'batch' => 'edit_others_posts', + ); + + if ( 'revision' === $post_type ) { + $permission = false; + } else { + $cap = $contexts[ $context ]; + $post_type_object = get_post_type_object( $post_type ); + $permission = current_user_can( $post_type_object->cap->$cap, $object_id ); + } + + return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, $post_type ); + } +} diff --git a/src/Controllers/Version4/SettingsTrait.php b/src/Controllers/Version4/Utilities/SettingsTrait.php similarity index 98% rename from src/Controllers/Version4/SettingsTrait.php rename to src/Controllers/Version4/Utilities/SettingsTrait.php index a16763e5a43..5fed3faf7d3 100644 --- a/src/Controllers/Version4/SettingsTrait.php +++ b/src/Controllers/Version4/Utilities/SettingsTrait.php @@ -5,7 +5,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace WooCommerce\RestApi\Controllers\Version4\Utilities; /** * SettingsTrait. diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index 77886eb0703..1a6b1e01e93 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -23,6 +23,13 @@ class Webhooks extends AbstractController { */ protected $rest_base = 'webhooks'; + /** + * Permission to check. + * + * @var string + */ + protected $resource_type = 'webhooks'; + /** * Post type. * @@ -113,94 +120,6 @@ class Webhooks extends AbstractController { $this->register_batch_route(); } - /** - * Check whether a given request has permission to read webhooks. - * - * @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( 'webhooks', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create webhooks. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'webhooks', 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a webhook. - * - * @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( 'webhooks', 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access update a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function update_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'webhooks', 'edit' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'webhooks', 'delete' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'webhooks', 'batch' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get the default REST API version. * From fa0f09615f5618a0fb51766af5ed9c385a78975b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 22:44:13 +0100 Subject: [PATCH 151/440] Update permission checks --- src/Controllers/Version4/AbstractObjectsController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index fd95fea5d27..9f25a9a4e99 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -90,7 +90,6 @@ abstract class AbstractObjectsController extends AbstractController { public function get_item_permissions_check( $request ) { $id = $request->get_param( 'id' ); - if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { if ( 0 !== $id && ! Permissions::check_post_object( $this->post_type, 'read', $id ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } From f19e5d930069740623a9f224d834882cc3453986 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 22:45:00 +0100 Subject: [PATCH 152/440] Move BatchTrait to utilities --- src/Controllers/Version4/AbstractController.php | 1 + src/Controllers/Version4/{ => Utilities}/BatchTrait.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename src/Controllers/Version4/{ => Utilities}/BatchTrait.php (99%) diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index 6d8ef36d718..9f09f636123 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -16,6 +16,7 @@ defined( 'ABSPATH' ) || exit; use \WP_REST_Controller; use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use \WooCommerce\RestApi\Controllers\Version4\Utilities\BatchTrait; /** * Abstract Rest Controller Class diff --git a/src/Controllers/Version4/BatchTrait.php b/src/Controllers/Version4/Utilities/BatchTrait.php similarity index 99% rename from src/Controllers/Version4/BatchTrait.php rename to src/Controllers/Version4/Utilities/BatchTrait.php index 5ee4837d75d..19ae18315ab 100644 --- a/src/Controllers/Version4/BatchTrait.php +++ b/src/Controllers/Version4/Utilities/BatchTrait.php @@ -5,7 +5,7 @@ * @package WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace WooCommerce\RestApi\Controllers\Version4\Utilities; /** * BatchTrait. From f7c9393012faff7d4b35e5cc79b7a6571c521012 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 17 Jun 2019 23:42:15 +0100 Subject: [PATCH 153/440] Customer requests + responses --- src/Controllers/Version4/Customers.php | 220 +++++------------- .../Version4/Requests/CustomerRequest.php | 105 +++++++++ .../Version4/Requests/OrderRequest.php | 2 +- .../Version4/Responses/CustomerResponse.php | 54 +++++ 4 files changed, 212 insertions(+), 169 deletions(-) create mode 100644 src/Controllers/Version4/Requests/CustomerRequest.php create mode 100644 src/Controllers/Version4/Responses/CustomerResponse.php diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 7d30b4c1db6..474ec10e203 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -12,6 +12,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; use \WP_REST_Server; +use WooCommerce\RestApi\Controllers\Version4\Requests\CustomerRequest; +use WooCommerce\RestApi\Controllers\Version4\Responses\CustomerResponse; /** * REST API Customers controller class. @@ -125,45 +127,6 @@ class Customers extends AbstractController { $this->register_batch_route(); } - /** - * Get formatted item data. - * - * @param \WC_Data $object WC_Data instance. - * - * @since 3.0.0 - * @return array - */ - protected function get_formatted_item_data( $object ) { - $data = $object->get_data(); - $format_date = array( 'date_created', 'date_modified' ); - - // Format date values. - foreach ( $format_date as $key ) { - // Date created is stored UTC, date modified is stored WP local time. - $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - return array( - 'id' => $object->get_id(), - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => $data['email'], - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'role' => $data['role'], - 'username' => $data['username'], - 'billing' => $data['billing'], - 'shipping' => $data['shipping'], - 'is_paying_customer' => $data['is_paying_customer'], - 'avatar_url' => $object->get_avatar_url(), - 'meta_data' => $data['meta_data'], - ); - } - /** * Get all customers. * @@ -171,16 +134,19 @@ class Customers extends AbstractController { * @return \WP_Error|\WP_REST_Response */ public function get_items( $request ) { - $prepared_args = array(); - $prepared_args['exclude'] = $request['exclude']; - $prepared_args['include'] = $request['include']; - $prepared_args['order'] = $request['order']; - $prepared_args['number'] = $request['per_page']; + $prepared_args = array( + 'exclude' => $request['exclude'], + 'include' => $request['include'], + 'order' => $request['order'], + 'number' => $request['per_page'], + ); + if ( ! empty( $request['offset'] ) ) { $prepared_args['offset'] = $request['offset']; } else { $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; } + $orderby_possibles = array( 'id' => 'ID', 'include' => 'include', @@ -215,19 +181,20 @@ class Customers extends AbstractController { */ $prepared_args = apply_filters( 'woocommerce_rest_customer_query', $prepared_args, $request ); - $query = new \ WP_User_Query( $prepared_args ); + $query = new \WP_User_Query( $prepared_args ); $users = array(); foreach ( $query->results as $user ) { - $data = $this->prepare_item_for_response( $user, $request ); - $users[] = $this->prepare_response_for_collection( $data ); + $customer = new \WC_Customer( $user->ID ); + $data = $this->prepare_item_for_response( $customer, $request ); + $users[] = $this->prepare_response_for_collection( $data ); } $response = rest_ensure_response( $users ); // Store pagination values for headers then unset for count query. $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); $prepared_args['fields'] = 'ID'; @@ -274,38 +241,27 @@ class Customers extends AbstractController { throw new \WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); } - // Sets the username. - $request['username'] = ! empty( $request['username'] ) ? $request['username'] : ''; - - // Sets the password. - $request['password'] = ! empty( $request['password'] ) ? $request['password'] : ''; - - // Create customer. - $customer = new \WC_Customer(); - $customer->set_username( $request['username'] ); - $customer->set_password( $request['password'] ); - $customer->set_email( $request['email'] ); - $this->update_customer_meta_fields( $customer, $request ); + $customer_request = new CustomerRequest( $request ); + $customer = $customer_request->prepare_object(); $customer->save(); if ( ! $customer->get_id() ) { throw new \WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); } - $user_data = get_userdata( $customer->get_id() ); - $this->update_additional_fields_for_object( $user_data, $request ); + $this->update_additional_fields_for_object( $customer, $request ); /** * Fires after a customer is created or updated via the REST API. * - * @param WP_User $user_data Data used to create the customer. + * @param \WC_Customer $customer Customer object. * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating customer, false when updating customer. + * @param boolean $creating True when creating customer, false when updating customer. */ - do_action( 'woocommerce_rest_insert_customer', $user_data, $request, true ); + do_action( 'woocommerce_rest_insert_customer_object', $customer, $request, true ); $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $user_data, $request ); + $response = $this->prepare_item_for_response( $customer, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ) ); @@ -323,15 +279,15 @@ class Customers extends AbstractController { * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { - $id = (int) $request['id']; - $user_data = get_userdata( $id ); + $id = (int) $request['id']; + $customer = new \WC_Customer( $id ); - if ( empty( $id ) || empty( $user_data->ID ) ) { + if ( empty( $id ) || ! $customer->get_id() ) { return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - $customer = $this->prepare_item_for_response( $user_data, $request ); - $response = rest_ensure_response( $customer ); + $response = $this->prepare_item_for_response( $customer, $request ); + $response = rest_ensure_response( $response ); return $response; } @@ -346,52 +302,27 @@ class Customers extends AbstractController { */ public function update_item( $request ) { try { - $id = (int) $request['id']; - $customer = new \WC_Customer( $id ); - - if ( ! $customer->get_id() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); - } - - if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->get_email() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); - } - - if ( ! empty( $request['username'] ) && $request['username'] !== $customer->get_username() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); - } - - // Customer email. - if ( isset( $request['email'] ) ) { - $customer->set_email( sanitize_email( $request['email'] ) ); - } - - // Customer password. - if ( isset( $request['password'] ) ) { - $customer->set_password( $request['password'] ); - } - - $this->update_customer_meta_fields( $customer, $request ); + $customer_request = new CustomerRequest( $request ); + $customer = $customer_request->prepare_object(); $customer->save(); - $user_data = get_userdata( $customer->get_id() ); - $this->update_additional_fields_for_object( $user_data, $request ); + $this->update_additional_fields_for_object( $customer, $request ); - if ( ! is_user_member_of_blog( $user_data->ID ) ) { - $user_data->add_role( 'customer' ); + if ( is_multisite() && ! is_user_member_of_blog( $customer->get_id() ) ) { + add_user_to_blog( get_current_blog_id(), $customer->get_id(), 'customer' ); } /** * Fires after a customer is created or updated via the REST API. * - * @param WP_User $customer Data used to create the customer. + * @param \WC_Customer $customer Data used to create the customer. * @param \WP_REST_Request $request Request object. * @param boolean $creating True when creating customer, false when updating customer. */ - do_action( 'woocommerce_rest_insert_customer', $user_data, $request, false ); + do_action( 'woocommerce_rest_insert_customer_object', $customer, $request, false ); $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $user_data, $request ); + $response = $this->prepare_item_for_response( $customer, $request ); $response = rest_ensure_response( $response ); return $response; } catch ( Exception $e ) { @@ -415,8 +346,7 @@ class Customers extends AbstractController { return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } - $user_data = get_userdata( $id ); - if ( ! $user_data ) { + if ( ! get_userdata( $id ) ) { return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); } @@ -426,14 +356,14 @@ class Customers extends AbstractController { } } - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $user_data, $request ); - /** Include admin customer functions to get access to wp_delete_user() */ require_once ABSPATH . 'wp-admin/includes/user.php'; $customer = new \WC_Customer( $id ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $customer, $request ); + if ( ! is_null( $reassign ) ) { $result = $customer->delete_and_reassign( $reassign ); } else { @@ -447,11 +377,11 @@ class Customers extends AbstractController { /** * Fires after a customer is deleted via the REST API. * - * @param WP_User $user_data User data. + * @param \WC_Customer $customer User data. * @param \WP_REST_Response $response The response returned from the API. * @param \WP_REST_Request $request The request sent to the API. */ - do_action( 'woocommerce_rest_delete_customer', $user_data, $response, $request ); + do_action( 'woocommerce_rest_delete_customer_object', $customer, $response, $request ); return $response; } @@ -459,86 +389,40 @@ class Customers extends AbstractController { /** * Prepare a single customer output for response. * - * @param WP_User $user_data User object. + * @param \WC_Customer $customer User object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ - public function prepare_item_for_response( $user_data, $request ) { - $customer = new \WC_Customer( $user_data->ID ); - $data = $this->get_formatted_item_data( $customer ); - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + public function prepare_item_for_response( $customer, $request ) { + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $customer_response = new CustomerResponse(); + + $data = $customer_response->prepare_response( $customer, $context ); $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $user_data ) ); + $response->add_links( $this->prepare_links( $customer ) ); /** * Filter customer data returned from the REST API. * * @param \WP_REST_Response $response The response object. - * @param WP_User $user_data User object used to create response. + * @param \WC_Customer $customer User object used to create response. * @param \WP_REST_Request $request Request object. */ - return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); - } - - /** - * Update customer meta fields. - * - * @param WC_Customer $customer Customer being updated. - * @param \WP_REST_Request $request Request params. - */ - protected function update_customer_meta_fields( $customer, $request ) { - $schema = $this->get_item_schema(); - - // Customer first name. - if ( isset( $request['first_name'] ) ) { - $customer->set_first_name( wc_clean( $request['first_name'] ) ); - } - - // Customer last name. - if ( isset( $request['last_name'] ) ) { - $customer->set_last_name( wc_clean( $request['last_name'] ) ); - } - - // Customer billing address. - if ( isset( $request['billing'] ) ) { - foreach ( array_keys( $schema['properties']['billing']['properties'] ) as $field ) { - if ( isset( $request['billing'][ $field ] ) && is_callable( array( $customer, "set_billing_{$field}" ) ) ) { - $customer->{"set_billing_{$field}"}( $request['billing'][ $field ] ); - } - } - } - - // Customer shipping address. - if ( isset( $request['shipping'] ) ) { - foreach ( array_keys( $schema['properties']['shipping']['properties'] ) as $field ) { - if ( isset( $request['shipping'][ $field ] ) && is_callable( array( $customer, "set_shipping_{$field}" ) ) ) { - $customer->{"set_shipping_{$field}"}( $request['shipping'][ $field ] ); - } - } - } - - // Meta data. - if ( isset( $request['meta_data'] ) ) { - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $customer->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - } + return apply_filters( 'woocommerce_rest_prepare_customer_object', $response, $customer, $request ); } /** * Prepare links for the request. * - * @param WP_User $customer Customer object. + * @param \WC_Customer $customer Customer object. * @return array Links for the given customer. */ protected function prepare_links( $customer ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->ID ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), diff --git a/src/Controllers/Version4/Requests/CustomerRequest.php b/src/Controllers/Version4/Requests/CustomerRequest.php new file mode 100644 index 00000000000..5bbde2bef1a --- /dev/null +++ b/src/Controllers/Version4/Requests/CustomerRequest.php @@ -0,0 +1,105 @@ +get_param( 'id', 0 ); + $object = new \WC_Customer( $id ); + + if ( $id !== $object->get_id() ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); + } + + $this->set_props( $object ); + $this->set_meta_data( $object ); + + return $object; + } + + /** + * Set order props. + * + * @throws \WC_REST_Exception Will throw an exception if the customer is invalid. + * @param \WC_Customer $object Order object reference. + */ + protected function set_props( &$object ) { + $props = [ + 'username', + 'password', + 'email', + 'first_name', + 'last_name', + 'billing', + 'shipping', + 'billing', + 'shipping', + ]; + + $request_props = array_intersect_key( $this->request, array_flip( $props ) ); + $prop_values = []; + + foreach ( $request_props as $prop => $value ) { + switch ( $prop ) { + case 'email': + if ( email_exists( $value ) && $value !== $object->get_email() ) { + throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); + } + $prop_values[ $prop ] = $value; + break; + case 'username': + if ( $object->get_id() && $value !== $object->get_username() ) { + throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); + } + $prop_values[ $prop ] = $value; + break; + case 'billing': + case 'shipping': + $address = $this->parse_address_field( $value, $object, $prop ); + $prop_values = array_merge( $prop_values, $address ); + break; + default: + $prop_values[ $prop ] = $value; + } + } + + foreach ( $prop_values as $prop => $value ) { + $object->{"set_$prop"}( $value ); + } + } + + /** + * Parse address data. + * + * @param array $data Posted data. + * @param \WC_Customer $object Customer object. + * @param string $type Address type. + * @return array + */ + protected function parse_address_field( $data, $object, $type = 'billing' ) { + $address = []; + foreach ( $data as $key => $value ) { + if ( is_callable( array( $object, "set_{$type}_{$key}" ) ) ) { + $address[ "{$type}_{$key}" ] = $value; + } + } + return $address; + } +} diff --git a/src/Controllers/Version4/Requests/OrderRequest.php b/src/Controllers/Version4/Requests/OrderRequest.php index 7593182a2b1..4eefbea6c08 100644 --- a/src/Controllers/Version4/Requests/OrderRequest.php +++ b/src/Controllers/Version4/Requests/OrderRequest.php @@ -1,6 +1,6 @@ get_data(); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + // Date created is stored UTC, date modified is stored WP local time. + $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => $data['email'], + 'first_name' => $data['first_name'], + 'last_name' => $data['last_name'], + 'role' => $data['role'], + 'username' => $data['username'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'is_paying_customer' => $data['is_paying_customer'], + 'avatar_url' => $object->get_avatar_url(), + 'meta_data' => $data['meta_data'], + ); + } +} From 5bd17af0dac43faf3d8f6741f139abdfb24b9268 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 18 Jun 2019 00:11:30 +0100 Subject: [PATCH 154/440] ProductReviewResponse --- src/Controllers/Version4/ProductReviews.php | 83 +++---------------- .../Responses/ProductReviewResponse.php | 71 ++++++++++++++++ src/Utilities/ImageAttachment.php | 2 +- 3 files changed, 85 insertions(+), 71 deletions(-) create mode 100644 src/Controllers/Version4/Responses/ProductReviewResponse.php diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index d6a26c3e091..1265d9b7bab 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -11,6 +11,9 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use WooCommerce\RestApi\Controllers\Version4\Responses\ProductReviewResponse; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; + /** * REST API Product Reviews controller class. */ @@ -216,7 +219,7 @@ class ProductReviews extends AbstractController { $reviews = array(); foreach ( $query_result as $review ) { - if ( ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { + if ( ! Permissions::check_resource( $this->resource_type, 'read', $review->comment_ID ) ) { continue; } @@ -572,54 +575,19 @@ class ProductReviews extends AbstractController { /** * Prepare a single product review output for response. * - * @param WP_Comment $review Product review object. + * @param \WP_Comment $review Product review object. * @param \WP_REST_Request $request Request object. * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $review, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $fields = $this->get_fields_for_response( $request ); - $data = array(); - - if ( in_array( 'id', $fields, true ) ) { - $data['id'] = (int) $review->comment_ID; - } - if ( in_array( 'date_created', $fields, true ) ) { - $data['date_created'] = wc_rest_prepare_date_response( $review->comment_date ); - } - if ( in_array( 'date_created_gmt', $fields, true ) ) { - $data['date_created_gmt'] = wc_rest_prepare_date_response( $review->comment_date_gmt ); - } - if ( in_array( 'product_id', $fields, true ) ) { - $data['product_id'] = (int) $review->comment_post_ID; - } - if ( in_array( 'status', $fields, true ) ) { - $data['status'] = $this->prepare_status_response( (string) $review->comment_approved ); - } - if ( in_array( 'reviewer', $fields, true ) ) { - $data['reviewer'] = $review->comment_author; - } - if ( in_array( 'reviewer_email', $fields, true ) ) { - $data['reviewer_email'] = $review->comment_author_email; - } - if ( in_array( 'review', $fields, true ) ) { - $data['review'] = 'view' === $context ? wpautop( $review->comment_content ) : $review->comment_content; - } - if ( in_array( 'rating', $fields, true ) ) { - $data['rating'] = (int) get_comment_meta( $review->comment_ID, 'rating', true ); - } - if ( in_array( 'verified', $fields, true ) ) { - $data['verified'] = wc_review_is_from_verified_owner( $review->comment_ID ); - } - if ( in_array( 'reviewer_avatar_urls', $fields, true ) ) { - $data['reviewer_avatar_urls'] = rest_get_avatar_urls( $review->comment_author_email ); - } - - $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 ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $fields = $this->get_fields_for_response( $request ); + $review_response = new ProductReviewResponse(); + $data = $review_response->prepare_response( $review, $context ); + $data = array_intersect_key( $data, array_flip( $fields ) ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); $response->add_links( $this->prepare_links( $review ) ); @@ -990,32 +958,7 @@ class ProductReviews extends AbstractController { return $normalized; } - /** - * Checks comment_approved to set comment status for single comment output. - * - * @since 3.5.0 - * @param string|int $comment_approved comment status. - * @return string Comment status. - */ - protected function prepare_status_response( $comment_approved ) { - switch ( $comment_approved ) { - case 'hold': - case '0': - $status = 'hold'; - break; - case 'approve': - case '1': - $status = 'approved'; - break; - case 'spam': - case 'trash': - default: - $status = $comment_approved; - break; - } - return $status; - } /** * Sets the comment_status of a given review object when creating or updating a review. diff --git a/src/Controllers/Version4/Responses/ProductReviewResponse.php b/src/Controllers/Version4/Responses/ProductReviewResponse.php new file mode 100644 index 00000000000..e07094827c4 --- /dev/null +++ b/src/Controllers/Version4/Responses/ProductReviewResponse.php @@ -0,0 +1,71 @@ + (int) $object->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $object->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->comment_date_gmt ), + 'product_id' => (int) $object->comment_post_ID, + 'status' => $this->prepare_status_response( (string) $object->comment_approved ), + 'reviewer' => $object->comment_author, + 'reviewer_email' => $object->comment_author_email, + 'review' => $object->comment_content, + 'rating' => (int) get_comment_meta( $object->comment_ID, 'rating', true ), + 'verified' => wc_review_is_from_verified_owner( $object->comment_ID ), + 'reviewer_avatar_urls' => rest_get_avatar_urls( $object->comment_author_email ), + ); + + if ( 'view' === $context ) { + $data['review'] = wpautop( $data['review'] ); + } + + return $data; + } + + /** + * Checks comment_approved to set comment status for single comment output. + * + * @param string|int $comment_approved comment status. + * @return string Comment status. + */ + protected function prepare_status_response( $comment_approved ) { + switch ( $comment_approved ) { + case 'hold': + case '0': + $status = 'hold'; + break; + case 'approve': + case '1': + $status = 'approved'; + break; + case 'spam': + case 'trash': + default: + $status = $comment_approved; + break; + } + + return $status; + } +} diff --git a/src/Utilities/ImageAttachment.php b/src/Utilities/ImageAttachment.php index 14408376a0a..8abba23ab1c 100644 --- a/src/Utilities/ImageAttachment.php +++ b/src/Utilities/ImageAttachment.php @@ -47,7 +47,7 @@ class ImageAttachment { $upload = wc_rest_upload_image_from_url( esc_url_raw( $src ) ); if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $object->get_id(), $images ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $this->object_id, $images ) ) { throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); } else { return; From d2e4c199f448fc6db0fc54eda251e3d80450f655 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 18 Jun 2019 10:44:41 +0100 Subject: [PATCH 155/440] Standardisation of prepare_item and prepare_links --- .../Version4/AbstractController.php | 68 ++++++++++++++++++ .../Version4/AbstractObjectsController.php | 8 +-- .../Version4/AbstractTermsContoller.php | 14 ++-- src/Controllers/Version4/Coupons.php | 12 ++-- .../Version4/CustomerDownloads.php | 69 ++++++++----------- src/Controllers/Version4/Customers.php | 47 ++++++------- src/Controllers/Version4/Data.php | 41 +++++------ src/Controllers/Version4/Data/Continents.php | 9 +-- src/Controllers/Version4/Data/Countries.php | 9 +-- src/Controllers/Version4/Data/Currencies.php | 9 +-- src/Controllers/Version4/Data/DownloadIPs.php | 9 +-- src/Controllers/Version4/OrderNotes.php | 60 +++++++--------- src/Controllers/Version4/OrderRefunds.php | 24 +++---- src/Controllers/Version4/Orders.php | 16 ++--- src/Controllers/Version4/PaymentGateways.php | 63 ++++++++--------- .../Version4/ProductAttributes.php | 11 +-- src/Controllers/Version4/ProductReviews.php | 64 +++++++---------- .../Version4/ProductVariations.php | 8 +-- src/Controllers/Version4/Products.php | 13 ++-- src/Controllers/Version4/Settings.php | 11 +-- src/Controllers/Version4/SettingsOptions.php | 16 ++--- src/Controllers/Version4/ShippingMethods.php | 8 +-- .../Version4/ShippingZoneLocations.php | 11 +-- .../Version4/ShippingZoneMethods.php | 18 ++--- src/Controllers/Version4/ShippingZones.php | 13 ++-- src/Controllers/Version4/SystemStatus.php | 31 +++------ .../Version4/SystemStatusTools.php | 35 ++++------ src/Controllers/Version4/TaxClasses.php | 46 ++++--------- src/Controllers/Version4/Taxes.php | 67 ++++++++---------- src/Controllers/Version4/Webhooks.php | 9 +-- 30 files changed, 404 insertions(+), 415 deletions(-) diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index 9f09f636123..809b37f5cdf 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -49,6 +49,15 @@ abstract class AbstractController extends WP_REST_Controller { */ protected $resource_type = ''; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = ''; + /** * Register route for items requests. * @@ -246,4 +255,63 @@ abstract class AbstractController extends WP_REST_Controller { } return true; } + + /** + * Get context for the request. + * + * @param \WP_REST_Request $request Full details about the request. + * @return string + */ + protected function get_request_context( $request ) { + return ! empty( $request['context'] ) ? $request['context'] : 'view'; + } + + /** + * Prepare a single item for response. + * + * @param mixed $item Object used to create response. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $context = $this->get_request_context( $request ); + $fields = $this->get_fields_for_response( $request ); + $data = array_intersect_key( $this->get_data_for_response( $item, $request ), array_flip( $fields ) ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter object returned from the REST API. + * + * @param \WP_REST_Response $response The response object. + * @param mixed $item Object used to create response. + * @param \WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->singular}", $response, $item, $request ); + } + + /** + * Get data for this object in the format of this endpoint's schema. + * + * @param mixed $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return mixed Array of data in the correct format. + */ + protected function get_data_for_response( $object, $request ) { + return $object; + } + + /** + * Prepare links for the request. + * + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $item, $request ) { + return array(); + } } diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 9f25a9a4e99..db814217eae 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -531,14 +531,14 @@ abstract class AbstractObjectsController extends AbstractController { /** * Prepare links for the request. * - * @param \WC_Data $object Object data. + * @param mixed $item Object to prepare. * @param \WP_REST_Request $request Request object. - * @return array Links for the given post. + * @return array */ - protected function prepare_links( $object, $request ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index 6ec5b8ee705..f82a3fe148a 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -517,11 +517,11 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Prepare links for the request. * - * @param object $term Term object. - * @param \WP_REST_Request $request Full details about the request. - * @return array Links for the given term. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $term, $request ) { + protected function prepare_links( $item, $request ) { $base = '/' . $this->namespace . '/' . $this->rest_base; if ( ! empty( $request['attribute_id'] ) ) { @@ -530,15 +530,15 @@ abstract class AbstractTermsContoller extends AbstractController { $links = array( 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $term->term_id ), + 'href' => rest_url( trailingslashit( $base ) . $item->term_id ), ), 'collection' => array( 'href' => rest_url( $base ), ), ); - if ( $term->parent ) { - $parent_term = get_term( (int) $term->parent, $term->taxonomy ); + if ( $item->parent ) { + $parent_term = get_term( (int) $item->parent, $item->taxonomy ); if ( $parent_term ) { $links['up'] = array( 'href' => rest_url( trailingslashit( $base ) . $parent_term->term_id ), diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index 7bc765561a2..36061f3b814 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -42,13 +42,13 @@ class Coupons extends AbstractObjectsController { } /** - * Get formatted item data. + * Get data for this object in the format of this endpoint's schema. * - * @since 3.0.0 - * @param \WC_Data $object WC_Data instance. - * @return array + * @param \WP_Comment $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - protected function get_formatted_item_data( $object ) { + protected function get_data_for_response( $object, $request ) { $data = $object->get_data(); $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); @@ -112,7 +112,7 @@ class Coupons extends AbstractObjectsController { * @return \WP_REST_Response */ public function prepare_object_for_response( $object, $request ) { - $data = $this->get_formatted_item_data( $object ); + $data = $this->get_data_for_response( $object, $request ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index 5b74e38cea7..dfe04d6baa5 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -32,6 +32,15 @@ class CustomerDownloads extends AbstractController { */ protected $resource_type = 'customers'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'customer_download'; + /** * Register the routes for customers. */ @@ -79,64 +88,46 @@ class CustomerDownloads extends AbstractController { } /** - * Prepare a single download output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \stdClass $download Download object. + * @param \WP_Comment $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $download, $request ) { - $data = array( - 'download_id' => $download->download_id, - 'download_url' => $download->download_url, - 'product_id' => $download->product_id, - 'product_name' => $download->product_name, - 'download_name' => $download->download_name, - 'order_id' => $download->order_id, - 'order_key' => $download->order_key, - 'downloads_remaining' => '' === $download->downloads_remaining ? 'unlimited' : $download->downloads_remaining, - 'access_expires' => $download->access_expires ? wc_rest_prepare_date_response( $download->access_expires ) : 'never', - 'access_expires_gmt' => $download->access_expires ? wc_rest_prepare_date_response( get_gmt_from_date( $download->access_expires ) ) : 'never', - 'file' => $download->file, + protected function get_data_for_response( $object, $request ) { + return array( + 'download_id' => $object->download_id, + 'download_url' => $object->download_url, + 'product_id' => $object->product_id, + 'product_name' => $object->product_name, + 'download_name' => $object->download_name, + 'order_id' => $object->order_id, + 'order_key' => $object->order_key, + 'downloads_remaining' => '' === $object->downloads_remaining ? 'unlimited' : $object->downloads_remaining, + 'access_expires' => $object->access_expires ? wc_rest_prepare_date_response( $object->access_expires ) : 'never', + 'access_expires_gmt' => $object->access_expires ? wc_rest_prepare_date_response( get_gmt_from_date( $object->access_expires ) ) : 'never', + 'file' => $object->file, ); - - $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( $download, $request ) ); - - /** - * Filter customer download data returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param \stdClass $download Download object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); } /** * Prepare links for the request. * - * @param \stdClass $download Download object. + * @param mixed $item Object to prepare. * @param \WP_REST_Request $request Request object. - * @return array Links for the given customer download. + * @return array */ - protected function prepare_links( $download, $request ) { + protected function prepare_links( $item, $request ) { $base = str_replace( '(?P[\d]+)', $request['customer_id'], $this->rest_base ); $links = array( 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), ), 'product' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $download->product_id ) ), + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $item->product_id ) ), ), 'order' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $download->order_id ) ), + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $item->order_id ) ), ), ); diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 474ec10e203..59ac1250ac7 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -34,6 +34,15 @@ class Customers extends AbstractController { */ protected $resource_type = 'customers'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'customer'; + /** * Register the routes for customers. */ @@ -387,48 +396,34 @@ class Customers extends AbstractController { } /** - * Prepare a single customer output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \WC_Customer $customer User object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @param \WP_Comment $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $customer, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $customer_response = new CustomerResponse(); + protected function get_data_for_response( $object, $request ) { + $formatter = new CustomerResponse(); - $data = $customer_response->prepare_response( $customer, $context ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $customer ) ); - - /** - * Filter customer data returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param \WC_Customer $customer User object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_customer_object', $response, $customer, $request ); + return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); } /** * Prepare links for the request. * - * @param \WC_Customer $customer Customer object. - * @return array Links for the given customer. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $customer ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), ), ); - return $links; } diff --git a/src/Controllers/Version4/Data.php b/src/Controllers/Version4/Data.php index 45be1c8857e..3e7965e376b 100644 --- a/src/Controllers/Version4/Data.php +++ b/src/Controllers/Version4/Data.php @@ -30,6 +30,15 @@ class Data extends AbstractController { */ protected $resource_type = 'settings'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'data'; + /** * Register routes. * @@ -88,35 +97,27 @@ class Data extends AbstractController { } /** - * Prepare a data resource object for serialization. + * Get data for this object in the format of this endpoint's schema. * - * @param \stdClass $resource Resource data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @param \stdClass $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $resource, $request ) { - $data = array( - 'slug' => $resource->slug, - 'description' => $resource->description, + protected function get_data_for_response( $object, $request ) { + return array( + 'slug' => $object->slug, + 'description' => $object->description, ); - - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, 'view' ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $resource ) ); - - return $response; } /** * Prepare links for the request. * - * @param object $item Data object. - * @return array Links for the given country. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $item ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->slug ) ), diff --git a/src/Controllers/Version4/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php index 8b96e9ea720..94fb82d9256 100644 --- a/src/Controllers/Version4/Data/Continents.php +++ b/src/Controllers/Version4/Data/Continents.php @@ -198,7 +198,7 @@ class Continents extends DataController { $data = $this->filter_response_by_context( $data, 'view' ); $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $item ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); /** * Filter the location list returned from the API. @@ -215,10 +215,11 @@ class Continents extends DataController { /** * Prepare links for the request. * - * @param object $item Data object. - * @return array Links for the given continent. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $item ) { + protected function prepare_links( $item, $request ) { $continent_code = strtolower( $item['code'] ); $links = array( 'self' => array( diff --git a/src/Controllers/Version4/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php index a135fad36e2..0d3090ff0d7 100644 --- a/src/Controllers/Version4/Data/Countries.php +++ b/src/Controllers/Version4/Data/Countries.php @@ -145,7 +145,7 @@ class Countries extends DataController { $data = $this->filter_response_by_context( $data, 'view' ); $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $item ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); /** * Filter the states list for a country returned from the API. @@ -162,10 +162,11 @@ class Countries extends DataController { /** * Prepare links for the request. * - * @param object $item Data object. - * @return array Links for the given country. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $item ) { + protected function prepare_links( $item, $request ) { $country_code = strtolower( $item['code'] ); $links = array( 'self' => array( diff --git a/src/Controllers/Version4/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php index 428987b9f80..ff537ab71bd 100644 --- a/src/Controllers/Version4/Data/Currencies.php +++ b/src/Controllers/Version4/Data/Currencies.php @@ -151,7 +151,7 @@ class Currencies extends DataController { $data = $this->filter_response_by_context( $data, 'view' ); $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $item ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); /** * Filter currency returned from the API. @@ -166,10 +166,11 @@ class Currencies extends DataController { /** * Prepare links for the request. * - * @param object $item Data object. - * @return array Links for the given currency. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $item ) { + protected function prepare_links( $item, $request ) { $code = strtoupper( $item['code'] ); $links = array( 'self' => array( diff --git a/src/Controllers/Version4/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php index 08d340732d2..37651f38281 100644 --- a/src/Controllers/Version4/Data/DownloadIPs.php +++ b/src/Controllers/Version4/Data/DownloadIPs.php @@ -93,7 +93,7 @@ class DownloadIPs extends DataController { $data = $this->filter_response_by_context( $data, 'view' ); $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $item ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); /** * Filter the list returned from the API. @@ -108,10 +108,11 @@ class DownloadIPs extends DataController { /** * Prepare links for the request. * - * @param object $item Data object. - * @return array Links for the given object. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $item ) { + protected function prepare_links( $item, $request ) { $links = array( 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index 5e0ab83ebdd..f6791a6e340 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -32,6 +32,15 @@ class OrderNotes extends AbstractController { */ protected $post_type = 'shop_order'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'order_note'; + /** * Register the routes for order notes. */ @@ -356,53 +365,36 @@ class OrderNotes extends AbstractController { } /** - * Prepare a single order note output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Comment $note Order note object. + * @param \WP_Comment $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $note, $request ) { - $data = array( - 'id' => (int) $note->comment_ID, - 'author' => __( 'WooCommerce', 'woocommerce' ) === $note->comment_author ? 'system' : $note->comment_author, - 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), - 'note' => $note->comment_content, - 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + protected function get_data_for_response( $object, $request ) { + return array( + 'id' => (int) $object->comment_ID, + 'author' => __( 'WooCommerce', 'woocommerce' ) === $object->comment_author ? 'system' : $object->comment_author, + 'date_created' => wc_rest_prepare_date_response( $object->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->comment_date_gmt ), + 'note' => $object->comment_content, + 'customer_note' => (bool) get_comment_meta( $object->comment_ID, 'is_customer_note', true ), ); - - $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( $note ) ); - - /** - * Filter order note object returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param \WP_Comment $note Order note object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); } /** * Prepare links for the request. * - * @param WP_Comment $note Delivery order_note object. - * @return array Links for the given order note. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $note ) { - $order_id = (int) $note->comment_post_ID; + protected function prepare_links( $item, $request ) { + $order_id = (int) $item->comment_post_ID; $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $note->comment_ID ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $item->comment_ID ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), diff --git a/src/Controllers/Version4/OrderRefunds.php b/src/Controllers/Version4/OrderRefunds.php index dc40abf6e09..80910d6c985 100644 --- a/src/Controllers/Version4/OrderRefunds.php +++ b/src/Controllers/Version4/OrderRefunds.php @@ -127,13 +127,13 @@ class OrderRefunds extends Orders { } /** - * Get formatted item data. + * Get data for this object in the format of this endpoint's schema. * - * @since 3.0.0 - * @param \WC_Data $object WC_Data instance. - * @return array + * @param mixed $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - protected function get_formatted_item_data( $object ) { + protected function get_data_for_response( $object, $request ) { $data = $object->get_data(); $format_decimal = array( 'amount' ); $format_date = array( 'date_created' ); @@ -192,7 +192,7 @@ class OrderRefunds extends Orders { return new \WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); } - $data = $this->get_formatted_item_data( $object ); + $data = $this->get_data_for_response( $object, $request ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); @@ -336,21 +336,21 @@ class OrderRefunds extends Orders { /** * Prepare links for the request. * - * @param \WC_Data $object Object data. + * @param mixed $item Object to prepare. * @param \WP_REST_Request $request Request object. - * @return array Links for the given post. + * @return array */ - protected function prepare_links( $object, $request ) { - $base = str_replace( '(?P[\d]+)', $object->get_parent_id(), $this->rest_base ); + protected function prepare_links( $item, $request ) { + $base = str_replace( '(?P[\d]+)', $item->get_parent_id(), $this->rest_base ); $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $item->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), ), 'up' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $item->get_parent_id() ) ), ), ); diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index caf8061ba4c..8d407a320ae 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -153,29 +153,29 @@ class Orders extends AbstractObjectsController { /** * Prepare links for the request. * - * @param \WC_Data $object Object data. + * @param mixed $item Object to prepare. * @param \WP_REST_Request $request Request object. - * @return array Links for the given post. + * @return array */ - protected function prepare_links( $object, $request ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), ), ); - if ( 0 !== (int) $object->get_customer_id() ) { + if ( 0 !== (int) $item->get_customer_id() ) { $links['customer'] = array( - 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object->get_customer_id() ) ), + 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $item->get_customer_id() ) ), ); } - if ( 0 !== (int) $object->get_parent_id() ) { + if ( 0 !== (int) $item->get_parent_id() ) { $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $item->get_parent_id() ) ), ); } diff --git a/src/Controllers/Version4/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php index 62ba3617e05..176dc43a035 100644 --- a/src/Controllers/Version4/PaymentGateways.php +++ b/src/Controllers/Version4/PaymentGateways.php @@ -33,6 +33,15 @@ class PaymentGateways extends AbstractController { */ protected $resource_type = 'payment_gateways'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'payment_gateway'; + /** * Register the route for /payment_gateways and /payment_gateways/ */ @@ -210,41 +219,25 @@ class PaymentGateways extends AbstractController { } /** - * Prepare a payment gateway for response. + * Get data for this object in the format of this endpoint's schema. * - * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @param \WC_Payment_Gateway $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $gateway, $request ) { + protected function get_data_for_response( $object, $request ) { $order = (array) get_option( 'woocommerce_gateway_order' ); - $item = array( - 'id' => $gateway->id, - 'title' => $gateway->title, - 'description' => $gateway->description, - 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', - 'enabled' => ( 'yes' === $gateway->enabled ), - 'method_title' => $gateway->get_method_title(), - 'method_description' => $gateway->get_method_description(), - 'method_supports' => $gateway->supports, - 'settings' => $this->get_settings( $gateway ), + return array( + 'id' => $object->id, + 'title' => $object->title, + 'description' => $object->description, + 'order' => isset( $order[ $object->id ] ) ? $order[ $object->id ] : '', + 'enabled' => ( 'yes' === $object->enabled ), + 'method_title' => $object->get_method_title(), + 'method_description' => $object->get_method_description(), + 'method_supports' => $object->supports, + 'settings' => $this->get_settings( $object ), ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $gateway, $request ) ); - - /** - * Filter payment gateway objects returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); } /** @@ -289,14 +282,14 @@ class PaymentGateways extends AbstractController { /** * Prepare links for the request. * - * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param \WP_REST_Request $request Request object. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. * @return array */ - protected function prepare_links( $gateway, $request ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $gateway->id ) ), + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->id ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), diff --git a/src/Controllers/Version4/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php index a07f9551d77..ad2110eb331 100644 --- a/src/Controllers/Version4/ProductAttributes.php +++ b/src/Controllers/Version4/ProductAttributes.php @@ -321,7 +321,7 @@ class ProductAttributes extends AbstractController { $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $item ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); /** * Filter a attribute item returned from the API. @@ -338,14 +338,15 @@ class ProductAttributes extends AbstractController { /** * Prepare links for the request. * - * @param object $attribute Attribute object. - * @return array Links for the given attribute. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $attribute ) { + protected function prepare_links( $item, $request ) { $base = '/' . $this->namespace . '/' . $this->rest_base; $links = array( 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $attribute->attribute_id ), + 'href' => rest_url( trailingslashit( $base ) . $item->attribute_id ), ), 'collection' => array( 'href' => rest_url( $base ), diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index 1265d9b7bab..263e9818f0e 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -33,6 +33,15 @@ class ProductReviews extends AbstractController { */ protected $resource_type = 'product_reviews'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'product_reviews'; + /** * Register the routes for product reviews. */ @@ -391,7 +400,6 @@ class ProductReviews extends AbstractController { $request->set_param( 'context', $context ); $response = $this->prepare_item_for_response( $review, $request ); - $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $review_id ) ) ); @@ -411,10 +419,7 @@ class ProductReviews extends AbstractController { return $review; } - $data = $this->prepare_item_for_response( $review, $request ); - $response = rest_ensure_response( $data ); - - return $response; + return $this->prepare_item_for_response( $review, $request ); } /** @@ -498,9 +503,7 @@ class ProductReviews extends AbstractController { $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $review, $request ); - - return rest_ensure_response( $response ); + return $this->prepare_item_for_response( $review, $request ); } /** @@ -573,32 +576,16 @@ class ProductReviews extends AbstractController { } /** - * Prepare a single product review output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Comment $review Product review object. + * @param \WP_Comment $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $review, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $fields = $this->get_fields_for_response( $request ); - $review_response = new ProductReviewResponse(); - $data = $review_response->prepare_response( $review, $context ); - $data = array_intersect_key( $data, array_flip( $fields ) ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); + protected function get_data_for_response( $object, $request ) { + $formatter = new ProductReviewResponse(); - $response->add_links( $this->prepare_links( $review ) ); - - /** - * Filter product reviews object returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param \WP_Comment $review Product review object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); } /** @@ -657,27 +644,28 @@ class ProductReviews extends AbstractController { /** * Prepare links for the request. * - * @param WP_Comment $review Product review object. - * @return array Links for the given product review. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $review ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $review->comment_ID ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->comment_ID ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), ), ); - if ( 0 !== (int) $review->comment_post_ID ) { + if ( 0 !== (int) $item->comment_post_ID ) { $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $review->comment_post_ID ) ), + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $item->comment_post_ID ) ), 'embeddable' => true, ); } - if ( 0 !== (int) $review->user_id ) { + if ( 0 !== (int) $item->user_id ) { $links['reviewer'] = array( - 'href' => rest_url( 'wp/v2/users/' . $review->user_id ), + 'href' => rest_url( 'wp/v2/users/' . $item->user_id ), 'embeddable' => true, ); } diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index bc4c08e3002..de8be8e44b5 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -847,16 +847,16 @@ class ProductVariations extends Products { /** * Prepare links for the request. * - * @param \WC_Data $object Object data. + * @param mixed $item Object to prepare. * @param \WP_REST_Request $request Request object. - * @return array Links for the given post. + * @return array */ - protected function prepare_links( $object, $request ) { + protected function prepare_links( $item, $request ) { $product_id = (int) $request['product_id']; $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $item->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 44e975e0868..2bd70170518 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -1092,24 +1092,23 @@ class Products extends AbstractObjectsController { /** * Prepare links for the request. * - * @param \WC_Data $object Object data. + * @param mixed $item Object to prepare. * @param \WP_REST_Request $request Request object. - * - * @return array Links for the given post. + * @return array */ - protected function prepare_links( $object, $request ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), // @codingStandardsIgnoreLine. + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), // @codingStandardsIgnoreLine. ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), // @codingStandardsIgnoreLine. ), ); - if ( $object->get_parent_id() ) { + if ( $item->get_parent_id() ) { $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $object->get_parent_id() ) ), // @codingStandardsIgnoreLine. + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $item->get_parent_id() ) ), // @codingStandardsIgnoreLine. ); } diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index 23fa5d58e80..a50d5e19f3d 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -106,14 +106,15 @@ class Settings extends AbstractController { /** * Prepare links for the request. * - * @param string $group_id Group ID. - * @return array Links for the given group. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $group_id ) { + protected function prepare_links( $item, $request ) { $base = '/' . $this->namespace . '/' . $this->rest_base; $links = array( 'options' => array( - 'href' => rest_url( trailingslashit( $base ) . $group_id ), + 'href' => rest_url( trailingslashit( $base ) . $item['id'] ), ), ); @@ -135,7 +136,7 @@ class Settings extends AbstractController { $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $item['id'] ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); return $response; } diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index 926e03cb7b3..8a4fdde3032 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -11,7 +11,7 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; +use WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; /** * REST API Setting Options controller class. @@ -366,22 +366,22 @@ class SettingsOptions extends AbstractController { $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, empty( $request['context'] ) ? 'view' : $request['context'] ); $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $data['id'], $request['group_id'] ) ); + $response->add_links( $this->prepare_links( $data, $request ) ); return $response; } /** * Prepare links for the request. * - * @param string $setting_id Setting ID. - * @param string $group_id Group ID. - * @return array Links for the given setting. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $setting_id, $group_id ) { - $base = str_replace( '(?P[\w-]+)', $group_id, $this->rest_base ); + protected function prepare_links( $item, $request ) { + $base = str_replace( '(?P[\w-]+)', $request['group_id'], $this->rest_base ); $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $base, $setting_id ) ), + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $base, $item['id'] ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php index 5358b507514..7cce50b9f4e 100644 --- a/src/Controllers/Version4/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -144,14 +144,14 @@ class ShippingMethods extends AbstractController { /** * Prepare links for the request. * - * @param \WC_Shipping_Method $method Shipping method object. - * @param \WP_REST_Request $request Request object. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. * @return array */ - protected function prepare_links( $method, $request ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $method->id ) ), + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->id ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), diff --git a/src/Controllers/Version4/ShippingZoneLocations.php b/src/Controllers/Version4/ShippingZoneLocations.php index a653426f4bc..37db8f33c9f 100644 --- a/src/Controllers/Version4/ShippingZoneLocations.php +++ b/src/Controllers/Version4/ShippingZoneLocations.php @@ -130,7 +130,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { // Wrap the data in a response object. $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( (int) $request['id'] ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); return $response; } @@ -138,11 +138,12 @@ class ShippingZoneLocations extends AbstractShippingZonesController { /** * Prepare links for the request. * - * @param int $zone_id Given Shipping Zone ID. - * @return array Links for the given Shipping Zone Location. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $zone_id ) { - $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + protected function prepare_links( $item, $request ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $request['id']; $links = array( 'collection' => array( 'href' => rest_url( $base . '/locations' ), diff --git a/src/Controllers/Version4/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php index 84d920cd973..1cd07109230 100644 --- a/src/Controllers/Version4/ShippingZoneMethods.php +++ b/src/Controllers/Version4/ShippingZoneMethods.php @@ -297,8 +297,8 @@ class ShippingZoneMethods extends AbstractShippingZonesController { /** * Updates settings, order, and enabled status on create. * - * @param int $instance_id Instance ID. - * @param WC_Shipping_Method $method Shipping method data. + * @param int $instance_id Instance ID. + * @param \WC_Shipping_Method $method Shipping method data. * @param \WP_REST_Request $request Request data. * * @return WC_Shipping_Method @@ -377,7 +377,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { // Wrap the data in a response object. $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $request['zone_id'], $item->instance_id ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); $response = $this->prepare_response_for_collection( $response ); @@ -416,15 +416,15 @@ class ShippingZoneMethods extends AbstractShippingZonesController { /** * Prepare links for the request. * - * @param int $zone_id Given Shipping Zone ID. - * @param int $instance_id Given Shipping Zone Method Instance ID. - * @return array Links for the given Shipping Zone Method. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $zone_id, $instance_id ) { - $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + protected function prepare_links( $item, $request ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $request['zone_id']; $links = array( 'self' => array( - 'href' => rest_url( $base . '/methods/' . $instance_id ), + 'href' => rest_url( $base . '/methods/' . $item->instance_id ), ), 'collection' => array( 'href' => rest_url( $base . '/methods' ), diff --git a/src/Controllers/Version4/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php index 16170276d12..203de94da0c 100644 --- a/src/Controllers/Version4/ShippingZones.php +++ b/src/Controllers/Version4/ShippingZones.php @@ -250,7 +250,7 @@ class ShippingZones extends AbstractShippingZonesController { // Wrap the data in a response object. $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $data['id'] ) ); + $response->add_links( $this->prepare_links( $data, $request ) ); return $response; } @@ -258,20 +258,21 @@ class ShippingZones extends AbstractShippingZonesController { /** * Prepare links for the request. * - * @param int $zone_id Given Shipping Zone ID. - * @return array Links for the given Shipping Zone. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $zone_id ) { + protected function prepare_links( $item, $request ) { $base = '/' . $this->namespace . '/' . $this->rest_base; $links = array( 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $zone_id ), + 'href' => rest_url( trailingslashit( $base ) . $item['id'] ), ), 'collection' => array( 'href' => rest_url( $base ), ), 'describedby' => array( - 'href' => rest_url( trailingslashit( $base ) . $zone_id . '/locations' ), + 'href' => rest_url( trailingslashit( $base ) . $item['id'] . '/locations' ), ), ); diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index cec20180f4b..d22521d1911 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -30,6 +30,15 @@ class SystemStatus extends AbstractController { */ protected $resource_type = 'system_status'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'system_status'; + /** * Register the route for /system_status */ @@ -585,26 +594,4 @@ class SystemStatus extends AbstractController { 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } - - /** - * Prepare the system status response - * - * @param array $system_status System status data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_item_for_response( $system_status, $request ) { - $data = $this->add_additional_fields_to_object( $system_status, $request ); - $data = $this->filter_response_by_context( $data, 'view' ); - $response = rest_ensure_response( $data ); - - /** - * Filter the system status returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param mixed $system_status System status - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_system_status', $response, $system_status, $request ); - } } diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php index 04aa4ab8d53..a82ce813dea 100644 --- a/src/Controllers/Version4/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -30,6 +30,15 @@ class SystemStatusTools extends AbstractController { */ protected $resource_type = 'system_status'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'system_status_tool'; + /** * Register the routes for /system_status/tools/*. */ @@ -257,25 +266,6 @@ class SystemStatusTools extends AbstractController { return rest_ensure_response( $response ); } - /** - * Prepare a tool item for serialization. - * - * @param array $item Object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item['id'] ) ); - - return $response; - } - /** * Get the system status tools schema, conforming to JSON Schema. * @@ -341,14 +331,15 @@ class SystemStatusTools extends AbstractController { /** * Prepare links for the request. * - * @param string $id ID. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. * @return array */ - protected function prepare_links( $id ) { + protected function prepare_links( $item, $request ) { $base = '/' . $this->namespace . '/' . $this->rest_base; $links = array( 'item' => array( - 'href' => rest_url( trailingslashit( $base ) . $id ), + 'href' => rest_url( trailingslashit( $base ) . $item['id'] ), 'embeddable' => true, ), ); diff --git a/src/Controllers/Version4/TaxClasses.php b/src/Controllers/Version4/TaxClasses.php index 6bd86c3bb71..c6ff2e99bc4 100644 --- a/src/Controllers/Version4/TaxClasses.php +++ b/src/Controllers/Version4/TaxClasses.php @@ -30,6 +30,15 @@ class TaxClasses extends AbstractController { */ protected $resource_type = 'settings'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'tax_class'; + /** * Register the routes for tax classes. */ @@ -243,46 +252,19 @@ class TaxClasses extends AbstractController { * @param \WP_REST_Response $response The response returned from the API. * @param \WP_REST_Request $request The request sent to the API. */ - do_action( 'woocommerce_rest_delete_tax', (object) $tax_class, $response, $request ); + do_action( 'woocommerce_rest_delete_tax_class', (object) $tax_class, $response, $request ); return $response; } - /** - * Prepare a single tax class output for response. - * - * @param array $tax_class Tax class data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $tax_class, $request ) { - $data = $tax_class; - - $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() ); - - /** - * Filter tax object returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param \stdClass $tax_class Tax object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_tax', $response, (object) $tax_class, $request ); - } - /** * Prepare links for the request. * - * @return array Links for the given tax class. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links() { + protected function prepare_links( $item, $request ) { $links = array( 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php index 9c1e915a313..bcb588cbae0 100644 --- a/src/Controllers/Version4/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -30,6 +30,15 @@ class Taxes extends AbstractController { */ protected $resource_type = 'settings'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'tax'; + /** * Register the routes for taxes. */ @@ -410,29 +419,29 @@ class Taxes extends AbstractController { } /** - * Prepare a single tax output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \stdClass $tax Tax object. + * @param \stdClass $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $tax, $request ) { + protected function get_data_for_response( $object, $request ) { global $wpdb; - $id = (int) $tax->tax_rate_id; + $id = (int) $object->tax_rate_id; $data = array( 'id' => $id, - 'country' => $tax->tax_rate_country, - 'state' => $tax->tax_rate_state, + 'country' => $object->tax_rate_country, + 'state' => $object->tax_rate_state, 'postcode' => '', 'city' => '', - 'rate' => $tax->tax_rate, - 'name' => $tax->tax_rate_name, - 'priority' => (int) $tax->tax_rate_priority, - 'compound' => (bool) $tax->tax_rate_compound, - 'shipping' => (bool) $tax->tax_rate_shipping, - 'order' => (int) $tax->tax_rate_order, - 'class' => $tax->tax_rate_class ? $tax->tax_rate_class : 'standard', + 'rate' => $object->tax_rate, + 'name' => $object->tax_rate_name, + 'priority' => (int) $object->tax_rate_priority, + 'compound' => (bool) $object->tax_rate_compound, + 'shipping' => (bool) $object->tax_rate_shipping, + 'order' => (int) $object->tax_rate_order, + 'class' => $object->tax_rate_class ? $object->tax_rate_class : 'standard', ); // Get locales from a tax rate. @@ -447,41 +456,25 @@ class Taxes extends AbstractController { ) ); - if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) { + if ( ! is_wp_error( $locales ) && ! is_null( $locales ) ) { foreach ( $locales as $locale ) { $data[ $locale->location_type ] = $locale->location_code; } } - - $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( $tax ) ); - - /** - * Filter tax object returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param \stdClass $tax Tax object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_tax', $response, $tax, $request ); + return $data; } /** * Prepare links for the request. * - * @param \stdClass $tax Tax object. - * @return array Links for the given tax. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array */ - protected function prepare_links( $tax ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->tax_rate_id ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index 1a6b1e01e93..d8c19ad957b 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -490,7 +490,7 @@ class Webhooks extends AbstractController { // Wrap the data in a response object. $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $webhook->get_id() ) ); + $response->add_links( $this->prepare_links( $webhook, $request ) ); /** * Filter webhook object returned from the REST API. @@ -505,13 +505,14 @@ class Webhooks extends AbstractController { /** * Prepare links for the request. * - * @param int $id Webhook ID. + * @param mixed $item Object to prepare. + * @param \WP_REST_Request $request Request object. * @return array */ - protected function prepare_links( $id ) { + protected function prepare_links( $item, $request ) { $links = array( 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $id ) ), + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), From a4e89f89ce5bf82b723185d17c42037787ab3839 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 18 Jun 2019 12:45:34 +0100 Subject: [PATCH 156/440] Consistent responses across all classes --- .../Version4/AbstractController.php | 32 ++- .../Version4/AbstractObjectsController.php | 30 +-- .../Version4/AbstractTermsContoller.php | 10 + src/Controllers/Version4/Coupons.php | 29 --- src/Controllers/Version4/Data/Continents.php | 35 ++- src/Controllers/Version4/Data/Countries.php | 35 ++- src/Controllers/Version4/Data/Currencies.php | 32 ++- src/Controllers/Version4/Data/DownloadIPs.php | 35 ++- src/Controllers/Version4/OrderRefunds.php | 209 +++++------------- src/Controllers/Version4/Orders.php | 92 +------- .../Version4/ProductAttributeTerms.php | 44 +--- .../Version4/ProductAttributes.php | 52 ++--- .../Version4/ProductCategories.php | 64 +++--- .../Version4/ProductShippingClasses.php | 50 ++--- src/Controllers/Version4/ProductTags.php | 50 ++--- .../Version4/ProductVariations.php | 43 ++-- src/Controllers/Version4/Products.php | 43 ++-- src/Controllers/Version4/Settings.php | 29 +-- src/Controllers/Version4/SettingsOptions.php | 28 ++- src/Controllers/Version4/ShippingMethods.php | 45 ++-- .../Version4/ShippingZoneLocations.php | 31 +-- .../Version4/ShippingZoneMethods.php | 59 ++--- src/Controllers/Version4/ShippingZones.php | 36 ++- src/Controllers/Version4/Webhooks.php | 107 ++++----- 24 files changed, 458 insertions(+), 762 deletions(-) diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index 809b37f5cdf..9c409257981 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -274,14 +274,18 @@ abstract class AbstractController extends WP_REST_Controller { * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { - $context = $this->get_request_context( $request ); - $fields = $this->get_fields_for_response( $request ); - $data = array_intersect_key( $this->get_data_for_response( $item, $request ), array_flip( $fields ) ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); + try { + $context = $this->get_request_context( $request ); + $fields = $this->get_fields_for_response( $request ); + $data = $this->get_data_for_response( $item, $request ); + $data = array_intersect_key( $data, array_flip( $fields ) ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $item, $request ) ); + } catch ( \WC_REST_Exception $e ) { + $response = rest_ensure_response( new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ) ); + } /** * Filter object returned from the REST API. @@ -290,7 +294,17 @@ abstract class AbstractController extends WP_REST_Controller { * @param mixed $item Object used to create response. * @param \WP_REST_Request $request Request object. */ - return apply_filters( "woocommerce_rest_prepare_{$this->singular}", $response, $item, $request ); + return apply_filters( 'woocommerce_rest_prepare_' . $this->get_hook_suffix( $item ), $response, $item, $request ); + } + + /** + * Return suffix for item action hooks. + * + * @param mixed $item Object used to create response. + * @return string + */ + protected function get_hook_suffix( $item ) { + return $this->singular; } /** diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index db814217eae..a4827d4b663 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -38,16 +38,6 @@ abstract class AbstractObjectsController extends AbstractController { */ abstract protected function get_object( $id ); - /** - * Prepares the object for the REST response. - * - * @since 3.0.0 - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response Response object on success, or \WP_Error object on failure. - */ - abstract protected function prepare_object_for_response( $object, $request ); - /** * Prepares one object for create or update operation. * @@ -171,7 +161,7 @@ abstract class AbstractObjectsController extends AbstractController { return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - $data = $this->prepare_object_for_response( $object, $request ); + $data = $this->prepare_item_for_response( $object, $request ); $response = rest_ensure_response( $data ); return $response; @@ -241,7 +231,7 @@ abstract class AbstractObjectsController extends AbstractController { do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); + $response = $this->prepare_item_for_response( $object, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ) ); @@ -286,7 +276,7 @@ abstract class AbstractObjectsController extends AbstractController { do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); + $response = $this->prepare_item_for_response( $object, $request ); return rest_ensure_response( $response ); } @@ -393,7 +383,7 @@ abstract class AbstractObjectsController extends AbstractController { continue; } - $data = $this->prepare_object_for_response( $object, $request ); + $data = $this->prepare_item_for_response( $object, $request ); $objects[] = $this->prepare_response_for_collection( $data ); } @@ -460,7 +450,7 @@ abstract class AbstractObjectsController extends AbstractController { } $request->set_param( 'context', 'edit' ); - $previous = $this->prepare_object_for_response( $object, $request ); + $previous = $this->prepare_item_for_response( $object, $request ); // If we're forcing, then delete permanently. if ( $force ) { @@ -833,4 +823,14 @@ abstract class AbstractObjectsController extends AbstractController { return $args['meta_query']; } + + /** + * Return suffix for item action hooks. + * + * @param mixed $item Object used to create response. + * @return string + */ + protected function get_hook_suffix( $item ) { + return $this->post_type . '_object'; + } } diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index f82a3fe148a..e5916460e6e 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -749,4 +749,14 @@ abstract class AbstractTermsContoller extends AbstractController { return $this->taxonomy; } + + /** + * Return suffix for item action hooks. + * + * @param mixed $item Object used to create response. + * @return string + */ + protected function get_hook_suffix( $item ) { + return $this->taxonomy; + } } diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index 36061f3b814..c158c81faa6 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -103,35 +103,6 @@ class Coupons extends AbstractObjectsController { ); } - /** - * Prepare a single coupon output for response. - * - * @since 3.0.0 - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $data = $this->get_data_for_response( $object, $request ); - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param \WP_REST_Response $response The response object. - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - /** * Prepare objects query. * diff --git a/src/Controllers/Version4/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php index 94fb82d9256..23212b3f160 100644 --- a/src/Controllers/Version4/Data/Continents.php +++ b/src/Controllers/Version4/Data/Continents.php @@ -25,6 +25,15 @@ class Continents extends DataController { */ protected $rest_base = 'data/continents'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'continent'; + /** * Register routes. * @@ -186,30 +195,14 @@ class Continents extends DataController { } /** - * Prepare the data object for response. + * Get data for this object in the format of this endpoint's schema. * - * @since 3.5.0 - * @param object $item Data object. + * @param mixed $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @return mixed Array of data in the correct format. */ - 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 ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter the location list returned from the API. - * - * Allows modification of the loction data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param array $item The original list of continent(s), countries, and states. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_data_continent', $response, $item, $request ); + protected function get_data_for_response( $object, $request ) { + return $object; } /** diff --git a/src/Controllers/Version4/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php index 0d3090ff0d7..197ccda374a 100644 --- a/src/Controllers/Version4/Data/Countries.php +++ b/src/Controllers/Version4/Data/Countries.php @@ -25,6 +25,15 @@ class Countries extends DataController { */ protected $rest_base = 'data/countries'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'country'; + /** * Register routes. * @@ -133,30 +142,14 @@ class Countries extends DataController { } /** - * Prepare the data object for response. + * Get data for this object in the format of this endpoint's schema. * - * @since 3.5.0 - * @param object $item Data object. + * @param mixed $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @return mixed Array of data in the correct format. */ - 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 ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter the states list for a country returned from the API. - * - * Allows modification of the loction data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param array $data The original country's states list. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_data_country', $response, $item, $request ); + protected function get_data_for_response( $object, $request ) { + return $object; } /** diff --git a/src/Controllers/Version4/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php index ff537ab71bd..c5bbdac098d 100644 --- a/src/Controllers/Version4/Data/Currencies.php +++ b/src/Controllers/Version4/Data/Currencies.php @@ -25,6 +25,15 @@ class Currencies extends DataController { */ protected $rest_base = 'data/currencies'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'currency'; + /** * Register routes. */ @@ -140,27 +149,14 @@ class Currencies extends DataController { } /** - * Prepare the data object for response. + * Get data for this object in the format of this endpoint's schema. * - * @param object $item Data object. + * @param mixed $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @return mixed Array of data in the correct format. */ - 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 ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter currency returned from the API. - * - * @param \WP_REST_Response $response The response object. - * @param array $item Currency data. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_data_currency', $response, $item, $request ); + protected function get_data_for_response( $object, $request ) { + return $object; } /** diff --git a/src/Controllers/Version4/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php index 37651f38281..02b4d8c84c8 100644 --- a/src/Controllers/Version4/Data/DownloadIPs.php +++ b/src/Controllers/Version4/Data/DownloadIPs.php @@ -25,6 +25,15 @@ class DownloadIPs extends DataController { */ protected $rest_base = 'data/download-ips'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'download_ip'; + /** * Register routes. * @@ -72,7 +81,7 @@ class DownloadIPs extends DataController { if ( ! empty( $downloads ) ) { foreach ( $downloads as $download ) { - $response = $this->prepare_item_for_response( $download, $request ); + $response = $this->prepare_item_for_response( (array) $download, $request ); $data[] = $this->prepare_response_for_collection( $response ); } } @@ -81,28 +90,14 @@ class DownloadIPs extends DataController { } /** - * Prepare the data object for response. + * Get data for this object in the format of this endpoint's schema. * - * @since 3.5.0 - * @param object $item Data object. + * @param mixed $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @return mixed Array of data in the correct format. */ - 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 ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * 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_data_download_ip', $response, $item, $request ); + protected function get_data_for_response( $object, $request ) { + return $object; } /** diff --git a/src/Controllers/Version4/OrderRefunds.php b/src/Controllers/Version4/OrderRefunds.php index 80910d6c985..f8869581159 100644 --- a/src/Controllers/Version4/OrderRefunds.php +++ b/src/Controllers/Version4/OrderRefunds.php @@ -30,13 +30,6 @@ class OrderRefunds extends Orders { */ protected $post_type = 'shop_order_refund'; - /** - * Stores the request. - * - * @var array - */ - protected $request = array(); - /** * Order refunds actions. */ @@ -129,19 +122,32 @@ class OrderRefunds extends Orders { /** * Get data for this object in the format of this endpoint's schema. * + * @throws \WC_REST_Exception Exception on invalid data. + * * @param mixed $object Object to prepare. * @param \WP_REST_Request $request Request object. * @return array Array of data in the correct format. */ protected function get_data_for_response( $object, $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + } + $data = $object->get_data(); $format_decimal = array( 'amount' ); $format_date = array( 'date_created' ); $format_line_items = array( 'line_items' ); + $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); // Format decimal values. foreach ( $format_decimal as $key ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + $data[ $key ] = wc_format_decimal( $data[ $key ], $dp ); } // Format date values. @@ -153,7 +159,7 @@ class OrderRefunds extends Orders { // Format line items. foreach ( $format_line_items as $key ) { - $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); + $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ], $request ) ); } return array( @@ -170,167 +176,56 @@ class OrderRefunds extends Orders { } /** - * Prepare a single order output for response. + * Expands an order item to get its data. * - * @since 3.0.0 - * - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - * - * @return \WP_Error|\WP_REST_Response + * @param \WC_Order_item $item Order item data. + * @param \WP_REST_Response $response The response object. + * @return array */ - public function prepare_object_for_response( $object, $request ) { - $this->request = $request; - $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); - $order = wc_get_order( (int) $request['order_id'] ); + protected function get_order_item_data( $item, $request ) { + $data = $item->get_data(); + $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); + $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); - if ( ! $order ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); - } - - if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); - } - - $data = $this->get_data_for_response( $object, $request ); - $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( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param \WP_REST_Response $response The response object. - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - - /** - * Prepare a single order refund output for response. - * - * @param \WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * - * @return \WP_Error|\WP_REST_Response - */ - public function prepare_item_for_response( $post, $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); - } - - $refund = wc_get_order( $post ); - - if ( ! $refund || $refund->get_parent_id() !== $order->get_id() ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); - } - - $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); - - $data = array( - 'id' => $refund->get_id(), - 'date_created' => wc_rest_prepare_date_response( $refund->get_date_created() ), - 'amount' => wc_format_decimal( $refund->get_amount(), $dp ), - 'reason' => $refund->get_reason(), - 'line_items' => array(), - ); - - // Add line items. - foreach ( $refund->get_items() as $item_id => $item ) { - $product = $item->get_product(); - $product_id = 0; - $variation_id = 0; - $product_sku = null; - - // Check if the product exists. - if ( is_object( $product ) ) { - $product_id = $item->get_product_id(); - $variation_id = $item->get_variation_id(); - $product_sku = $product->get_sku(); + // Format decimal values. + foreach ( $format_decimal as $key ) { + if ( isset( $data[ $key ] ) ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); } + } - $item_meta = array(); + // Add SKU and PRICE to products. + if ( is_callable( array( $item, 'get_product' ) ) ) { + $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; + $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; + } - $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; + // Format taxes. + if ( ! empty( $data['taxes']['total'] ) ) { + $taxes = array(); - foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { - $item_meta[] = array( - 'key' => $formatted_meta->key, - 'label' => $formatted_meta->display_key, - 'value' => wc_clean( $formatted_meta->display_value ), + foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { + $taxes[] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', ); } - - $line_item = array( - 'id' => $item_id, - 'name' => $item['name'], - 'sku' => $product_sku, - 'product_id' => (int) $product_id, - 'variation_id' => (int) $variation_id, - 'quantity' => wc_stock_amount( $item['qty'] ), - 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', - 'price' => wc_format_decimal( $refund->get_item_total( $item, false, false ), $dp ), - 'subtotal' => wc_format_decimal( $refund->get_line_subtotal( $item, false, false ), $dp ), - 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), - 'total' => wc_format_decimal( $refund->get_line_total( $item, false, false ), $dp ), - 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), - 'taxes' => array(), - 'meta' => $item_meta, - ); - - $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); - if ( isset( $item_line_taxes['total'] ) ) { - $line_tax = array(); - - foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { - $line_tax[ $tax_rate_id ] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => '', - ); - } - - foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { - $line_tax[ $tax_rate_id ]['subtotal'] = $tax; - } - - $line_item['taxes'] = array_values( $line_tax ); - } - - $data['line_items'][] = $line_item; + $data['taxes'] = $taxes; + } elseif ( isset( $data['taxes'] ) ) { + $data['taxes'] = array(); } - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); + // Remove names for coupons, taxes and shipping. + if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { + unset( $data['name'] ); + } - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); + // Remove props we don't want to expose. + unset( $data['order_id'] ); + unset( $data['type'] ); - $response->add_links( $this->prepare_links( $refund, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. - * - * @param \WP_REST_Response $response The response object. - * @param \WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + return $data; } /** diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index 8d407a320ae..e04a3652e1a 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -40,13 +40,6 @@ class Orders extends AbstractObjectsController { */ protected $hierarchical = true; - /** - * Stores the request. - * - * @var array - */ - protected $request = array(); - /** * Get object. Return false if object is not of required type. * @@ -65,89 +58,20 @@ class Orders extends AbstractObjectsController { } /** - * Expands an order item to get its data. + * Get data for this object in the format of this endpoint's schema. * - * @param \WC_Order_item $item Order item data. - * @return array + * @param \WP_Comment $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - protected function get_order_item_data( $item ) { - $data = $item->get_data(); - $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - if ( isset( $data[ $key ] ) ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); - } - } - - // Add SKU and PRICE to products. - if ( is_callable( array( $item, 'get_product' ) ) ) { - $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; - $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; - } - - // Format taxes. - if ( ! empty( $data['taxes']['total'] ) ) { - $taxes = array(); - - foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { - $taxes[] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', - ); - } - $data['taxes'] = $taxes; - } elseif ( isset( $data['taxes'] ) ) { - $data['taxes'] = array(); - } - - // Remove names for coupons, taxes and shipping. - if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { - unset( $data['name'] ); - } - - // Remove props we don't want to expose. - unset( $data['order_id'] ); - unset( $data['type'] ); - - return $data; - } - - /** - * Prepare a single order output for response. - * - * @since 3.0.0 - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $order_response = new OrderResponse(); + protected function get_data_for_response( $object, $request ) { + $formatter = new OrderResponse(); if ( ! is_null( $request['dp'] ) ) { - $order_response->set_dp( $request['dp'] ); + $formatter->set_dp( $request['dp'] ); } - $data = $order_response->prepare_response( $object, $context ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param \WP_REST_Response $response The response object. - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); } /** diff --git a/src/Controllers/Version4/ProductAttributeTerms.php b/src/Controllers/Version4/ProductAttributeTerms.php index 7d831e0b633..18ed0d19edb 100644 --- a/src/Controllers/Version4/ProductAttributeTerms.php +++ b/src/Controllers/Version4/ProductAttributeTerms.php @@ -131,43 +131,23 @@ class ProductAttributeTerms extends AbstractTermsContoller { } /** - * Prepare a single product attribute term output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Term $item Term object. - * @param \WP_REST_Request $request Request params. - * @return \WP_REST_Response $response + * @param \WP_Term $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $item, $request ) { - // Get term order. - $menu_order = get_term_meta( $item->term_id, 'order_' . $this->taxonomy, true ); + protected function get_data_for_response( $object, $request ) { + $menu_order = get_term_meta( $object->term_id, 'order_' . $this->taxonomy, true ); - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'description' => $item->description, + return array( + 'id' => (int) $object->term_id, + 'name' => $object->name, + 'slug' => $object->slug, + 'description' => $object->description, 'menu_order' => (int) $menu_order, - 'count' => (int) $item->count, + 'count' => (int) $object->count, ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); } /** diff --git a/src/Controllers/Version4/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php index ad2110eb331..b13ac14dfad 100644 --- a/src/Controllers/Version4/ProductAttributes.php +++ b/src/Controllers/Version4/ProductAttributes.php @@ -37,6 +37,15 @@ class ProductAttributes extends AbstractController { */ protected $attribute = ''; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'product_attribute'; + /** * Register the routes for product attributes. */ @@ -299,40 +308,21 @@ class ProductAttributes extends AbstractController { } /** - * Prepare a single product attribute output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param obj $item Term object. - * @param \WP_REST_Request $request Request params. - * @return \WP_REST_Response $response + * @param object $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $item, $request ) { - $data = array( - 'id' => (int) $item->attribute_id, - 'name' => $item->attribute_label, - 'slug' => wc_attribute_taxonomy_name( $item->attribute_name ), - 'type' => $item->attribute_type, - 'order_by' => $item->attribute_orderby, - 'has_archives' => (bool) $item->attribute_public, + protected function get_data_for_response( $object, $request ) { + return array( + 'id' => (int) $object->attribute_id, + 'name' => $object->attribute_label, + 'slug' => wc_attribute_taxonomy_name( $object->attribute_name ), + 'type' => $object->attribute_type, + 'order_by' => $object->attribute_orderby, + 'has_archives' => (bool) $object->attribute_public, ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a attribute item returned from the API. - * - * Allows modification of the product attribute data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $item The original attribute object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_product_attribute', $response, $item, $request ); } /** diff --git a/src/Controllers/Version4/ProductCategories.php b/src/Controllers/Version4/ProductCategories.php index 76940158244..b263423fa8f 100644 --- a/src/Controllers/Version4/ProductCategories.php +++ b/src/Controllers/Version4/ProductCategories.php @@ -31,33 +31,37 @@ class ProductCategories extends AbstractTermsContoller { protected $taxonomy = 'product_cat'; /** - * Prepare a single product category output for response. + * Singular name for resource type. * - * @param WP_Term $item Term object. - * @param \WP_REST_Request $request Request instance. - * @return \WP_REST_Response + * Used in filter/action names for single resources. + * + * @var string */ - public function prepare_item_for_response( $item, $request ) { - // Get category display type. - $display_type = get_term_meta( $item->term_id, 'display_type', true ); + protected $singular = 'product_cat'; - // Get category order. - $menu_order = get_term_meta( $item->term_id, 'order', true ); - - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'parent' => (int) $item->parent, - 'description' => $item->description, + /** + * Get data for this object in the format of this endpoint's schema. + * + * @param \WP_Term $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. + */ + protected function get_data_for_response( $object, $request ) { + $display_type = get_term_meta( $object->term_id, 'display_type', true ); + $menu_order = get_term_meta( $object->term_id, 'order', true ); + $image_id = get_term_meta( $object->term_id, 'thumbnail_id', true ); + $data = array( + 'id' => (int) $object->term_id, + 'name' => $object->name, + 'slug' => $object->slug, + 'parent' => (int) $object->parent, + 'description' => $object->description, 'display' => $display_type ? $display_type : 'default', 'image' => null, 'menu_order' => (int) $menu_order, - 'count' => (int) $item->count, + 'count' => (int) $object->count, ); - // Get category image. - $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); if ( $image_id ) { $attachment = get_post( $image_id ); @@ -72,31 +76,13 @@ class ProductCategories extends AbstractTermsContoller { 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), ); } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + return $data; } /** * Update term meta fields. * - * @param WP_Term $term Term object. + * @param \WP_Term $term Term object. * @param \WP_REST_Request $request Request instance. * @return bool|\WP_Error * diff --git a/src/Controllers/Version4/ProductShippingClasses.php b/src/Controllers/Version4/ProductShippingClasses.php index 57c3a5fc5c5..e2a693df692 100644 --- a/src/Controllers/Version4/ProductShippingClasses.php +++ b/src/Controllers/Version4/ProductShippingClasses.php @@ -31,39 +31,29 @@ class ProductShippingClasses extends AbstractTermsContoller { protected $taxonomy = 'product_shipping_class'; /** - * Prepare a single product shipping class output for response. + * Singular name for resource type. * - * @param object $item Term object. - * @param \WP_REST_Request $request Request params. - * @return \WP_REST_Response $response + * Used in filter/action names for single resources. + * + * @var string */ - public function prepare_item_for_response( $item, $request ) { - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'description' => $item->description, - 'count' => (int) $item->count, + protected $singular = 'product_shipping_class'; + + /** + * Get data for this object in the format of this endpoint's schema. + * + * @param \WP_Term $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. + */ + protected function get_data_for_response( $object, $request ) { + return array( + 'id' => (int) $object->term_id, + 'name' => $object->name, + 'slug' => $object->slug, + 'description' => $object->description, + 'count' => (int) $object->count, ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); } /** diff --git a/src/Controllers/Version4/ProductTags.php b/src/Controllers/Version4/ProductTags.php index 1144bae2b05..ba70253a7a4 100644 --- a/src/Controllers/Version4/ProductTags.php +++ b/src/Controllers/Version4/ProductTags.php @@ -31,39 +31,29 @@ class ProductTags extends AbstractTermsContoller { protected $taxonomy = 'product_tag'; /** - * Prepare a single product tag output for response. + * Singular name for resource type. * - * @param object $item Term object. - * @param \WP_REST_Request $request Request params. - * @return \WP_REST_Response $response + * Used in filter/action names for single resources. + * + * @var string */ - public function prepare_item_for_response( $item, $request ) { - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'description' => $item->description, - 'count' => (int) $item->count, + protected $singular = 'product_tag'; + + /** + * Get data for this object in the format of this endpoint's schema. + * + * @param \WP_Term $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. + */ + protected function get_data_for_response( $object, $request ) { + return array( + 'id' => (int) $object->term_id, + 'name' => $object->name, + 'slug' => $object->slug, + 'description' => $object->description, + 'count' => (int) $object->count, ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param \WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param \WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); } /** diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index de8be8e44b5..da66cdc8878 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -34,6 +34,15 @@ class ProductVariations extends Products { */ protected $post_type = 'product_variation'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'product_variation'; + /** * Register the routes for products. */ @@ -582,32 +591,16 @@ class ProductVariations extends Products { } /** - * Prepare a single variation output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response + * @param \WC_Variation $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_object_for_response( $object, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $variation_response = new ProductVariationResponse(); - $data = $variation_response->prepare_response( $object, $context ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); + protected function get_data_for_response( $object, $request ) { + $formatter = new ProductVariationResponse(); - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param \WP_REST_Response $response The response object. - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); } /** @@ -750,7 +743,7 @@ class ProductVariations extends Products { // If we're forcing, then delete permanently. if ( $force ) { - $previous = $this->prepare_object_for_response( $object, $request ); + $previous = $this->prepare_item_for_response( $object, $request ); $object->delete( true ); @@ -788,7 +781,7 @@ class ProductVariations extends Products { $result = 'trash' === $object->get_status(); } - $response = $this->prepare_object_for_response( $object, $request ); + $response = $this->prepare_item_for_response( $object, $request ); } if ( ! $result ) { diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 2bd70170518..2308f2c0e7d 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -41,6 +41,15 @@ class Products extends AbstractObjectsController { */ protected $hierarchical = true; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'product'; + /** * Get the Product's schema, conforming to JSON Schema. * @@ -822,34 +831,16 @@ class Products extends AbstractObjectsController { } /** - * Prepare a single product output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \WC_Data $object Object data. + * @param \WC_Product $object Object to prepare. * @param \WP_REST_Request $request Request object. - * - * @since 3.0.0 - * @return \WP_REST_Response + * @return array Array of data in the correct format. */ - public function prepare_object_for_response( $object, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $product_response = new ProductResponse(); - $data = $product_response->prepare_response( $object, $context ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); + protected function get_data_for_response( $object, $request ) { + $formatter = new ProductResponse(); - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param \WP_REST_Response $response The response object. - * @param \WC_Data $object Object data. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); } /** @@ -1175,7 +1166,7 @@ class Products extends AbstractObjectsController { // If we're forcing, then delete permanently. if ( $force ) { - $previous = $this->prepare_object_for_response( $object, $request ); + $previous = $this->prepare_item_for_response( $object, $request ); $object->delete( true ); $result = 0 === $object->get_id(); @@ -1217,7 +1208,7 @@ class Products extends AbstractObjectsController { $result = 'trash' === $object->get_status(); } - $response = $this->prepare_object_for_response( $object, $request ); + $response = $this->prepare_item_for_response( $object, $request ); } if ( ! $result ) { diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index a50d5e19f3d..8a1cefd176f 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -30,6 +30,15 @@ class Settings extends AbstractController { */ protected $resource_type = 'settings'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'setting'; + /** * Register routes. * @@ -121,26 +130,6 @@ class Settings extends AbstractController { return $links; } - /** - * Prepare a report sales object for serialization. - * - * @since 3.0.0 - * @param array $item Group object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - return $response; - } - /** * Filters out bad values from the groups array/filter so we * only return known values via the API. diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index 8a4fdde3032..7389c316257 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -33,6 +33,15 @@ class SettingsOptions extends AbstractController { */ protected $rest_base = 'settings/(?P[\w-]+)'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'setting_option'; + /** * Register routes. * @@ -354,20 +363,15 @@ class SettingsOptions extends AbstractController { } /** - * Prepare a single setting object for response. + * Get data for this object in the format of this endpoint's schema. * - * @param object $item Setting object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @param \WC_Shipping_Method $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $item, $request ) { - unset( $item['option_key'] ); - $data = $this->filter_setting( $item ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, empty( $request['context'] ) ? 'view' : $request['context'] ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $data, $request ) ); - return $response; + protected function get_data_for_response( $object, $request ) { + unset( $object['option_key'] ); + return $this->filter_setting( $object ); } /** diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php index 7cce50b9f4e..cb2f27b3af0 100644 --- a/src/Controllers/Version4/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -30,6 +30,15 @@ class ShippingMethods extends AbstractController { */ protected $resource_type = 'shipping_methods'; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'shipping_method'; + /** * Register the route for /shipping_methods and /shipping_methods/ */ @@ -109,36 +118,18 @@ class ShippingMethods extends AbstractController { } /** - * Prepare a shipping method for response. + * Get data for this object in the format of this endpoint's schema. * - * @param \WC_Shipping_Method $method Shipping method object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. + * @param \WC_Shipping_Method $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $method, $request ) { - $data = array( - 'id' => $method->id, - 'title' => $method->method_title, - 'description' => $method->method_description, + protected function get_data_for_response( $object, $request ) { + return array( + 'id' => $object->id, + 'title' => $object->method_title, + 'description' => $object->method_description, ); - - $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( $method, $request ) ); - - /** - * Filter shipping methods object returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param \WC_Shipping_Method $method Shipping method object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_shipping_method', $response, $method, $request ); } /** diff --git a/src/Controllers/Version4/ShippingZoneLocations.php b/src/Controllers/Version4/ShippingZoneLocations.php index 37db8f33c9f..201712f52b4 100644 --- a/src/Controllers/Version4/ShippingZoneLocations.php +++ b/src/Controllers/Version4/ShippingZoneLocations.php @@ -16,6 +16,15 @@ defined( 'ABSPATH' ) || exit; */ class ShippingZoneLocations extends AbstractShippingZonesController { + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'shipping_zone_location'; + /** * Register the routes for Shipping Zone Locations. */ @@ -64,7 +73,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { $data = array(); foreach ( $locations as $location_obj ) { - $location = $this->prepare_item_for_response( $location_obj, $request ); + $location = $this->prepare_item_for_response( (array) $location_obj, $request ); $location = $this->prepare_response_for_collection( $location ); $data[] = $location; } @@ -115,26 +124,6 @@ class ShippingZoneLocations extends AbstractShippingZonesController { return $this->get_items( $request ); } - /** - * Prepare the Shipping Zone Location for the REST response. - * - * @param array $item Shipping Zone Location. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response - */ - public function prepare_item_for_response( $item, $request ) { - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $data = $this->add_additional_fields_to_object( $item, $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( $item, $request ) ); - - return $response; - } - /** * Prepare links for the request. * diff --git a/src/Controllers/Version4/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php index 1cd07109230..b4e4211ed4b 100644 --- a/src/Controllers/Version4/ShippingZoneMethods.php +++ b/src/Controllers/Version4/ShippingZoneMethods.php @@ -19,6 +19,15 @@ use \WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; class ShippingZoneMethods extends AbstractShippingZonesController { use SettingsTrait; + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'shipping_zone_method'; + /** * Register the routes for Shipping Zone Methods. */ @@ -351,36 +360,36 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } /** - * Prepare the Shipping Zone Method for the REST response. + * Get data for this object in the format of this endpoint's schema. * - * @param array $item Shipping Zone Method. + * @param array $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response + * @return array Array of data in the correct format. + */ + protected function get_data_for_response( $object, $request ) { + return array( + 'id' => $object->instance_id, + 'instance_id' => $object->instance_id, + 'title' => $object->instance_settings['title'], + 'order' => $object->method_order, + 'enabled' => ( 'yes' === $object->enabled ), + 'method_id' => $object->id, + 'method_title' => $object->method_title, + 'method_description' => $object->method_description, + 'settings' => $this->get_settings( $object ), + ); + } + + /** + * Prepare a single item for response. + * + * @param mixed $item Object used to create response. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { - $method = array( - 'id' => $item->instance_id, - 'instance_id' => $item->instance_id, - 'title' => $item->instance_settings['title'], - 'order' => $item->method_order, - 'enabled' => ( 'yes' === $item->enabled ), - 'method_id' => $item->id, - 'method_title' => $item->method_title, - 'method_description' => $item->method_description, - 'settings' => $this->get_settings( $item ), - ); - - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $data = $this->add_additional_fields_to_object( $method, $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( $item, $request ) ); - + $response = parent::prepare_item_for_response( $item, $request ); $response = $this->prepare_response_for_collection( $response ); - return $response; } diff --git a/src/Controllers/Version4/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php index 203de94da0c..d26886dfb78 100644 --- a/src/Controllers/Version4/ShippingZones.php +++ b/src/Controllers/Version4/ShippingZones.php @@ -16,6 +16,15 @@ defined( 'ABSPATH' ) || exit; */ class ShippingZones extends AbstractShippingZonesController { + /** + * Singular name for resource type. + * + * Used in filter/action names for single resources. + * + * @var string + */ + protected $singular = 'shipping_zone'; + /** * Register the routes for Shipping Zones. */ @@ -230,29 +239,18 @@ class ShippingZones extends AbstractShippingZonesController { } /** - * Prepare the Shipping Zone for the REST response. + * Get data for this object in the format of this endpoint's schema. * - * @param array $item Shipping Zone. + * @param \WP_Comment $object Object to prepare. * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $item, $request ) { - $data = array( - 'id' => (int) $item['id'], - 'name' => $item['zone_name'], - 'order' => (int) $item['zone_order'], + protected function get_data_for_response( $object, $request ) { + return array( + 'id' => (int) $object['id'], + 'name' => $object['zone_name'], + 'order' => (int) $object['zone_order'], ); - - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $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( $data, $request ) ); - - return $response; } /** diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index d8c19ad957b..667f5d09693 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -169,7 +169,13 @@ class Webhooks extends AbstractController { $webhook_ids = $results->webhooks; foreach ( $webhook_ids as $webhook_id ) { - $data = $this->prepare_item_for_response( $webhook_id, $request ); + $object = $this->get_object( $webhook_id ); + + if ( ! $object || 0 === $object->get_id() ) { + continue; + } + + $data = $this->prepare_item_for_response( $object, $request ); $webhooks[] = $this->prepare_response_for_collection( $data ); } @@ -200,6 +206,22 @@ class Webhooks extends AbstractController { return $response; } + /** + * Get object. + * + * @param int $id Object ID. + * @return \WC_Webhook|bool + */ + protected function get_object( $id ) { + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return false; + } + + return $webhook; + } + /** * Get a single item. * @@ -207,16 +229,13 @@ class Webhooks extends AbstractController { * @return \WP_Error|\WP_REST_Response */ public function get_item( $request ) { - $id = (int) $request['id']; + $object = $this->get_object( (int) $request['id'] ); - if ( empty( $id ) ) { + if ( ! $object || 0 === $object->get_id() ) { return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - $data = $this->prepare_item_for_response( $id, $request ); - $response = rest_ensure_response( $data ); - - return $response; + return $this->prepare_item_for_response( $object, $request ); } /** @@ -268,7 +287,7 @@ class Webhooks extends AbstractController { do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, true ); $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); + $response = $this->prepare_item_for_response( $webhook, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $webhook->get_id() ) ) ); @@ -348,7 +367,7 @@ class Webhooks extends AbstractController { do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, false ); $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); + $response = $this->prepare_item_for_response( $webhook, $request ); return rest_ensure_response( $response ); } @@ -455,51 +474,27 @@ class Webhooks extends AbstractController { } /** - * Prepare a single webhook output for response. + * Get data for this object in the format of this endpoint's schema. * - * @param int $id Webhook ID. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response + * @param \WP_Comment $object Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array Array of data in the correct format. */ - public function prepare_item_for_response( $id, $request ) { - $webhook = wc_get_webhook( $id ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - $data = array( - 'id' => $webhook->get_id(), - 'name' => $webhook->get_name(), - 'status' => $webhook->get_status(), - 'topic' => $webhook->get_topic(), - 'resource' => $webhook->get_resource(), - 'event' => $webhook->get_event(), - 'hooks' => $webhook->get_hooks(), - 'delivery_url' => $webhook->get_delivery_url(), - 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $webhook->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), + protected function get_data_for_response( $object, $request ) { + return array( + 'id' => $object->get_id(), + 'name' => $object->get_name(), + 'status' => $object->get_status(), + 'topic' => $object->get_topic(), + 'resource' => $object->get_resource(), + 'event' => $object->get_event(), + 'hooks' => $object->get_hooks(), + 'delivery_url' => $object->get_delivery_url(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), ); - - $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( $webhook, $request ) ); - - /** - * Filter webhook object returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param WC_Webhook $webhook Webhook object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); } /** @@ -694,4 +689,14 @@ class Webhooks extends AbstractController { return $params; } + + /** + * Return suffix for item action hooks. + * + * @param mixed $item Object used to create response. + * @return string + */ + protected function get_hook_suffix( $item ) { + return $this->post_type; + } } From 1f6455807d2690cba32c3181c474b99a16eea2e6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 18 Jun 2019 13:00:04 +0100 Subject: [PATCH 157/440] Improve hook suffix --- src/Controllers/Version4/AbstractController.php | 17 ++++------------- .../Version4/AbstractObjectsController.php | 3 +-- .../Version4/AbstractTermsContoller.php | 3 +-- src/Controllers/Version4/CustomerDownloads.php | 9 --------- src/Controllers/Version4/Customers.php | 9 --------- src/Controllers/Version4/Data.php | 9 --------- src/Controllers/Version4/Data/Continents.php | 11 +---------- src/Controllers/Version4/Data/Countries.php | 11 +---------- src/Controllers/Version4/Data/Currencies.php | 11 +---------- src/Controllers/Version4/Data/DownloadIPs.php | 11 +---------- src/Controllers/Version4/OrderNotes.php | 9 --------- src/Controllers/Version4/PaymentGateways.php | 9 --------- src/Controllers/Version4/ProductAttributes.php | 9 --------- src/Controllers/Version4/ProductCategories.php | 9 --------- src/Controllers/Version4/ProductReviews.php | 9 --------- .../Version4/ProductShippingClasses.php | 9 --------- src/Controllers/Version4/ProductTags.php | 9 --------- src/Controllers/Version4/ProductVariations.php | 9 --------- src/Controllers/Version4/Products.php | 9 --------- src/Controllers/Version4/Settings.php | 9 --------- src/Controllers/Version4/SettingsOptions.php | 9 --------- src/Controllers/Version4/ShippingMethods.php | 9 --------- .../Version4/ShippingZoneLocations.php | 9 --------- .../Version4/ShippingZoneMethods.php | 9 --------- src/Controllers/Version4/ShippingZones.php | 9 --------- src/Controllers/Version4/SystemStatus.php | 9 --------- src/Controllers/Version4/SystemStatusTools.php | 9 --------- src/Controllers/Version4/TaxClasses.php | 9 --------- src/Controllers/Version4/Taxes.php | 9 --------- src/Controllers/Version4/Webhooks.php | 3 +-- 30 files changed, 11 insertions(+), 257 deletions(-) diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index 9c409257981..ff2be035ec4 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -49,15 +49,6 @@ abstract class AbstractController extends WP_REST_Controller { */ protected $resource_type = ''; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = ''; - /** * Register route for items requests. * @@ -294,17 +285,17 @@ abstract class AbstractController extends WP_REST_Controller { * @param mixed $item Object used to create response. * @param \WP_REST_Request $request Request object. */ - return apply_filters( 'woocommerce_rest_prepare_' . $this->get_hook_suffix( $item ), $response, $item, $request ); + return apply_filters( 'woocommerce_rest_prepare_' . $this->get_hook_suffix(), $response, $item, $request ); } /** * Return suffix for item action hooks. * - * @param mixed $item Object used to create response. * @return string */ - protected function get_hook_suffix( $item ) { - return $this->singular; + protected function get_hook_suffix() { + $schema = $this->get_item_schema(); + return $schema['title']; } /** diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index a4827d4b663..c5a723ba5b8 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -827,10 +827,9 @@ abstract class AbstractObjectsController extends AbstractController { /** * Return suffix for item action hooks. * - * @param mixed $item Object used to create response. * @return string */ - protected function get_hook_suffix( $item ) { + protected function get_hook_suffix() { return $this->post_type . '_object'; } } diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index e5916460e6e..42169be5682 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -753,10 +753,9 @@ abstract class AbstractTermsContoller extends AbstractController { /** * Return suffix for item action hooks. * - * @param mixed $item Object used to create response. * @return string */ - protected function get_hook_suffix( $item ) { + protected function get_hook_suffix() { return $this->taxonomy; } } diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index dfe04d6baa5..342d5fdbba7 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -32,15 +32,6 @@ class CustomerDownloads extends AbstractController { */ protected $resource_type = 'customers'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'customer_download'; - /** * Register the routes for customers. */ diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 59ac1250ac7..8d6796053fa 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -34,15 +34,6 @@ class Customers extends AbstractController { */ protected $resource_type = 'customers'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'customer'; - /** * Register the routes for customers. */ diff --git a/src/Controllers/Version4/Data.php b/src/Controllers/Version4/Data.php index 3e7965e376b..d34bf73736c 100644 --- a/src/Controllers/Version4/Data.php +++ b/src/Controllers/Version4/Data.php @@ -30,15 +30,6 @@ class Data extends AbstractController { */ protected $resource_type = 'settings'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'data'; - /** * Register routes. * diff --git a/src/Controllers/Version4/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php index 23212b3f160..3341425033e 100644 --- a/src/Controllers/Version4/Data/Continents.php +++ b/src/Controllers/Version4/Data/Continents.php @@ -25,15 +25,6 @@ class Continents extends DataController { */ protected $rest_base = 'data/continents'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'continent'; - /** * Register routes. * @@ -234,7 +225,7 @@ class Continents extends DataController { public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_continents', + 'title' => 'continent', 'type' => 'object', 'properties' => array( 'code' => array( diff --git a/src/Controllers/Version4/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php index 197ccda374a..13136317950 100644 --- a/src/Controllers/Version4/Data/Countries.php +++ b/src/Controllers/Version4/Data/Countries.php @@ -25,15 +25,6 @@ class Countries extends DataController { */ protected $rest_base = 'data/countries'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'country'; - /** * Register routes. * @@ -183,7 +174,7 @@ class Countries extends DataController { public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_countries', + 'title' => 'country', 'type' => 'object', 'properties' => array( 'code' => array( diff --git a/src/Controllers/Version4/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php index c5bbdac098d..de52a531b24 100644 --- a/src/Controllers/Version4/Data/Currencies.php +++ b/src/Controllers/Version4/Data/Currencies.php @@ -25,15 +25,6 @@ class Currencies extends DataController { */ protected $rest_base = 'data/currencies'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'currency'; - /** * Register routes. */ @@ -189,7 +180,7 @@ class Currencies extends DataController { public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_currencies', + 'title' => 'currency', 'type' => 'object', 'properties' => array( 'code' => array( diff --git a/src/Controllers/Version4/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php index 02b4d8c84c8..47d4cbdc97d 100644 --- a/src/Controllers/Version4/Data/DownloadIPs.php +++ b/src/Controllers/Version4/Data/DownloadIPs.php @@ -25,15 +25,6 @@ class DownloadIPs extends DataController { */ protected $rest_base = 'data/download-ips'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'download_ip'; - /** * Register routes. * @@ -141,7 +132,7 @@ class DownloadIPs extends DataController { public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_download_ips', + 'title' => 'download_ip', 'type' => 'object', 'properties' => array( 'user_ip_address' => array( diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index f6791a6e340..01a96b214b4 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -32,15 +32,6 @@ class OrderNotes extends AbstractController { */ protected $post_type = 'shop_order'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'order_note'; - /** * Register the routes for order notes. */ diff --git a/src/Controllers/Version4/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php index 176dc43a035..8c1df3c60b4 100644 --- a/src/Controllers/Version4/PaymentGateways.php +++ b/src/Controllers/Version4/PaymentGateways.php @@ -33,15 +33,6 @@ class PaymentGateways extends AbstractController { */ protected $resource_type = 'payment_gateways'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'payment_gateway'; - /** * Register the route for /payment_gateways and /payment_gateways/ */ diff --git a/src/Controllers/Version4/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php index b13ac14dfad..8ddb0af6317 100644 --- a/src/Controllers/Version4/ProductAttributes.php +++ b/src/Controllers/Version4/ProductAttributes.php @@ -37,15 +37,6 @@ class ProductAttributes extends AbstractController { */ protected $attribute = ''; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'product_attribute'; - /** * Register the routes for product attributes. */ diff --git a/src/Controllers/Version4/ProductCategories.php b/src/Controllers/Version4/ProductCategories.php index b263423fa8f..ba8e27a02cc 100644 --- a/src/Controllers/Version4/ProductCategories.php +++ b/src/Controllers/Version4/ProductCategories.php @@ -30,15 +30,6 @@ class ProductCategories extends AbstractTermsContoller { */ protected $taxonomy = 'product_cat'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'product_cat'; - /** * Get data for this object in the format of this endpoint's schema. * diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index 263e9818f0e..071c9b240e5 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -33,15 +33,6 @@ class ProductReviews extends AbstractController { */ protected $resource_type = 'product_reviews'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'product_reviews'; - /** * Register the routes for product reviews. */ diff --git a/src/Controllers/Version4/ProductShippingClasses.php b/src/Controllers/Version4/ProductShippingClasses.php index e2a693df692..4c55791ed50 100644 --- a/src/Controllers/Version4/ProductShippingClasses.php +++ b/src/Controllers/Version4/ProductShippingClasses.php @@ -30,15 +30,6 @@ class ProductShippingClasses extends AbstractTermsContoller { */ protected $taxonomy = 'product_shipping_class'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'product_shipping_class'; - /** * Get data for this object in the format of this endpoint's schema. * diff --git a/src/Controllers/Version4/ProductTags.php b/src/Controllers/Version4/ProductTags.php index ba70253a7a4..5c3b5f01826 100644 --- a/src/Controllers/Version4/ProductTags.php +++ b/src/Controllers/Version4/ProductTags.php @@ -30,15 +30,6 @@ class ProductTags extends AbstractTermsContoller { */ protected $taxonomy = 'product_tag'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'product_tag'; - /** * Get data for this object in the format of this endpoint's schema. * diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index da66cdc8878..b791cbda69b 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -34,15 +34,6 @@ class ProductVariations extends Products { */ protected $post_type = 'product_variation'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'product_variation'; - /** * Register the routes for products. */ diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 2308f2c0e7d..cfe86fd63cd 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -41,15 +41,6 @@ class Products extends AbstractObjectsController { */ protected $hierarchical = true; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'product'; - /** * Get the Product's schema, conforming to JSON Schema. * diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index 8a1cefd176f..c32e924c526 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -30,15 +30,6 @@ class Settings extends AbstractController { */ protected $resource_type = 'settings'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'setting'; - /** * Register routes. * diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index 7389c316257..94d57ccce94 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -33,15 +33,6 @@ class SettingsOptions extends AbstractController { */ protected $rest_base = 'settings/(?P[\w-]+)'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'setting_option'; - /** * Register routes. * diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php index cb2f27b3af0..9176f01bbab 100644 --- a/src/Controllers/Version4/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -30,15 +30,6 @@ class ShippingMethods extends AbstractController { */ protected $resource_type = 'shipping_methods'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'shipping_method'; - /** * Register the route for /shipping_methods and /shipping_methods/ */ diff --git a/src/Controllers/Version4/ShippingZoneLocations.php b/src/Controllers/Version4/ShippingZoneLocations.php index 201712f52b4..f9c2a96d09c 100644 --- a/src/Controllers/Version4/ShippingZoneLocations.php +++ b/src/Controllers/Version4/ShippingZoneLocations.php @@ -16,15 +16,6 @@ defined( 'ABSPATH' ) || exit; */ class ShippingZoneLocations extends AbstractShippingZonesController { - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'shipping_zone_location'; - /** * Register the routes for Shipping Zone Locations. */ diff --git a/src/Controllers/Version4/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php index b4e4211ed4b..19ab78a9f47 100644 --- a/src/Controllers/Version4/ShippingZoneMethods.php +++ b/src/Controllers/Version4/ShippingZoneMethods.php @@ -19,15 +19,6 @@ use \WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; class ShippingZoneMethods extends AbstractShippingZonesController { use SettingsTrait; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'shipping_zone_method'; - /** * Register the routes for Shipping Zone Methods. */ diff --git a/src/Controllers/Version4/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php index d26886dfb78..3869551bb4a 100644 --- a/src/Controllers/Version4/ShippingZones.php +++ b/src/Controllers/Version4/ShippingZones.php @@ -16,15 +16,6 @@ defined( 'ABSPATH' ) || exit; */ class ShippingZones extends AbstractShippingZonesController { - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'shipping_zone'; - /** * Register the routes for Shipping Zones. */ diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index d22521d1911..07512d8e949 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -30,15 +30,6 @@ class SystemStatus extends AbstractController { */ protected $resource_type = 'system_status'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'system_status'; - /** * Register the route for /system_status */ diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php index a82ce813dea..4c7a932de37 100644 --- a/src/Controllers/Version4/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -30,15 +30,6 @@ class SystemStatusTools extends AbstractController { */ protected $resource_type = 'system_status'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'system_status_tool'; - /** * Register the routes for /system_status/tools/*. */ diff --git a/src/Controllers/Version4/TaxClasses.php b/src/Controllers/Version4/TaxClasses.php index c6ff2e99bc4..460bfc6db79 100644 --- a/src/Controllers/Version4/TaxClasses.php +++ b/src/Controllers/Version4/TaxClasses.php @@ -30,15 +30,6 @@ class TaxClasses extends AbstractController { */ protected $resource_type = 'settings'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'tax_class'; - /** * Register the routes for tax classes. */ diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php index bcb588cbae0..4cddea1b2a4 100644 --- a/src/Controllers/Version4/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -30,15 +30,6 @@ class Taxes extends AbstractController { */ protected $resource_type = 'settings'; - /** - * Singular name for resource type. - * - * Used in filter/action names for single resources. - * - * @var string - */ - protected $singular = 'tax'; - /** * Register the routes for taxes. */ diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index 667f5d09693..10f8a5ebac5 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -693,10 +693,9 @@ class Webhooks extends AbstractController { /** * Return suffix for item action hooks. * - * @param mixed $item Object used to create response. * @return string */ - protected function get_hook_suffix( $item ) { + protected function get_hook_suffix() { return $this->post_type; } } From 71a32c96b64b0f9a901c97c7613f7eb3789a6065 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 18 Jun 2019 16:06:04 +0100 Subject: [PATCH 158/440] Tidy up permission checks --- .../Version4/AbstractController.php | 58 ++-- .../Version4/AbstractObjectsController.php | 148 ++++------ .../Version4/AbstractTermsContoller.php | 84 ------ .../Version4/CustomerDownloads.php | 2 +- src/Controllers/Version4/Customers.php | 64 +++++ src/Controllers/Version4/OrderNotes.php | 33 +-- src/Controllers/Version4/ProductReviews.php | 53 +++- .../Version4/ProductVariations.php | 62 ++++- src/Controllers/Version4/Products.php | 2 +- .../Version4/Utilities/Permissions.php | 260 +++++++++++++----- unit-tests/Tests/Version4/Customers.php | 2 +- 11 files changed, 467 insertions(+), 301 deletions(-) diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index ff2be035ec4..eedc9116f41 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -159,6 +159,8 @@ abstract class AbstractController extends WP_REST_Controller { return $schema; } + + /** * Check whether a given request has permission to read webhooks. * @@ -166,10 +168,13 @@ abstract class AbstractController extends WP_REST_Controller { * @return \WP_Error|boolean */ public function get_items_permissions_check( $request ) { - if ( ! Permissions::check_resource( $this->resource_type, 'read' ) ) { + $permission = Permissions::user_can_list( $this->get_item_title() ); + + if ( false === $permission ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; + + return $permission; } /** @@ -180,10 +185,13 @@ abstract class AbstractController extends WP_REST_Controller { * @return bool|\WP_Error */ public function create_item_permissions_check( $request ) { - if ( ! Permissions::check_resource( $this->resource_type, 'create' ) ) { + $permission = Permissions::user_can_create( $this->get_item_title() ); + + if ( false === $permission ) { return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; + + return $permission; } /** @@ -193,12 +201,14 @@ abstract class AbstractController extends WP_REST_Controller { * @return \WP_Error|boolean */ public function get_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); + $id = $request->get_param( 'id' ); + $permission = Permissions::user_can_read( $this->get_item_title(), $id ); - if ( 0 !== $id && ! Permissions::check_resource( $this->resource_type, 'read', $id ) ) { + if ( false === $permission ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; + + return $permission; } /** @@ -209,12 +219,14 @@ abstract class AbstractController extends WP_REST_Controller { * @return bool|\WP_Error */ public function update_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); + $id = $request->get_param( 'id' ); + $permission = Permissions::user_can_edit( $this->get_item_title(), $id ); - if ( 0 !== $id && ! Permissions::check_resource( $this->resource_type, 'edit', $id ) ) { + if ( false === $permission ) { return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; + + return $permission; } /** @@ -225,12 +237,14 @@ abstract class AbstractController extends WP_REST_Controller { * @return bool|\WP_Error */ public function delete_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); + $id = $request->get_param( 'id' ); + $permission = Permissions::user_can_delete( $this->get_item_title(), $id ); - if ( 0 !== $id && ! Permissions::check_resource( $this->resource_type, 'delete', $id ) ) { + if ( false === $permission ) { return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; + + return $permission; } /** @@ -241,10 +255,13 @@ abstract class AbstractController extends WP_REST_Controller { * @return bool|\WP_Error */ public function batch_items_permissions_check( $request ) { - if ( ! Permissions::check_resource( $this->resource_type, 'batch' ) ) { + $permission = Permissions::user_can_batch( $this->get_item_title() ); + + if ( false === $permission ) { return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; + + return $permission; } /** @@ -293,11 +310,20 @@ abstract class AbstractController extends WP_REST_Controller { * * @return string */ - protected function get_hook_suffix() { + protected function get_item_title() { $schema = $this->get_item_schema(); return $schema['title']; } + /** + * Return suffix for item action hooks. + * + * @return string + */ + protected function get_hook_suffix() { + return $this->get_item_title(); + } + /** * Get data for this object in the format of this endpoint's schema. * diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index c5a723ba5b8..fb0c1ec10b2 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -57,97 +57,6 @@ abstract class AbstractObjectsController extends AbstractController { $this->register_batch_route(); } - /** - * Check if a given request has access to read items. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! Permissions::check_post_object( $this->post_type, 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - - if ( 0 !== $id && ! Permissions::check_post_object( $this->post_type, 'read', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! Permissions::check_post_object( $this->post_type, 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - - if ( 0 !== $id && ! Permissions::check_post_object( $this->post_type, 'edit', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - - if ( 0 !== $id && ! Permissions::check_post_object( $this->post_type, 'delete', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return boolean|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! Permissions::check_post_object( $this->post_type, 'batch' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get a single item. * @@ -379,7 +288,7 @@ abstract class AbstractObjectsController extends AbstractController { $objects = array(); foreach ( $query_results['objects'] as $object ) { - if ( ! Permissions::check_post_object( $this->post_type, 'read', $object->get_id() ) ) { + if ( ! Permissions::user_can_read( $this->post_type, $object->get_id() ) ) { continue; } @@ -444,7 +353,7 @@ abstract class AbstractObjectsController extends AbstractController { $supports_trash = $this->supports_trash( $object ); - if ( ! Permissions::check_post_object( $this->post_type, 'delete', $object->get_id() ) ) { + if ( ! Permissions::user_can_delete( $this->post_type, $object->get_id() ) ) { /* translators: %s: post type */ return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } @@ -832,4 +741,57 @@ abstract class AbstractObjectsController extends AbstractController { protected function get_hook_suffix() { return $this->post_type . '_object'; } + + /** + * Check if a given request has access to read a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + $object = $this->get_object( $id ); + + if ( ! $object || 0 === $object->get_id() ) { + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return parent::get_item_permissions_check( $request ); + } + + /** + * Check if a given request has access update a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * + * @return bool|\WP_Error + */ + public function update_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + $object = $this->get_object( $id ); + + if ( ! $object || 0 === $object->get_id() ) { + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return parent::update_item_permissions_check( $request ); + } + + /** + * Check if a given request has access delete a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * + * @return bool|\WP_Error + */ + public function delete_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + $object = $this->get_object( $id ); + + if ( ! $object || 0 === $object->get_id() ) { + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return parent::delete_item_permissions_check( $request ); + } } diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index 42169be5682..ffcf6870ba4 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -122,90 +122,6 @@ abstract class AbstractTermsContoller extends AbstractController { $this->register_batch_route(); } - /** - * Check if a given request has access to read the terms. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! Permissions::check_taxonomy( $this->taxonomy, 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to create a term. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! Permissions::check_taxonomy( $this->taxonomy, 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to read a term. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - - if ( ! Permissions::check_taxonomy( $this->taxonomy, 'read', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you are not allowed to view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to update a term. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - - if ( ! Permissions::check_taxonomy( $this->taxonomy, 'edit', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to delete a term. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - - if ( ! Permissions::check_taxonomy( $this->taxonomy, 'delete', $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * @return boolean|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! Permissions::check_taxonomy( $this->taxonomy, 'batch' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - /** * Get terms associated with a taxonomy. * diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index 342d5fdbba7..18a7cbea7c5 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -52,7 +52,7 @@ class CustomerDownloads extends AbstractController { return new \WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } - if ( ! Permissions::user_can( $this->resource_type, 'read', $customer->ID ) ) { + if ( ! Permissions::user_can_read( $this->resource_type, $customer->ID ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 8d6796053fa..84c84bae043 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -740,4 +740,68 @@ class Customers extends AbstractController { ); return $params; } + + /** + * Check if a given ID is valid. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + protected function check_valid_customer_id( $request ) { + $id = $request->get_param( 'id' ); + $user = get_userdata( $id ); + + if ( false === $user ) { + return new \WP_Error( 'woocommerce_rest_customer_invalid_id', __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return true; + } + + /** + * Check if a given request has access to read a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $check_valid = $this->check_valid_customer_id( $request ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::get_item_permissions_check( $request ); + } + + /** + * Check if a given request has access to delete an item. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $check_valid = $this->check_valid_customer_id( $request ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::delete_item_permissions_check( $request ); + } + + /** + * Check if a given request has access to update an item. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $check_valid = $this->check_valid_customer_id( $request ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::update_item_permissions_check( $request ); + } } diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index 01a96b214b4..551ee43c02b 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -112,35 +112,6 @@ class OrderNotes extends AbstractController { ); } - /** - * Check whether a given request has permission to read order notes. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! Permissions::check_post_object( $this->post_type, 'read' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create order notes. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! Permissions::check_post_object( $this->post_type, 'create' ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Check if a given request has access to read a order note. * @@ -150,7 +121,7 @@ class OrderNotes extends AbstractController { public function get_item_permissions_check( $request ) { $order = wc_get_order( (int) $request['order_id'] ); - if ( $order && ! Permissions::check_post_object( $this->post_type, 'read', $order->get_id() ) ) { + if ( $order && ! Permissions::user_can_read( $this->post_type, $order->get_id() ) ) { return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } @@ -167,7 +138,7 @@ class OrderNotes extends AbstractController { public function delete_item_permissions_check( $request ) { $order = wc_get_order( (int) $request['order_id'] ); - if ( $order && ! Permissions::check_post_object( $this->post_type, 'delete', $order->get_id() ) ) { + if ( $order && ! Permissions::user_can_delete( $this->post_type, $order->get_id() ) ) { return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index 071c9b240e5..35c1d5b27ba 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -219,7 +219,7 @@ class ProductReviews extends AbstractController { $reviews = array(); foreach ( $query_result as $review ) { - if ( ! Permissions::check_resource( $this->resource_type, 'read', $review->comment_ID ) ) { + if ( ! Permissions::user_can_read( 'product_review', $review->comment_ID ) ) { continue; } @@ -983,4 +983,55 @@ class ProductReviews extends AbstractController { return $changed; } + + /** + * Check if a given request has access to read a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + $check_valid = $this->get_review( $id ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::get_item_permissions_check( $request ); + } + + /** + * Check if a given request has access to delete an item. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + $check_valid = $this->get_review( $id ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::delete_item_permissions_check( $request ); + } + + /** + * Check if a given request has access to update an item. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $id = $request->get_param( 'id' ); + $check_valid = $this->get_review( $id ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::update_item_permissions_check( $request ); + } } diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index b791cbda69b..8243fdc973d 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -561,26 +561,74 @@ class ProductVariations extends Products { } /** - * Check if a given request has access to update an item. + * Check if a given ID is valid. * * @param \WP_REST_Request $request Full details about the request. * @return \WP_Error|boolean */ - public function update_item_permissions_check( $request ) { - $object = $this->get_object( (int) $request['id'] ); + protected function check_valid_variation_id( $request ) { + $id = $request->get_param( 'id' ); + $object = $this->get_object( $id ); - if ( $object && 0 !== $object->get_id() && ! Permissions::check_post_object( $this->post_type, 'edit', $object->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + if ( ! $object || 0 === $object->get_id() ) { + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } // Check if variation belongs to the correct parent product. if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } - return true; } + /** + * Check if a given request has access to read a webhook. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $check_valid = $this->check_valid_variation_id( $request ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::get_item_permissions_check( $request ); + } + + /** + * Check if a given request has access to delete an item. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $check_valid = $this->check_valid_variation_id( $request ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::delete_item_permissions_check( $request ); + } + + /** + * Check if a given request has access to update an item. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $check_valid = $this->check_valid_variation_id( $request ); + + if ( is_wp_error( $check_valid ) ) { + return $check_valid; + } + + return parent::update_item_permissions_check( $request ); + } + /** * Get data for this object in the format of this endpoint's schema. * @@ -721,7 +769,7 @@ class ProductVariations extends Products { */ $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - if ( ! Permissions::check_post_object( $this->post_type, 'delete', $object->get_id() ) ) { + if ( ! Permissions::user_can_delete( $this->post_type, $object->get_id() ) ) { return new \WP_Error( /* translators: %s: post type */ "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index cfe86fd63cd..c6e20340e88 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -1142,7 +1142,7 @@ class Products extends AbstractObjectsController { */ $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - if ( ! Permissions::check_post_object( $this->post_type, 'delete', $object->get_id() ) ) { + if ( ! Permissions::user_can_delete( $this->post_type, $object->get_id() ) ) { return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", /* translators: %s: post type */ diff --git a/src/Controllers/Version4/Utilities/Permissions.php b/src/Controllers/Version4/Utilities/Permissions.php index c70c93573d0..eaa19400b78 100644 --- a/src/Controllers/Version4/Utilities/Permissions.php +++ b/src/Controllers/Version4/Utilities/Permissions.php @@ -17,94 +17,222 @@ defined( 'ABSPATH' ) || exit; class Permissions { /** - * Resource permissions required. + * Items not defined here will default to manage_woocommerce permission. * * @var array */ - protected static $resource_permissions = [ - 'settings' => 'manage_woocommerce', - 'system_status' => 'manage_woocommerce', - 'attributes' => 'manage_product_terms', - 'shipping_methods' => 'manage_woocommerce', - 'payment_gateways' => 'manage_woocommerce', - 'webhooks' => 'manage_woocommerce', - 'product_reviews' => 'moderate_comments', - 'customers' => [ + protected static $capabilities = array( + 'shop_coupon' => [ + 'read' => 'read_shop_coupon', + 'list' => 'read_private_shop_coupons', + 'create' => 'publish_shop_coupons', + 'edit' => 'edit_shop_coupon', + 'delete' => 'delete_shop_coupon', + 'batch' => 'edit_others_shop_coupons', + ], + 'customer_download' => [ + 'read' => 'read_shop_order', + 'list' => 'read_private_shop_orders', + 'create' => 'publish_shop_orders', + 'edit' => 'edit_shop_order', + 'delete' => 'delete_shop_order', + 'batch' => 'edit_others_shop_orders', + ], + 'customer' => [ 'read' => 'list_users', - 'create' => 'promote_users', // Check if current user can create users, shop managers are not allowed to create users. + 'list' => 'list_users', + 'create' => 'promote_users', 'edit' => 'edit_users', 'delete' => 'delete_users', 'batch' => 'promote_users', ], - ]; + 'shop_order' => [ + 'read' => 'read_shop_order', + 'list' => 'read_private_shop_orders', + 'create' => 'publish_shop_orders', + 'edit' => 'edit_shop_order', + 'delete' => 'delete_shop_order', + 'batch' => 'edit_others_shop_orders', + ], + 'product_attribute' => 'edit_product_terms', + 'product_attribute_term' => [ + 'read' => 'manage_product_terms', + 'list' => 'manage_product_terms', + 'create' => 'edit_product_terms', + 'edit' => 'edit_product_terms', + 'delete' => 'delete_product_terms', + 'batch' => 'edit_product_terms', + ], + 'product_cat' => [ + 'read' => 'manage_product_terms', + 'list' => 'manage_product_terms', + 'create' => 'edit_product_terms', + 'edit' => 'edit_product_terms', + 'delete' => 'delete_product_terms', + 'batch' => 'edit_product_terms', + ], + 'product_review' => 'moderate_comments', + 'product' => [ + 'read' => 'read_product', + 'list' => 'read_private_products', + 'create' => 'publish_products', + 'edit' => 'edit_product', + 'delete' => 'delete_product', + 'batch' => 'edit_others_products', + ], + 'product_shipping_class' => [ + 'read' => 'manage_product_terms', + 'list' => 'manage_product_terms', + 'create' => 'edit_product_terms', + 'edit' => 'edit_product_terms', + 'delete' => 'delete_product_terms', + 'batch' => 'edit_product_terms', + ], + 'product_tag' => [ + 'read' => 'manage_product_terms', + 'list' => 'manage_product_terms', + 'create' => 'edit_product_terms', + 'edit' => 'edit_product_terms', + 'delete' => 'delete_product_terms', + 'batch' => 'edit_product_terms', + ], + 'product_variation' => [ + 'read' => 'read_product', + 'list' => 'read_private_products', + 'create' => 'publish_products', + 'edit' => 'edit_product', + 'delete' => 'delete_product', + 'batch' => 'edit_others_products', + ], + ); /** - * See if the current user can do something to a resource. + * Get capabilities required for a resource for a given context. * - * @param string $resource Type of permission required. - * @param string $context Context. One of read, edit, create, update, delete, batch. - * @param int $resource_id Optional resource ID. + * @param string $type Item/resource type. Comes from schema title. + * @param string $context Read, edit, delete, batch, create. + * @return array List of caps to check. Defaults to manage_woocommerce. + */ + protected static function get_capabilities_for_type( $type, $context = 'read' ) { + if ( isset( self::$capabilities[ $type ][ $context ] ) ) { + $caps = self::$capabilities[ $type ][ $context ]; + } elseif ( isset( self::$capabilities[ $type ] ) ) { + $caps = self::$capabilities[ $type ]; + } else { + $caps = 'manage_woocommerce'; + } + return is_array( $caps ) ? $caps : array( $caps ); + } + + /** + * Check if user has a list of caps. + * + * @param array $capabilities List of caps to check. + * @param int $object_id Object ID to check. Optional. * @return boolean */ - public static function check_resource( $resource, $context = 'read', $resource_id = 0 ) { - if ( ! isset( self::$resource_permissions[ $resource ] ) ) { + protected static function has_required_capabilities( $capabilities, $object_id = null ) { + $permission = true; + + foreach ( $capabilities as $capability ) { + if ( ! current_user_can( $capability, $object_id ) ) { + $permission = false; + } + } + + return $permission; + } + + /** + * Check if user can list a collection of resources. + * + * @param string $type Item/resource type. Comes from schema title. + * @return bool True on success. + */ + public static function user_can_list( $type ) { + $capabilities = self::get_capabilities_for_type( $type, 'list' ); + $permission = self::has_required_capabilities( $capabilities ); + + return apply_filters( 'woocommerce_rest_user_can_list', $permission, $type ); + } + + /** + * Check if user can read a resource. + * + * @param string $type Item/resource type. Comes from schema title. + * @param int $object_id Resource ID. 0 to check access to read all. + * @return bool True on success. + */ + public static function user_can_read( $type, $object_id = 0 ) { + if ( 0 === $object_id ) { return false; } - $permissions = self::$resource_permissions[ $resource ]; - $capability = is_array( $permissions ) ? $permissions[ $context ] : $permissions; - $permission = current_user_can( $capability ); - return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $resource_id, $resource ); + $capabilities = self::get_capabilities_for_type( $type, 'read' ); + $permission = self::has_required_capabilities( $capabilities, $object_id ); + + return apply_filters( 'woocommerce_rest_user_can_read', $permission, $type, $object_id ); } /** - * See if the current user can do something to a resource. + * Check if user can read a resource. * - * @param string $taxonomy Taxonomy name. - * @param string $context Context. One of read, edit, create, update, delete, batch. - * @param int $object_id Optional object ID. - * @return boolean + * @param string $type Item/resource type. Comes from schema title. + * @param int $object_id Resource ID. + * @return bool True on success. */ - public static function check_taxonomy( $taxonomy, $context = 'read', $object_id = 0 ) { - $contexts = array( - 'read' => 'manage_terms', - 'create' => 'edit_terms', - 'edit' => 'edit_terms', - 'delete' => 'delete_terms', - 'batch' => 'edit_terms', - ); - $cap = $contexts[ $context ]; - $taxonomy_object = get_taxonomy( $taxonomy ); - $permission = current_user_can( $taxonomy_object->cap->$cap, $object_id ); - - return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, $taxonomy ); - } - - /** - * Check permissions of posts on REST API. - * - * @param string $post_type Post type. - * @param string $context Request context. - * @param int $object_id Post ID. - * @return bool - */ - public static function check_post_object( $post_type, $context = 'read', $object_id = 0 ) { - $contexts = array( - 'read' => 'read_private_posts', - 'create' => 'publish_posts', - 'edit' => 'edit_post', - 'delete' => 'delete_post', - 'batch' => 'edit_others_posts', - ); - - if ( 'revision' === $post_type ) { - $permission = false; - } else { - $cap = $contexts[ $context ]; - $post_type_object = get_post_type_object( $post_type ); - $permission = current_user_can( $post_type_object->cap->$cap, $object_id ); + public static function user_can_edit( $type, $object_id ) { + if ( 0 === $object_id ) { + return false; } - return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, $post_type ); + $capabilities = self::get_capabilities_for_type( $type, 'edit' ); + $permission = self::has_required_capabilities( $capabilities, $object_id ); + + return apply_filters( 'woocommerce_rest_user_can_edit', $permission, $type, $object_id ); + } + + /** + * Check if user can create a resource. + * + * @param string $type Item/resource type. Comes from schema title. + * @return bool True on success. + */ + public static function user_can_create( $type ) { + $capabilities = self::get_capabilities_for_type( $type, 'create' ); + $permission = self::has_required_capabilities( $capabilities ); + + return apply_filters( 'woocommerce_rest_user_can_create', $permission, $type ); + } + + /** + * Check if user can delete a resource. + * + * @param string $type Item/resource type. Comes from schema title. + * @param int $object_id Resource ID. + * @return bool True on success. + */ + public static function user_can_delete( $type, $object_id ) { + if ( 0 === $object_id ) { + return false; + } + + $capabilities = self::get_capabilities_for_type( $type, 'delete' ); + $permission = self::has_required_capabilities( $capabilities, $object_id ); + + return apply_filters( 'woocommerce_rest_user_can_delete', $permission, $type, $object_id ); + } + + /** + * Check if user can batch update a resource. + * + * @param string $type Item/resource type. Comes from schema title. + * @return bool True on success. + */ + public static function user_can_batch( $type ) { + $capabilities = self::get_capabilities_for_type( $type, 'batch' ); + $permission = self::has_required_capabilities( $capabilities ); + + return apply_filters( 'woocommerce_rest_user_can_batch', $permission, $type ); } } diff --git a/unit-tests/Tests/Version4/Customers.php b/unit-tests/Tests/Version4/Customers.php index 0cb812dfc7b..842039d8ecf 100644 --- a/unit-tests/Tests/Version4/Customers.php +++ b/unit-tests/Tests/Version4/Customers.php @@ -533,7 +533,7 @@ class Customers extends WC_REST_Unit_Test_Case { $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/0' ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); + $this->assertEquals( 404, $response->get_status() ); } /** From bd3828e72791c8eb98034b3daff418e6f34e0a8c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 18 Jun 2019 16:30:38 +0100 Subject: [PATCH 159/440] wrong comments --- src/Controllers/Version4/Coupons.php | 2 +- src/Controllers/Version4/CustomerDownloads.php | 2 +- src/Controllers/Version4/Customers.php | 2 +- src/Controllers/Version4/Orders.php | 2 +- src/Controllers/Version4/ShippingZones.php | 2 +- src/Controllers/Version4/Webhooks.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index c158c81faa6..a0af8e104b8 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -44,7 +44,7 @@ class Coupons extends AbstractObjectsController { /** * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Comment $object Object to prepare. + * @param \WC_Coupon $object Object to prepare. * @param \WP_REST_Request $request Request object. * @return array Array of data in the correct format. */ diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index 18a7cbea7c5..49716832190 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -81,7 +81,7 @@ class CustomerDownloads extends AbstractController { /** * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Comment $object Object to prepare. + * @param object $object Object to prepare. * @param \WP_REST_Request $request Request object. * @return array Array of data in the correct format. */ diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 84c84bae043..091bfd4e61f 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -389,7 +389,7 @@ class Customers extends AbstractController { /** * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Comment $object Object to prepare. + * @param \WC_Customer $object Object to prepare. * @param \WP_REST_Request $request Request object. * @return array Array of data in the correct format. */ diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index e04a3652e1a..e45b26b6df5 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -60,7 +60,7 @@ class Orders extends AbstractObjectsController { /** * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Comment $object Object to prepare. + * @param \WC_Order $object Object to prepare. * @param \WP_REST_Request $request Request object. * @return array Array of data in the correct format. */ diff --git a/src/Controllers/Version4/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php index 3869551bb4a..8590336378a 100644 --- a/src/Controllers/Version4/ShippingZones.php +++ b/src/Controllers/Version4/ShippingZones.php @@ -232,7 +232,7 @@ class ShippingZones extends AbstractShippingZonesController { /** * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Comment $object Object to prepare. + * @param object $object Object to prepare. * @param \WP_REST_Request $request Request object. * @return array Array of data in the correct format. */ diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index 10f8a5ebac5..49bb01d6c1d 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -476,7 +476,7 @@ class Webhooks extends AbstractController { /** * Get data for this object in the format of this endpoint's schema. * - * @param \WP_Comment $object Object to prepare. + * @param \WC_Webhook $object Object to prepare. * @param \WP_REST_Request $request Request object. * @return array Array of data in the correct format. */ From 3e3d2f3f8554b85a2d5fac477592800d3d8f41ec Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jun 2019 14:48:11 +0100 Subject: [PATCH 160/440] Update registration --- woocommerce-rest-api.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index cca8b5c50fe..b6c596d172b 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -28,10 +28,10 @@ $init_callback = include __DIR__ . '/init.php'; * This callback registers this version of the API with WooCommerce. */ $register_callback = function() use ( $version, $init_callback ) { - if ( ! is_callable( array( wc()->api, 'register' ) ) ) { + if ( ! class_exists( '\WooCommerce\Core\PackageManager' ) ) { return; } - wc()->api->register( $version, $init_callback, __DIR__ ); + \WooCommerce\Core\PackageManager::register( 'woocommerce-rest-api', $version, $init_callback, __DIR__ ); }; add_action( 'woocommerce_loaded', $register_callback ); From 3a6de36db709a6dceaeb55da53692729113a0bf7 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jun 2019 14:48:23 +0100 Subject: [PATCH 161/440] Update singleton class comment --- src/Utilities/SingletonTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utilities/SingletonTrait.php b/src/Utilities/SingletonTrait.php index e51b76f4b59..01ff37960c8 100644 --- a/src/Utilities/SingletonTrait.php +++ b/src/Utilities/SingletonTrait.php @@ -1,6 +1,6 @@ Date: Wed, 19 Jun 2019 15:35:05 +0100 Subject: [PATCH 162/440] Improve pagination header generation --- ...-product-attribute-terms-v1-controller.php | 3 +- .../Version4/AbstractObjectsController.php | 38 +-------- .../Version4/AbstractTermsContoller.php | 28 ++----- src/Controllers/Version4/Customers.php | 23 +----- src/Controllers/Version4/ProductReviews.php | 24 +----- src/Controllers/Version4/Taxes.php | 24 ++---- .../Version4/Utilities/Pagination.php | 81 +++++++++++++++++++ src/Controllers/Version4/Webhooks.php | 26 ++---- 8 files changed, 108 insertions(+), 139 deletions(-) create mode 100644 src/Controllers/Version4/Utilities/Pagination.php diff --git a/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php index 76d43c5cd90..6142998d003 100644 --- a/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php @@ -40,7 +40,8 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro * Register the routes for terms. */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( + register_rest_route( $this->namespace, '/' . $this->rest_base, + array( 'args' => array( 'attribute_id' => array( 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index fb0c1ec10b2..21cec24457d 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -9,7 +9,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * CRUD Object Controller. @@ -296,42 +297,11 @@ abstract class AbstractObjectsController extends AbstractController { $objects[] = $this->prepare_response_for_collection( $data ); } - $page = (int) $query_args['paged']; + $total = $query_results['total']; $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 = $this->rest_base; - $attrib_prefix = '(?P<'; - if ( strpos( $base, $attrib_prefix ) !== false ) { - $attrib_names = array(); - preg_match( '/\(\?P<[^>]+>.*\)/', $base, $attrib_names, PREG_OFFSET_CAPTURE ); - foreach ( $attrib_names as $attrib_name_match ) { - $beginning_offset = strlen( $attrib_prefix ); - $attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] ); - $attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset ); - if ( isset( $request[ $attrib_name ] ) ) { - $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); - } - } - } - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $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 ); - } + $response = Pagination::add_pagination_headers( $response, $request, $total, $max_pages ); return $response; } diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index ffcf6870ba4..f86b7886eae 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -9,7 +9,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * Terms controller class. @@ -203,31 +204,12 @@ abstract class AbstractTermsContoller extends AbstractController { $response[] = $this->prepare_response_for_collection( $data ); } - $response = rest_ensure_response( $response ); - // Store pagination values for headers then unset for count query. - $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); - - $response->header( 'X-WP-Total', (int) $total_terms ); + $per_page = (int) $prepared_args['number']; $max_pages = ceil( $total_terms / $per_page ); - $response->header( 'X-WP-TotalPages', (int) $max_pages ); - $base = str_replace( '(?P[\d]+)', $request['attribute_id'], $this->rest_base ); - $base = add_query_arg( $request->get_query_params(), rest_url( '/' . $this->namespace . '/' . $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 ); - } + $response = rest_ensure_response( $response ); + $response = Pagination::add_pagination_headers( $response, $request, $total_terms, $max_pages ); return $response; } diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index 091bfd4e61f..fc7c8af0cd5 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -14,6 +14,7 @@ defined( 'ABSPATH' ) || exit; use \WP_REST_Server; use WooCommerce\RestApi\Controllers\Version4\Requests\CustomerRequest; use WooCommerce\RestApi\Controllers\Version4\Responses\CustomerResponse; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * REST API Customers controller class. @@ -190,8 +191,6 @@ class Customers extends AbstractController { $users[] = $this->prepare_response_for_collection( $data ); } - $response = rest_ensure_response( $users ); - // Store pagination values for headers then unset for count query. $per_page = (int) $prepared_args['number']; $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); @@ -199,6 +198,7 @@ class Customers extends AbstractController { $prepared_args['fields'] = 'ID'; $total_users = $query->get_total(); + if ( $total_users < 1 ) { // Out-of-bounds, run the query again without LIMIT for total count. unset( $prepared_args['number'] ); @@ -206,24 +206,9 @@ class Customers extends AbstractController { $count_query = new \ WP_User_Query( $prepared_args ); $total_users = $count_query->get_total(); } - $response->header( 'X-WP-Total', (int) $total_users ); - $max_pages = ceil( $total_users / $per_page ); - $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 ); - } + $response = rest_ensure_response( $users ); + $response = Pagination::add_pagination_headers( $response, $request, $total_users, ceil( $total_users / $per_page ) ); return $response; } diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index 35c1d5b27ba..2b6922f330d 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -13,6 +13,7 @@ defined( 'ABSPATH' ) || exit; use WooCommerce\RestApi\Controllers\Version4\Responses\ProductReviewResponse; use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * REST API Product Reviews controller class. @@ -242,28 +243,7 @@ class ProductReviews extends AbstractController { } $response = rest_ensure_response( $reviews ); - $response->header( 'X-WP-Total', $total_reviews ); - $response->header( 'X-WP-TotalPages', $max_pages ); - - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); - - if ( $request['page'] > 1 ) { - $prev_page = $request['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 > $request['page'] ) { - $next_page = $request['page'] + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - - $response->link_header( 'next', $next_link ); - } + $response = Pagination::add_pagination_headers( $response, $request, $total_reviews, $max_pages ); return $response; } diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php index 4cddea1b2a4..2fb84276569 100644 --- a/src/Controllers/Version4/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; + /** * REST API Taxes controller class. */ @@ -175,8 +177,6 @@ class Taxes extends AbstractController { $taxes[] = $this->prepare_response_for_collection( $data ); } - $response = rest_ensure_response( $taxes ); - // Store pagination values for headers then unset for count query. $per_page = (int) $prepared_args['number']; $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); @@ -186,24 +186,10 @@ class Taxes extends AbstractController { // Calculate totals. $total_taxes = (int) $wpdb->num_rows; - $response->header( 'X-WP-Total', (int) $total_taxes ); - $max_pages = ceil( $total_taxes / $per_page ); - $response->header( 'X-WP-TotalPages', (int) $max_pages ); + $max_pages = ceil( $total_taxes / $per_page ); - $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 ); - } + $response = rest_ensure_response( $taxes ); + $response = Pagination::add_pagination_headers( $response, $request, $total_taxes, $max_pages ); return $response; } diff --git a/src/Controllers/Version4/Utilities/Pagination.php b/src/Controllers/Version4/Utilities/Pagination.php new file mode 100644 index 00000000000..71b31eb19f1 --- /dev/null +++ b/src/Controllers/Version4/Utilities/Pagination.php @@ -0,0 +1,81 @@ +header( 'X-WP-Total', $total_items ); + $response->header( 'X-WP-TotalPages', $total_pages ); + + $current_page = self::get_current_page( $request ); + $link_base = self::get_link_base( $request ); + + if ( $current_page > 1 ) { + $previous_page = $current_page - 1; + if ( $previous_page > $total_pages ) { + $previous_page = $total_pages; + } + self::add_page_link( $response, 'prev', $previous_page, $link_base ); + } + + if ( $total_pages > $current_page ) { + self::add_page_link( $response, 'next', ( $current_page + 1 ), $link_base ); + } + + return $response; + } + + /** + * Get current page. + * + * @param \WP_REST_Request $request The request object. + * @return int Get the page from the request object. + */ + protected static function get_current_page( $request ) { + return (int) $request->get_param( 'page' ); + } + + /** + * Get base for links from the request object. + * + * @param \WP_REST_Request $request The request object. + * @return string + */ + protected static function get_link_base( $request ) { + return add_query_arg( $request->get_query_params(), rest_url( $request->get_route() ) ); + } + + /** + * Add a page link. + * + * @param \WP_REST_Response $response Reference to the response object. + * @param string $name Page link name. e.g. prev. + * @param int $page Page number. + * @param string $link_base Base URL. + */ + protected static function add_page_link( &$response, $name, $page, $link_base ) { + $response->link_header( $name, add_query_arg( 'page', $page, $link_base ) ); + } +} diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index 49bb01d6c1d..58cc4374dbd 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; +use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; + /** * REST API Webhooks controller class. */ @@ -179,29 +181,11 @@ class Webhooks extends AbstractController { $webhooks[] = $this->prepare_response_for_collection( $data ); } - $response = rest_ensure_response( $webhooks ); - $per_page = (int) $prepared_args['limit']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + $total_webhooks = $results->total; $max_pages = $results->max_num_pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - - $response->header( 'X-WP-Total', $total_webhooks ); - $response->header( 'X-WP-TotalPages', $max_pages ); - - 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 ); - } + $response = rest_ensure_response( $webhooks ); + $response = Pagination::add_pagination_headers( $response, $request, $total_webhooks, $max_pages ); return $response; } From e7d232b7854edb402bf89eda8929da9675180df1 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jun 2019 15:49:46 +0100 Subject: [PATCH 163/440] config --- .scrutinizer.yml | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index f3649438a19..81419ce8e7f 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -30,6 +30,82 @@ filter: - unit-tests/ - vendor/ - classmap.php +coding_style: + php: + indentation: + general: + use_tabs: true + size: 4 + switch: + indent_case: true + spaces: + around_operators: + concatenation: true + negation: true + within: + brackets: true + grouping: true + function_call: true + function_declaration: true + if: true + for: true + while: true + switch: true + catch: true + before_left_brace: + class: true + function: true + if: true + else: true + for: true + while: true + do: true + switch: true + try: true + catch: true + finally: true + before_keywords: + else: true + while: true + catch: true + finally: true + ternary_operator: + before_condition: true + after_condition: true + before_alternative: true + after_alternative: true + in_short_version: false + other: + before_comma: false + after_comma: true + before_semicolon: false + after_semicolon: true + after_type_cast: true + braces: + classes_functions: + class: end-of-line + function: end-of-line + closure: end-of-line + if: + opening: undefined + always: true + else_on_new_line: false + for: + opening: undefined + always: true + while: + opening: undefined + always: true + do_while: + opening: undefined + always: true + while_on_new_line: false + switch: + opening: undefined + try: + opening: undefined + catch_on_new_line: false + finally_on_new_line: false build: tests: override: From fa0560f4ed828dfa68939eec66a26358fff70b5e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jun 2019 15:50:52 +0100 Subject: [PATCH 164/440] config --- .scrutinizer.yml | 50 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 81419ce8e7f..425a5847ebc 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -81,31 +81,31 @@ coding_style: before_semicolon: false after_semicolon: true after_type_cast: true - braces: - classes_functions: - class: end-of-line - function: end-of-line - closure: end-of-line - if: - opening: undefined - always: true - else_on_new_line: false - for: - opening: undefined - always: true - while: - opening: undefined - always: true - do_while: - opening: undefined - always: true - while_on_new_line: false - switch: - opening: undefined - try: - opening: undefined - catch_on_new_line: false - finally_on_new_line: false + braces: + classes_functions: + class: end-of-line + function: end-of-line + closure: end-of-line + if: + opening: undefined + always: true + else_on_new_line: false + for: + opening: undefined + always: true + while: + opening: undefined + always: true + do_while: + opening: undefined + always: true + while_on_new_line: false + switch: + opening: undefined + try: + opening: undefined + catch_on_new_line: false + finally_on_new_line: false build: tests: override: From 6b8bc5a1e09354b9649fc91a81257a391ec83612 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 19 Jun 2019 15:55:39 +0100 Subject: [PATCH 165/440] Moved utilities --- src/Controllers/Version4/SystemStatus.php | 12 ++++++------ .../Version4}/Utilities/DatabaseInformation.php | 2 +- .../Version4}/Utilities/PluginInformation.php | 2 +- .../Version4}/Utilities/ServerEnvironment.php | 2 +- .../Version4}/Utilities/ThemeInformation.php | 2 +- .../Version4}/Utilities/WPEnvironment.php | 2 +- .../Version4}/Utilities/WooEnvironment.php | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) rename src/{ => Controllers/Version4}/Utilities/DatabaseInformation.php (98%) rename src/{ => Controllers/Version4}/Utilities/PluginInformation.php (98%) rename src/{ => Controllers/Version4}/Utilities/ServerEnvironment.php (98%) rename src/{ => Controllers/Version4}/Utilities/ThemeInformation.php (98%) rename src/{ => Controllers/Version4}/Utilities/WPEnvironment.php (98%) rename src/{ => Controllers/Version4}/Utilities/WooEnvironment.php (97%) diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index 07512d8e949..946d2c2fe3b 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -554,12 +554,12 @@ class SystemStatus extends AbstractController { * @return array */ public function get_item_mappings() { - $plugin_info = new \WooCommerce\RestApi\Utilities\PluginInformation(); - $theme_info = new \WooCommerce\RestApi\Utilities\ThemeInformation(); - $server = new \WooCommerce\RestApi\Utilities\ServerEnvironment(); - $database = new \WooCommerce\RestApi\Utilities\DatabaseInformation(); - $wp_environment = new \WooCommerce\RestApi\Utilities\WPEnvironment(); - $woo_environment = new \WooCommerce\RestApi\Utilities\WooEnvironment(); + $plugin_info = new \WooCommerce\RestApi\Controllers\Version4\Utilities\PluginInformation(); + $theme_info = new \WooCommerce\RestApi\Controllers\Version4\Utilities\ThemeInformation(); + $server = new \WooCommerce\RestApi\Controllers\Version4\Utilities\ServerEnvironment(); + $database = new \WooCommerce\RestApi\Controllers\Version4\Utilities\DatabaseInformation(); + $wp_environment = new \WooCommerce\RestApi\Controllers\Version4\Utilities\WPEnvironment(); + $woo_environment = new \WooCommerce\RestApi\Controllers\Version4\Utilities\WooEnvironment(); return array( 'environment' => $server->get_environment_info(), diff --git a/src/Utilities/DatabaseInformation.php b/src/Controllers/Version4/Utilities/DatabaseInformation.php similarity index 98% rename from src/Utilities/DatabaseInformation.php rename to src/Controllers/Version4/Utilities/DatabaseInformation.php index caed00ecfaf..ce9dd3ff1a9 100644 --- a/src/Utilities/DatabaseInformation.php +++ b/src/Controllers/Version4/Utilities/DatabaseInformation.php @@ -5,7 +5,7 @@ * @package WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Utilities; +namespace WooCommerce\RestApi\Controllers\Version4\Utilities; /** * DatabaseInformation class. diff --git a/src/Utilities/PluginInformation.php b/src/Controllers/Version4/Utilities/PluginInformation.php similarity index 98% rename from src/Utilities/PluginInformation.php rename to src/Controllers/Version4/Utilities/PluginInformation.php index 925d44ca121..5cb411f2e35 100644 --- a/src/Utilities/PluginInformation.php +++ b/src/Controllers/Version4/Utilities/PluginInformation.php @@ -5,7 +5,7 @@ * @package WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Utilities; +namespace WooCommerce\RestApi\Controllers\Version4\Utilities; /** * PluginInformation class. diff --git a/src/Utilities/ServerEnvironment.php b/src/Controllers/Version4/Utilities/ServerEnvironment.php similarity index 98% rename from src/Utilities/ServerEnvironment.php rename to src/Controllers/Version4/Utilities/ServerEnvironment.php index 7bf4207ec46..ef22222f442 100644 --- a/src/Utilities/ServerEnvironment.php +++ b/src/Controllers/Version4/Utilities/ServerEnvironment.php @@ -5,7 +5,7 @@ * @package WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Utilities; +namespace WooCommerce\RestApi\Controllers\Version4\Utilities; /** * ServerEnvironment class. diff --git a/src/Utilities/ThemeInformation.php b/src/Controllers/Version4/Utilities/ThemeInformation.php similarity index 98% rename from src/Utilities/ThemeInformation.php rename to src/Controllers/Version4/Utilities/ThemeInformation.php index 001f2849d0b..45d6ac68072 100644 --- a/src/Utilities/ThemeInformation.php +++ b/src/Controllers/Version4/Utilities/ThemeInformation.php @@ -5,7 +5,7 @@ * @package WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Utilities; +namespace WooCommerce\RestApi\Controllers\Version4\Utilities; /** * ThemeInformation class. diff --git a/src/Utilities/WPEnvironment.php b/src/Controllers/Version4/Utilities/WPEnvironment.php similarity index 98% rename from src/Utilities/WPEnvironment.php rename to src/Controllers/Version4/Utilities/WPEnvironment.php index 88d0571aa66..ad29dd08396 100644 --- a/src/Utilities/WPEnvironment.php +++ b/src/Controllers/Version4/Utilities/WPEnvironment.php @@ -5,7 +5,7 @@ * @package WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Utilities; +namespace WooCommerce\RestApi\Controllers\Version4\Utilities; /** * WPEnvironment class. diff --git a/src/Utilities/WooEnvironment.php b/src/Controllers/Version4/Utilities/WooEnvironment.php similarity index 97% rename from src/Utilities/WooEnvironment.php rename to src/Controllers/Version4/Utilities/WooEnvironment.php index 47882cf7eff..28a7e4fbaa1 100644 --- a/src/Utilities/WooEnvironment.php +++ b/src/Controllers/Version4/Utilities/WooEnvironment.php @@ -5,7 +5,7 @@ * @package WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Utilities; +namespace WooCommerce\RestApi\Controllers\Version4\Utilities; /** * WooEnvironment class. From acfaf1a284f15ac191ade6e39acbf35000622f3d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jun 2019 11:30:19 +0100 Subject: [PATCH 166/440] Update autoload handling and build --- .gitattributes | 8 ++-- .gitignore | 1 + classmap.php.bak | 104 ----------------------------------------------- composer.json | 8 ++-- composer.lock | 24 +++++------ 5 files changed, 19 insertions(+), 126 deletions(-) delete mode 100644 classmap.php.bak diff --git a/.gitattributes b/.gitattributes index f125c3166c7..51aa9279117 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,6 @@ /.* export-ignore -composer.* export-ignore -Gruntfile.js export-ignore -package.json export-ignore -package-lock.json export-ignore +classmap.php.bak export-ignore phpcs.xml export-ignore phpunit.* export-ignore -tests export-ignore +unit-tests export-ignore +vendor export-ignore diff --git a/.gitignore b/.gitignore index b19a8d1f0ae..dd37e6a9ec2 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ Thumbs.db # composer vendor/ +classmap.php.bak diff --git a/classmap.php.bak b/classmap.php.bak deleted file mode 100644 index 742c3168c7b..00000000000 --- a/classmap.php.bak +++ /dev/null @@ -1,104 +0,0 @@ - $baseDir . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-controller.php', - 'WC_REST_Coupons_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', -); diff --git a/composer.json b/composer.json index 24043ef69b1..83275842339 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "pre-autoload-dump": [ "composer dump-autoload --no-dev --no-scripts", "SlowProg\\CopyFile\\ScriptHandler::copy", - "sed -i.bak -e 's/\\$baseDir = dirname(\\$vendorDir)/\\$baseDir = __DIR__/g' classmap.php" + "sed -i.bak -e 's/\\$baseDir = dirname(\\$vendorDir)/\\$baseDir = __DIR__/g' classmap.php", + "rm classmap.php.bak" ] }, "autoload": { @@ -29,10 +30,7 @@ "src/Controllers/Version1", "src/Controllers/Version2", "src/Controllers/Version3" - ], - "psr-4": { - "WooCommerce\\RestApi\\": "src/" - } + ] }, "extra": { "copy-file": { diff --git a/composer.lock b/composer.lock index e5d3819d5a8..148443bae27 100644 --- a/composer.lock +++ b/composer.lock @@ -591,16 +591,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.8.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76", + "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76", "shasum": "" }, "require": { @@ -621,8 +621,8 @@ } }, "autoload": { - "psr-0": { - "Prophecy\\": "src/" + "psr-4": { + "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", @@ -650,7 +650,7 @@ "spy", "stub" ], - "time": "2018-08-05T17:53:17+00:00" + "time": "2019-06-13T12:50:23+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1763,16 +1763,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8" + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8", - "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "shasum": "" }, "require": { @@ -1799,7 +1799,7 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2019-04-04T09:56:43+00:00" + "time": "2019-06-13T22:48:21+00:00" }, { "name": "webmozart/assert", From 9283910e115b2df21f11b1d9d69d7601b03cae89 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 20 Jun 2019 13:37:59 +0100 Subject: [PATCH 167/440] Test version without custom autoloader and allow core to generate this after install --- .gitattributes | 1 - classmap.php | 104 --------------------------------------------- composer.json | 20 ++------- init.php | 9 ++-- src/Autoloader.php | 82 ----------------------------------- 5 files changed, 7 insertions(+), 209 deletions(-) delete mode 100644 classmap.php delete mode 100644 src/Autoloader.php diff --git a/.gitattributes b/.gitattributes index 51aa9279117..61739dd0a85 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,4 @@ /.* export-ignore -classmap.php.bak export-ignore phpcs.xml export-ignore phpunit.* export-ignore unit-tests export-ignore diff --git a/classmap.php b/classmap.php deleted file mode 100644 index 1120d34c766..00000000000 --- a/classmap.php +++ /dev/null @@ -1,104 +0,0 @@ - $baseDir . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-controller.php', - 'WC_REST_Coupons_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', -); diff --git a/composer.json b/composer.json index 83275842339..1d95ffbf90f 100644 --- a/composer.json +++ b/composer.json @@ -8,8 +8,7 @@ "minimum-stability": "dev", "require-dev": { "phpunit/phpunit": "6.5.14", - "woocommerce/woocommerce-sniffs": "0.0.6", - "slowprog/composer-copy-file": "~0.3" + "woocommerce/woocommerce-sniffs": "0.0.6" }, "scripts": { "post-install-cmd": [ @@ -17,12 +16,6 @@ ], "post-update-cmd": [ "composer dump-autoload" - ], - "pre-autoload-dump": [ - "composer dump-autoload --no-dev --no-scripts", - "SlowProg\\CopyFile\\ScriptHandler::copy", - "sed -i.bak -e 's/\\$baseDir = dirname(\\$vendorDir)/\\$baseDir = __DIR__/g' classmap.php", - "rm classmap.php.bak" ] }, "autoload": { @@ -30,14 +23,9 @@ "src/Controllers/Version1", "src/Controllers/Version2", "src/Controllers/Version3" - ] - }, - "extra": { - "copy-file": { - "vendor/composer/autoload_classmap.php": "classmap.php" - }, - "copy-file-dev": { - "vendor/composer/autoload_classmap.php": "classmap.php" + ], + "psr-4": { + "WooCommerce\\RestApi\\": "src/" } } } diff --git a/init.php b/init.php index 76f449f9bea..63e89eeb4ca 100644 --- a/init.php +++ b/init.php @@ -6,12 +6,9 @@ */ return function() { - if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { - require __DIR__ . '/vendor/autoload.php'; - } else { - require __DIR__ . '/src/Autoloader.php'; - $classmap = require 'classmap.php'; - \WooCommerce\RestApi\Autoloader::register( $classmap ); + if ( ! file_exists( __DIR__ . '/vendor/autoload.php' ) ) { + return; } + require __DIR__ . '/vendor/autoload.php'; \WooCommerce\RestApi\Server::instance()->init(); }; diff --git a/src/Autoloader.php b/src/Autoloader.php deleted file mode 100644 index 805b072ebbb..00000000000 --- a/src/Autoloader.php +++ /dev/null @@ -1,82 +0,0 @@ - Date: Thu, 20 Jun 2019 13:47:04 +0100 Subject: [PATCH 168/440] Revert "Test version without custom autoloader and allow core to generate this after install" This reverts commit 9283910e115b2df21f11b1d9d69d7601b03cae89. --- .gitattributes | 1 + classmap.php | 104 +++++++++++++++++++++++++++++++++++++++++++++ composer.json | 20 +++++++-- init.php | 9 ++-- src/Autoloader.php | 82 +++++++++++++++++++++++++++++++++++ 5 files changed, 209 insertions(+), 7 deletions(-) create mode 100644 classmap.php create mode 100644 src/Autoloader.php diff --git a/.gitattributes b/.gitattributes index 61739dd0a85..51aa9279117 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ /.* export-ignore +classmap.php.bak export-ignore phpcs.xml export-ignore phpunit.* export-ignore unit-tests export-ignore diff --git a/classmap.php b/classmap.php new file mode 100644 index 00000000000..1120d34c766 --- /dev/null +++ b/classmap.php @@ -0,0 +1,104 @@ + $baseDir . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', +); diff --git a/composer.json b/composer.json index 1d95ffbf90f..83275842339 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,8 @@ "minimum-stability": "dev", "require-dev": { "phpunit/phpunit": "6.5.14", - "woocommerce/woocommerce-sniffs": "0.0.6" + "woocommerce/woocommerce-sniffs": "0.0.6", + "slowprog/composer-copy-file": "~0.3" }, "scripts": { "post-install-cmd": [ @@ -16,6 +17,12 @@ ], "post-update-cmd": [ "composer dump-autoload" + ], + "pre-autoload-dump": [ + "composer dump-autoload --no-dev --no-scripts", + "SlowProg\\CopyFile\\ScriptHandler::copy", + "sed -i.bak -e 's/\\$baseDir = dirname(\\$vendorDir)/\\$baseDir = __DIR__/g' classmap.php", + "rm classmap.php.bak" ] }, "autoload": { @@ -23,9 +30,14 @@ "src/Controllers/Version1", "src/Controllers/Version2", "src/Controllers/Version3" - ], - "psr-4": { - "WooCommerce\\RestApi\\": "src/" + ] + }, + "extra": { + "copy-file": { + "vendor/composer/autoload_classmap.php": "classmap.php" + }, + "copy-file-dev": { + "vendor/composer/autoload_classmap.php": "classmap.php" } } } diff --git a/init.php b/init.php index 63e89eeb4ca..76f449f9bea 100644 --- a/init.php +++ b/init.php @@ -6,9 +6,12 @@ */ return function() { - if ( ! file_exists( __DIR__ . '/vendor/autoload.php' ) ) { - return; + if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { + require __DIR__ . '/vendor/autoload.php'; + } else { + require __DIR__ . '/src/Autoloader.php'; + $classmap = require 'classmap.php'; + \WooCommerce\RestApi\Autoloader::register( $classmap ); } - require __DIR__ . '/vendor/autoload.php'; \WooCommerce\RestApi\Server::instance()->init(); }; diff --git a/src/Autoloader.php b/src/Autoloader.php new file mode 100644 index 00000000000..805b072ebbb --- /dev/null +++ b/src/Autoloader.php @@ -0,0 +1,82 @@ + Date: Thu, 20 Jun 2019 16:51:47 +0100 Subject: [PATCH 169/440] Test without init code - just an autoloader --- classmap.php | 104 --------------------------------------- composer.json | 23 ++------- composer.lock | 41 ++++++++++++++- init.php | 17 ------- src/Autoloader.php | 82 ------------------------------ src/Server.php | 21 ++++++++ version.php | 8 --- woocommerce-rest-api.php | 21 ++------ 8 files changed, 69 insertions(+), 248 deletions(-) delete mode 100644 classmap.php delete mode 100644 init.php delete mode 100644 src/Autoloader.php delete mode 100644 version.php diff --git a/classmap.php b/classmap.php deleted file mode 100644 index 1120d34c766..00000000000 --- a/classmap.php +++ /dev/null @@ -1,104 +0,0 @@ - $baseDir . '/src/Controllers/Version3/class-wc-rest-crud-controller.php', - 'WC_REST_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-controller.php', - 'WC_REST_Coupons_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-coupons-controller.php', - 'WC_REST_Coupons_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', - 'WC_REST_Coupons_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', - 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', - 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', - 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', - 'WC_REST_Customers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-customers-controller.php', - 'WC_REST_Customers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php', - 'WC_REST_Customers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php', - 'WC_REST_Data_Continents_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-continents-controller.php', - 'WC_REST_Data_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-controller.php', - 'WC_REST_Data_Countries_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-countries-controller.php', - 'WC_REST_Data_Currencies_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php', - 'WC_REST_Network_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-network-orders-controller.php', - 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', - 'WC_REST_Order_Notes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-notes-controller.php', - 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', - 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', - 'WC_REST_Order_Refunds_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php', - 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', - 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', - 'WC_REST_Orders_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-orders-controller.php', - 'WC_REST_Orders_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php', - 'WC_REST_Orders_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php', - 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', - 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', - 'WC_REST_Posts_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-posts-controller.php', - 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', - 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', - 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', - 'WC_REST_Product_Attributes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php', - 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', - 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', - 'WC_REST_Product_Categories_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-categories-controller.php', - 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', - 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', - 'WC_REST_Product_Reviews_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php', - 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', - 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', - 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', - 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', - 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', - 'WC_REST_Product_Tags_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-tags-controller.php', - 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', - 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', - 'WC_REST_Product_Variations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-product-variations-controller.php', - 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', - 'WC_REST_Products_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-products-controller.php', - 'WC_REST_Products_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-products-v1-controller.php', - 'WC_REST_Products_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-products-v2-controller.php', - 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', - 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', - 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', - 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', - 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', - 'WC_REST_Report_Sales_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-sales-controller.php', - 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', - 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', - 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', - 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', - 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', - 'WC_REST_Reports_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-reports-controller.php', - 'WC_REST_Reports_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php', - 'WC_REST_Reports_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php', - 'WC_REST_Setting_Options_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-setting-options-controller.php', - 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', - 'WC_REST_Settings_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-settings-controller.php', - 'WC_REST_Settings_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php', - 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', - 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', - 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', - 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', - 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', - 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', - 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', - 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', - 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', - 'WC_REST_System_Status_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-controller.php', - 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', - 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', - 'WC_REST_System_Status_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', - 'WC_REST_Tax_Classes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php', - 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', - 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', - 'WC_REST_Taxes_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-taxes-controller.php', - 'WC_REST_Taxes_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', - 'WC_REST_Taxes_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', - 'WC_REST_Terms_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-terms-controller.php', - 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', - 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', - 'WC_REST_Webhooks_Controller' => $baseDir . '/src/Controllers/Version3/class-wc-rest-webhooks-controller.php', - 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', - 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', -); diff --git a/composer.json b/composer.json index 83275842339..1ed922d9ccb 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,9 @@ "type": "wordpress-plugin", "prefer-stable": true, "minimum-stability": "dev", + "require": { + "automattic/jetpack-autoloader": "^1" + }, "require-dev": { "phpunit/phpunit": "6.5.14", "woocommerce/woocommerce-sniffs": "0.0.6", @@ -17,27 +20,11 @@ ], "post-update-cmd": [ "composer dump-autoload" - ], - "pre-autoload-dump": [ - "composer dump-autoload --no-dev --no-scripts", - "SlowProg\\CopyFile\\ScriptHandler::copy", - "sed -i.bak -e 's/\\$baseDir = dirname(\\$vendorDir)/\\$baseDir = __DIR__/g' classmap.php", - "rm classmap.php.bak" ] }, "autoload": { - "classmap": [ - "src/Controllers/Version1", - "src/Controllers/Version2", - "src/Controllers/Version3" - ] - }, - "extra": { - "copy-file": { - "vendor/composer/autoload_classmap.php": "classmap.php" - }, - "copy-file-dev": { - "vendor/composer/autoload_classmap.php": "classmap.php" + "psr-4": { + "WooCommerce\\RestApi\\": "src" } } } diff --git a/composer.lock b/composer.lock index 148443bae27..aeca76fa924 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,45 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e99b4d430b010135822c6362c7ebd4a6", - "packages": [], + "content-hash": "0654700fc5735080c502c67e64be6c00", + "packages": [ + { + "name": "automattic/jetpack-autoloader", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/Automattic/jetpack-autoloader.git", + "reference": "cf08e893a481e71feec6e61164efff0eeee98ccd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/cf08e893a481e71feec6e61164efff0eeee98ccd", + "reference": "cf08e893a481e71feec6e61164efff0eeee98ccd", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5" + }, + "type": "composer-plugin", + "extra": { + "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin" + }, + "autoload": { + "psr-4": { + "Automattic\\Jetpack\\Autoloader\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Creates a custom autoloader for a plugin or theme.", + "time": "2019-06-17T13:03:00+00:00" + } + ], "packages-dev": [ { "name": "dealerdirect/phpcodesniffer-composer-installer", diff --git a/init.php b/init.php deleted file mode 100644 index 76f449f9bea..00000000000 --- a/init.php +++ /dev/null @@ -1,17 +0,0 @@ -init(); -}; diff --git a/src/Autoloader.php b/src/Autoloader.php deleted file mode 100644 index 805b072ebbb..00000000000 --- a/src/Autoloader.php +++ /dev/null @@ -1,82 +0,0 @@ - 'WC_REST_Coupons_V1_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_V1_Controller', @@ -96,6 +103,13 @@ class Server { * @return array */ protected function get_v2_controllers() { + // Include legacy classes which are not autoloaded. + $controllers = glob( 'Version2/class-wc-*.php' ); + + foreach ( $controllers as $file ) { + include $file; + } + return [ 'coupons' => 'WC_REST_Coupons_V2_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_V2_Controller', @@ -137,6 +151,13 @@ class Server { * @return array */ protected function get_v3_controllers() { + // Include legacy classes which are not autoloaded. + $controllers = glob( 'Version3/class-wc-*.php' ); + + foreach ( $controllers as $file ) { + include $file; + } + return [ 'coupons' => 'WC_REST_Coupons_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_Controller', diff --git a/version.php b/version.php deleted file mode 100644 index e26da460584..00000000000 --- a/version.php +++ /dev/null @@ -1,8 +0,0 @@ - Date: Fri, 21 Jun 2019 10:17:22 +0100 Subject: [PATCH 170/440] Use package autoloader --- composer.json | 5 +++++ package-version.php | 8 +++++++ src/Server.php | 21 ------------------ woocommerce-rest-api.php | 47 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 package-version.php diff --git a/composer.json b/composer.json index 1ed922d9ccb..027da616ad7 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,11 @@ ] }, "autoload": { + "classmap": [ + "src/Controllers/Version1", + "src/Controllers/Version2", + "src/Controllers/Version3" + ], "psr-4": { "WooCommerce\\RestApi\\": "src" } diff --git a/package-version.php b/package-version.php new file mode 100644 index 00000000000..41e7b7621af --- /dev/null +++ b/package-version.php @@ -0,0 +1,8 @@ + 'WC_REST_Coupons_V1_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_V1_Controller', @@ -103,13 +96,6 @@ class Server { * @return array */ protected function get_v2_controllers() { - // Include legacy classes which are not autoloaded. - $controllers = glob( 'Version2/class-wc-*.php' ); - - foreach ( $controllers as $file ) { - include $file; - } - return [ 'coupons' => 'WC_REST_Coupons_V2_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_V2_Controller', @@ -151,13 +137,6 @@ class Server { * @return array */ protected function get_v3_controllers() { - // Include legacy classes which are not autoloaded. - $controllers = glob( 'Version3/class-wc-*.php' ); - - foreach ( $controllers as $file ) { - include $file; - } - return [ 'coupons' => 'WC_REST_Coupons_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_Controller', diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index c1dd66dc2a3..18f41482ce3 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -14,11 +14,58 @@ defined( 'ABSPATH' ) || exit; +/** + * This file is only used when running the REST API as a feature plugin. Core (and other packages) should not include it. + */ + if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) { return; } +/** + * Autoload packages. + * + * The package autoloader includes version information which prevents classes in this feature plugin + * conflicting with WooCommerce core. + * + * We want to fail gracefully if `composer install` has not been executed yet, so we are checking for the autoloader. + * If the autoloader is not present, let's log the failure and display a nice admin notice. + */ $autoloader = __DIR__ . '/vendor/autoload_packages.php'; if ( is_readable( $autoloader ) ) { require $autoloader; +} else { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + error_log( // phpcs:ignore + sprintf( + /* translators: 1: composer command. 2: plugin directory */ + esc_html__( 'Your installation of the WooCommerce REST API feature plugin is incomplete. Please run %1$s within the %2$s directory.', 'woocommerce' ), + '`composer install`', + '`' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '`' + ) + ); + } + /** + * Outputs an admin notice if composer install has not been ran. + */ + add_action( + 'admin_notices', + function() { + ?> +
+

+ composer install', + '' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '' + ); + ?> +

+
+ Date: Fri, 21 Jun 2019 10:40:39 +0100 Subject: [PATCH 171/440] Update dist file and namespaces --- .gitattributes | 12 +++-- README.md | 48 +++++++++-------- composer.json | 2 +- package-version.php | 8 +-- .../class-wc-rest-coupons-v1-controller.php | 4 +- ...-rest-customer-downloads-v1-controller.php | 4 +- .../class-wc-rest-customers-v1-controller.php | 4 +- ...lass-wc-rest-order-notes-v1-controller.php | 4 +- ...ss-wc-rest-order-refunds-v1-controller.php | 4 +- .../class-wc-rest-orders-v1-controller.php | 4 +- ...-product-attribute-terms-v1-controller.php | 4 +- ...-rest-product-attributes-v1-controller.php | 4 +- ...-rest-product-categories-v1-controller.php | 4 +- ...-wc-rest-product-reviews-v1-controller.php | 4 +- ...product-shipping-classes-v1-controller.php | 4 +- ...ass-wc-rest-product-tags-v1-controller.php | 4 +- .../class-wc-rest-products-v1-controller.php | 4 +- ...ass-wc-rest-report-sales-v1-controller.php | 4 +- ...-rest-report-top-sellers-v1-controller.php | 4 +- .../class-wc-rest-reports-v1-controller.php | 4 +- ...lass-wc-rest-tax-classes-v1-controller.php | 4 +- .../class-wc-rest-taxes-v1-controller.php | 4 +- ...-rest-webhook-deliveries-v1-controller.php | 4 +- .../class-wc-rest-webhooks-v1-controller.php | 4 +- .../class-wc-rest-coupons-v2-controller.php | 4 +- ...-rest-customer-downloads-v2-controller.php | 4 +- .../class-wc-rest-customers-v2-controller.php | 4 +- ...s-wc-rest-network-orders-v2-controller.php | 4 +- ...lass-wc-rest-order-notes-v2-controller.php | 4 +- ...ss-wc-rest-order-refunds-v2-controller.php | 4 +- .../class-wc-rest-orders-v2-controller.php | 4 +- ...wc-rest-payment-gateways-v2-controller.php | 4 +- ...-product-attribute-terms-v2-controller.php | 4 +- ...-rest-product-attributes-v2-controller.php | 4 +- ...-rest-product-categories-v2-controller.php | 4 +- ...-wc-rest-product-reviews-v2-controller.php | 4 +- ...product-shipping-classes-v2-controller.php | 4 +- ...ass-wc-rest-product-tags-v2-controller.php | 4 +- ...-rest-product-variations-v2-controller.php | 4 +- .../class-wc-rest-products-v2-controller.php | 4 +- ...ass-wc-rest-report-sales-v2-controller.php | 4 +- ...-rest-report-top-sellers-v2-controller.php | 4 +- .../class-wc-rest-reports-v2-controller.php | 4 +- ...-wc-rest-setting-options-v2-controller.php | 4 +- .../class-wc-rest-settings-v2-controller.php | 4 +- ...wc-rest-shipping-methods-v2-controller.php | 4 +- ...-shipping-zone-locations-v2-controller.php | 4 +- ...st-shipping-zone-methods-v2-controller.php | 4 +- ...s-wc-rest-shipping-zones-v2-controller.php | 4 +- ...rest-system-status-tools-v2-controller.php | 4 +- ...ss-wc-rest-system-status-v2-controller.php | 4 +- ...lass-wc-rest-tax-classes-v2-controller.php | 4 +- .../class-wc-rest-taxes-v2-controller.php | 4 +- ...-rest-webhook-deliveries-v2-controller.php | 4 +- .../class-wc-rest-webhooks-v2-controller.php | 4 +- .../Version3/class-wc-rest-controller.php | 4 +- .../class-wc-rest-coupons-controller.php | 4 +- .../class-wc-rest-crud-controller.php | 2 +- ...-wc-rest-customer-downloads-controller.php | 4 +- .../class-wc-rest-customers-controller.php | 4 +- ...ass-wc-rest-data-continents-controller.php | 4 +- .../class-wc-rest-data-controller.php | 4 +- ...lass-wc-rest-data-countries-controller.php | 4 +- ...ass-wc-rest-data-currencies-controller.php | 4 +- ...lass-wc-rest-network-orders-controller.php | 4 +- .../class-wc-rest-order-notes-controller.php | 4 +- ...class-wc-rest-order-refunds-controller.php | 4 +- .../class-wc-rest-orders-controller.php | 4 +- ...ss-wc-rest-payment-gateways-controller.php | 4 +- .../class-wc-rest-posts-controller.php | 4 +- ...est-product-attribute-terms-controller.php | 4 +- ...-wc-rest-product-attributes-controller.php | 4 +- ...-wc-rest-product-categories-controller.php | 4 +- ...ass-wc-rest-product-reviews-controller.php | 4 +- ...st-product-shipping-classes-controller.php | 4 +- .../class-wc-rest-product-tags-controller.php | 4 +- ...-wc-rest-product-variations-controller.php | 4 +- .../class-wc-rest-products-controller.php | 4 +- ...-rest-report-coupons-totals-controller.php | 4 +- ...est-report-customers-totals-controller.php | 4 +- ...c-rest-report-orders-totals-controller.php | 4 +- ...rest-report-products-totals-controller.php | 4 +- ...-rest-report-reviews-totals-controller.php | 4 +- .../class-wc-rest-report-sales-controller.php | 4 +- ...-wc-rest-report-top-sellers-controller.php | 4 +- .../class-wc-rest-reports-controller.php | 4 +- ...ass-wc-rest-setting-options-controller.php | 4 +- .../class-wc-rest-settings-controller.php | 4 +- ...ss-wc-rest-shipping-methods-controller.php | 4 +- ...est-shipping-zone-locations-controller.php | 4 +- ...-rest-shipping-zone-methods-controller.php | 4 +- ...wc-rest-shipping-zones-controller-base.php | 4 +- ...lass-wc-rest-shipping-zones-controller.php | 4 +- ...class-wc-rest-system-status-controller.php | 4 +- ...wc-rest-system-status-tools-controller.php | 4 +- .../class-wc-rest-tax-classes-controller.php | 4 +- .../class-wc-rest-taxes-controller.php | 4 +- .../class-wc-rest-terms-controller.php | 2 +- .../class-wc-rest-webhooks-controller.php | 4 +- .../Version4/AbstractController.php | 10 ++-- .../Version4/AbstractObjectsController.php | 8 +-- .../AbstractShippingZonesController.php | 6 +-- .../Version4/AbstractTermsContoller.php | 8 +-- src/Controllers/Version4/Coupons.php | 4 +- .../Version4/CustomerDownloads.php | 6 +-- src/Controllers/Version4/Customers.php | 10 ++-- src/Controllers/Version4/Data.php | 4 +- src/Controllers/Version4/Data/Continents.php | 6 +-- src/Controllers/Version4/Data/Countries.php | 6 +-- src/Controllers/Version4/Data/Currencies.php | 6 +-- src/Controllers/Version4/Data/DownloadIPs.php | 6 +-- src/Controllers/Version4/NetworkOrders.php | 4 +- src/Controllers/Version4/OrderNotes.php | 6 +-- src/Controllers/Version4/OrderRefunds.php | 4 +- src/Controllers/Version4/Orders.php | 8 +-- src/Controllers/Version4/PaymentGateways.php | 6 +-- .../Version4/ProductAttributeTerms.php | 4 +- .../Version4/ProductAttributes.php | 4 +- .../Version4/ProductCategories.php | 4 +- src/Controllers/Version4/ProductReviews.php | 10 ++-- .../Version4/ProductShippingClasses.php | 4 +- src/Controllers/Version4/ProductTags.php | 4 +- .../Version4/ProductVariations.php | 10 ++-- src/Controllers/Version4/Products.php | 10 ++-- .../Requests/AbstractObjectRequest.php | 4 +- .../Version4/Requests/CustomerRequest.php | 4 +- .../Version4/Requests/OrderRequest.php | 4 +- .../Version4/Requests/ProductRequest.php | 6 +-- .../Requests/ProductVariationRequest.php | 6 +-- .../Responses/AbstractObjectResponse.php | 4 +- .../Version4/Responses/CustomerResponse.php | 4 +- .../Version4/Responses/OrderResponse.php | 4 +- .../Version4/Responses/ProductResponse.php | 4 +- .../Responses/ProductReviewResponse.php | 4 +- .../Responses/ProductVariationResponse.php | 4 +- src/Controllers/Version4/Settings.php | 4 +- src/Controllers/Version4/SettingsOptions.php | 6 +-- src/Controllers/Version4/ShippingMethods.php | 4 +- .../Version4/ShippingZoneLocations.php | 4 +- .../Version4/ShippingZoneMethods.php | 6 +-- src/Controllers/Version4/ShippingZones.php | 4 +- src/Controllers/Version4/SystemStatus.php | 16 +++--- .../Version4/SystemStatusTools.php | 4 +- src/Controllers/Version4/TaxClasses.php | 4 +- src/Controllers/Version4/Taxes.php | 6 +-- .../Version4/Utilities/BatchTrait.php | 4 +- .../Utilities/DatabaseInformation.php | 4 +- .../Version4/Utilities/Pagination.php | 4 +- .../Version4/Utilities/Permissions.php | 4 +- .../Version4/Utilities/PluginInformation.php | 4 +- .../Version4/Utilities/ServerEnvironment.php | 4 +- .../Version4/Utilities/SettingsTrait.php | 4 +- .../Version4/Utilities/ThemeInformation.php | 4 +- .../Version4/Utilities/WPEnvironment.php | 4 +- .../Version4/Utilities/WooEnvironment.php | 4 +- src/Controllers/Version4/Webhooks.php | 6 +-- src/Server.php | 6 +-- src/Utilities/ImageAttachment.php | 4 +- src/Utilities/SingletonTrait.php | 4 +- unit-tests/AbstractRestApiTest.php | 10 ++-- unit-tests/Bootstrap.php | 6 +-- unit-tests/Helpers/AdminNotesHelper.php | 2 +- unit-tests/Helpers/CouponHelper.php | 2 +- unit-tests/Helpers/CustomerHelper.php | 2 +- unit-tests/Helpers/OrderHelper.php | 4 +- unit-tests/Helpers/ProductHelper.php | 2 +- unit-tests/Helpers/QueueHelper.php | 2 +- unit-tests/Helpers/SettingsHelper.php | 2 +- unit-tests/Helpers/ShippingHelper.php | 2 +- unit-tests/Tests/Version2/coupons.php | 24 ++++----- unit-tests/Tests/Version2/customers.php | 22 ++++---- unit-tests/Tests/Version2/orders.php | 42 +++++++-------- unit-tests/Tests/Version2/product-reviews.php | 54 +++++++++---------- .../Tests/Version2/product-variations.php | 30 +++++------ unit-tests/Tests/Version2/products.php | 26 ++++----- unit-tests/Tests/Version2/settings.php | 2 +- unit-tests/Tests/Version2/system-status.php | 2 +- unit-tests/Tests/Version3/coupons.php | 24 ++++----- unit-tests/Tests/Version3/customers.php | 24 ++++----- unit-tests/Tests/Version3/orders.php | 44 +++++++-------- unit-tests/Tests/Version3/product-reviews.php | 54 +++++++++---------- .../Tests/Version3/product-variations.php | 30 +++++------ unit-tests/Tests/Version3/products.php | 46 ++++++++-------- .../Tests/Version3/reports-coupons-totals.php | 2 +- .../Version3/reports-customers-totals.php | 2 +- .../Tests/Version3/reports-orders-totals.php | 2 +- .../Version3/reports-products-totals.php | 2 +- .../Tests/Version3/reports-reviews-totals.php | 2 +- unit-tests/Tests/Version3/settings.php | 2 +- unit-tests/Tests/Version3/system-status.php | 2 +- unit-tests/Tests/Version4/Coupons.php | 8 +-- unit-tests/Tests/Version4/Customers.php | 4 +- unit-tests/Tests/Version4/Data.php | 4 +- unit-tests/Tests/Version4/Orders.php | 16 +++--- unit-tests/Tests/Version4/PaymentGateways.php | 2 +- unit-tests/Tests/Version4/ProductReviews.php | 8 +-- .../Tests/Version4/ProductVariations.php | 4 +- unit-tests/Tests/Version4/Products.php | 4 +- unit-tests/Tests/Version4/Settings.php | 4 +- unit-tests/Tests/Version4/ShippingMethods.php | 2 +- unit-tests/Tests/Version4/ShippingZones.php | 2 +- unit-tests/Tests/Version4/SystemStatus.php | 4 +- woocommerce-rest-api.php | 2 +- 203 files changed, 657 insertions(+), 649 deletions(-) diff --git a/.gitattributes b/.gitattributes index 51aa9279117..63caea1317e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,8 @@ /.* export-ignore -classmap.php.bak export-ignore -phpcs.xml export-ignore -phpunit.* export-ignore -unit-tests export-ignore -vendor export-ignore +/phpcs.xml export-ignore +/phpunit.* export-ignore +/unit-tests export-ignore +/vendor export-ignore +/woocommerce-rest-api.php export-ignore +/README.md export-ignore +/readme.txt export-ignore diff --git a/README.md b/README.md index 5fa541fa285..fbc4faf622f 100644 --- a/README.md +++ b/README.md @@ -10,29 +10,9 @@ This repository is home to the WooCommerce REST API package. The stable version of this package is bundled with [WooCommerce core](https://github.com/woocommerce/woocommerce) releases, but it can also be used as a standalone plugin so bleeding-edge API features can be tested or used by other feature plugins. -## Using this repo +## Using this package as a plugin -After checking out the code, you'll need to run `composer install` in it's root directory to install dependencies and to enable the autoloader. - -## Using this package - -This package is [hosted on Packagist](https://packagist.org/packages/woocommerce/woocommerce-rest-api) and can be included using composer.json: - -```json -"require": { - "woocommerce/woocommerce-rest-api": "1.0.0" -}, -``` - -Since multiple versions of this package may be included at the same time, WooCommerce handles loading __only the latest version__ by using a special loader. - -After including the package and installing dependencies, include the main `woocommerce-rest-api.php` file in your code: - -```php -include 'vendor/woocommerce-rest-api/woocommerce-rest-api.php'; -``` - -This will register the version of the package with WooCommerce and make it available after the `woocommerce_loaded` hook is fired. +After checking out the code to your `wp-content/plugins` directory, you'll need to run `composer install` in the plugin directory (`wp-content/plugins/woocommerce-rest-api`) to install dependencies and to enable the autoloader. Without performing this step, if you activate the plugin it will simply show an admin notice. ## API documentation @@ -50,6 +30,30 @@ This will register the version of the package with WooCommerce and make it avail Note: API Versions are kept around for 2 years after being replaced, and may be removed in the next major version after that date passes. +## Using this package in other projects + +This package is [hosted on Packagist](https://packagist.org/packages/woocommerce/woocommerce-rest-api) and can be included using composer.json: + +```json +"require": { + "woocommerce/woocommerce-rest-api": "1.0.0" +}, +``` + +Since multiple versions of this package may be included at the same time, it includes a special package-version autoloader. This dependency is also on Packagist: + +```json + "automattic/jetpack-autoloader": "^1" +``` + +And using this autoloader requires the following include in your codebase: + +``` +$autoloader = __DIR__ . '/vendor/autoload_packages.php'; +``` + +If you choose to use your own autoloader, please note you won't be able to determine which version of the package is running since it could use the version in WooCommerce core or your version. The namespaces would conflict. All of our feature plugins and packages use the package autoloader. + ## Contributing Please read the [WooCommerce contributor guidelines](https://github.com/woocommerce/woocommerce/blob/master/.github/CONTRIBUTING.md) for more information how you can contribute to WooCommerce, and [the REST API contribution documentation here](https://github.com/woocommerce/woocommerce/wiki/Contributing-to-the-WooCommerce-REST-API). diff --git a/composer.json b/composer.json index 027da616ad7..a1391a1f352 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "src/Controllers/Version3" ], "psr-4": { - "WooCommerce\\RestApi\\": "src" + "Automattic\\WooCommerce\\RestApi\\": "src" } } } diff --git a/package-version.php b/package-version.php index 41e7b7621af..e43b5c3213a 100644 --- a/package-version.php +++ b/package-version.php @@ -1,8 +1,10 @@ /downloads endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Customers controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Customer_Downloads_V1_Controller */ class WC_REST_Customer_Downloads_V2_Controller extends WC_REST_Customer_Downloads_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php index e780f8f6122..de079d1ac2f 100644 --- a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /customers endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Customers controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Customers_V1_Controller */ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php index 26213306ceb..45d0f8b483d 100644 --- a/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders/network endpoint * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.4.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Network Orders controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Orders_V2_Controller */ class WC_REST_Network_Orders_V2_Controller extends WC_REST_Orders_V2_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php index f08ddaef67d..f3d269c963f 100644 --- a/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders//notes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Order Notes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Order_Notes_V1_Controller */ class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php b/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php index 46407715f5e..508db09352b 100644 --- a/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders//refunds endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Order Refunds controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Orders_V2_Controller */ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php index eb149c52d19..197d5a0e1dc 100644 --- a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Orders controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_CRUD_Controller */ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php b/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php index 96eece65ae4..69bfc51f418 100644 --- a/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /payment_gateways endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * Paymenga gateways controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php index 7a7ded8a5b0..27d71b11c10 100644 --- a/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/attributes//terms endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Attribute Terms controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Attribute_Terms_V1_Controller */ class WC_REST_Product_Attribute_Terms_V2_Controller extends WC_REST_Product_Attribute_Terms_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php index f31088d2fc5..3ff18b310a2 100644 --- a/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/attributes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Attributes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Attributes_V1_Controller */ class WC_REST_Product_Attributes_V2_Controller extends WC_REST_Product_Attributes_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php index a217e3f3c9f..08c5f8f1980 100644 --- a/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/categories endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Categories controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Categories_V1_Controller */ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categories_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php index cde63971b85..12ab7d62655 100644 --- a/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to /products//reviews. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Reviews Controller Class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Reviews_V1_Controller */ class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php index 8e2f2204595..6430ded093f 100644 --- a/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/shipping_classes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Shipping Classes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Shipping_Classes_V1_Controller */ class WC_REST_Product_Shipping_Classes_V2_Controller extends WC_REST_Product_Shipping_Classes_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php index 0d62cbdda84..c69e8cb9551 100644 --- a/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/tags endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Tags controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Tags_V1_Controller */ class WC_REST_Product_Tags_V2_Controller extends WC_REST_Product_Tags_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php index 8c1c4d1ad1d..7e051263f93 100644 --- a/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /products//variations endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API variations controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Products_V2_Controller */ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php index c96016a182c..f092749d5fe 100644 --- a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /products endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Products controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_CRUD_Controller */ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php b/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php index f2232447c0a..4c5a873f351 100644 --- a/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports/sales endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Report Sales controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Report_Sales_V1_Controller */ class WC_REST_Report_Sales_V2_Controller extends WC_REST_Report_Sales_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php b/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php index 407ade5c256..5aaab3724f0 100644 --- a/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports/top_sellers endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Report Top Sellers controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Report_Top_Sellers_V1_Controller */ class WC_REST_Report_Top_Sellers_V2_Controller extends WC_REST_Report_Top_Sellers_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php b/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php index 2eea5b97f67..6e0920bb3eb 100644 --- a/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Reports_V1_Controller */ class WC_REST_Reports_V2_Controller extends WC_REST_Reports_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php b/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php index 7136459b925..0b1d988f941 100644 --- a/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /settings/$group/$setting endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Setting Options controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php b/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php index 3b1dd0be705..f41c91e722d 100644 --- a/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /settings endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Settings controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php index 9b8442a12fc..795c92b3e18 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping_methods endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * Shipping methods controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php index 4fd40bc9060..9e171814f70 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones//locations endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Locations class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php index 3cd52028ea6..c753fd8e42f 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones//methods endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Methods class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php index 17038d2d9e5..db881b97fbe 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zones class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index a0e91c97346..4842a63c4fb 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /system_status/tools/* endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * System status tools controller. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index d141e656009..9b4fcec7b38 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /system_status endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * System status controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php index d024195657a..dc1cdd24bd3 100644 --- a/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /taxes/classes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Tax Classes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Tax_Classes_V1_Controller */ class WC_REST_Tax_Classes_V2_Controller extends WC_REST_Tax_Classes_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php index ea3884e9a9b..cf5ed792518 100644 --- a/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /taxes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Taxes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Taxes_V1_Controller */ class WC_REST_Taxes_V2_Controller extends WC_REST_Taxes_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php b/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php index 012a10ba78b..778a805d1e2 100644 --- a/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /webhooks//deliveries endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -14,7 +14,7 @@ defined( 'ABSPATH' ) || exit; * REST API Webhook Deliveries controller class. * * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Webhook_Deliveries_V1_Controller */ class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliveries_V1_Controller { diff --git a/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php b/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php index 7c02e332765..ede2c1d121a 100644 --- a/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /webhooks endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Webhooks controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Webhooks_V1_Controller */ class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-controller.php b/src/Controllers/Version3/class-wc-rest-controller.php index e0ff5c4732c..0c7278ab2cd 100644 --- a/src/Controllers/Version3/class-wc-rest-controller.php +++ b/src/Controllers/Version3/class-wc-rest-controller.php @@ -12,7 +12,7 @@ * If necessary extend this class and create new abstract classes like `WC_REST_CRUD_Controller` or `WC_REST_Terms_Controller`. * * @class WC_REST_Controller - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ */ @@ -23,7 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * Abstract Rest Controller Class * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WP_REST_Controller * @version 2.6.0 */ diff --git a/src/Controllers/Version3/class-wc-rest-coupons-controller.php b/src/Controllers/Version3/class-wc-rest-coupons-controller.php index fe6bcd0e449..0df4a6a3395 100644 --- a/src/Controllers/Version3/class-wc-rest-coupons-controller.php +++ b/src/Controllers/Version3/class-wc-rest-coupons-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /coupons endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Coupons controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Coupons_V2_Controller */ class WC_REST_Coupons_Controller extends WC_REST_Coupons_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-crud-controller.php b/src/Controllers/Version3/class-wc-rest-crud-controller.php index 6953ee2cb52..5733ddbb37d 100644 --- a/src/Controllers/Version3/class-wc-rest-crud-controller.php +++ b/src/Controllers/Version3/class-wc-rest-crud-controller.php @@ -3,7 +3,7 @@ * Abstract Rest CRUD Controller Class * * @class WC_REST_CRUD_Controller - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @version 3.0.0 */ diff --git a/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php b/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php index 1d67ca98c57..78147fe9301 100644 --- a/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php +++ b/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /customers//downloads endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Customers controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Customer_Downloads_V2_Controller */ class WC_REST_Customer_Downloads_Controller extends WC_REST_Customer_Downloads_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-customers-controller.php b/src/Controllers/Version3/class-wc-rest-customers-controller.php index e87360a60a0..b577fe89792 100644 --- a/src/Controllers/Version3/class-wc-rest-customers-controller.php +++ b/src/Controllers/Version3/class-wc-rest-customers-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /customers endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Customers controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Customers_V2_Controller */ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-data-continents-controller.php b/src/Controllers/Version3/class-wc-rest-data-continents-controller.php index ccf64086b3f..37d3a55630d 100644 --- a/src/Controllers/Version3/class-wc-rest-data-continents-controller.php +++ b/src/Controllers/Version3/class-wc-rest-data-continents-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /data/continents endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Data continents controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-data-controller.php b/src/Controllers/Version3/class-wc-rest-data-controller.php index 71c6dd9029a..67a69f025a5 100644 --- a/src/Controllers/Version3/class-wc-rest-data-controller.php +++ b/src/Controllers/Version3/class-wc-rest-data-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /data endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Data controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Data_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-data-countries-controller.php b/src/Controllers/Version3/class-wc-rest-data-countries-controller.php index ff659b67e09..d8219a77439 100644 --- a/src/Controllers/Version3/class-wc-rest-data-countries-controller.php +++ b/src/Controllers/Version3/class-wc-rest-data-countries-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /data/countries endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Data countries controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php b/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php index b5439695d0d..574d9d4c571 100644 --- a/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php +++ b/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /data/currencies endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Data Currencies controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-network-orders-controller.php b/src/Controllers/Version3/class-wc-rest-network-orders-controller.php index 963a7cbec36..5b327a54bce 100644 --- a/src/Controllers/Version3/class-wc-rest-network-orders-controller.php +++ b/src/Controllers/Version3/class-wc-rest-network-orders-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders/network endpoint * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.4.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Network Orders controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Network_Orders_V2_Controller */ class WC_REST_Network_Orders_Controller extends WC_REST_Network_Orders_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-order-notes-controller.php b/src/Controllers/Version3/class-wc-rest-order-notes-controller.php index e45d1ef3e27..738961591e4 100644 --- a/src/Controllers/Version3/class-wc-rest-order-notes-controller.php +++ b/src/Controllers/Version3/class-wc-rest-order-notes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders//notes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Order Notes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Order_Notes_V2_Controller */ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php b/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php index 38e6a69bb6d..98731f5756c 100644 --- a/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php +++ b/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders//refunds endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Order Refunds controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Order_Refunds_V2_Controller */ class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-orders-controller.php b/src/Controllers/Version3/class-wc-rest-orders-controller.php index f7dadc8b42c..5e4ea622fc8 100644 --- a/src/Controllers/Version3/class-wc-rest-orders-controller.php +++ b/src/Controllers/Version3/class-wc-rest-orders-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /orders endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Orders controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Orders_V2_Controller */ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php b/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php index dc71790b6f7..5c0eb9c8ac9 100644 --- a/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php +++ b/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /payment_gateways endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * Paymenga gateways controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Payment_Gateways_V2_Controller */ class WC_REST_Payment_Gateways_Controller extends WC_REST_Payment_Gateways_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-posts-controller.php b/src/Controllers/Version3/class-wc-rest-posts-controller.php index d5966551502..078f5cee4dd 100644 --- a/src/Controllers/Version3/class-wc-rest-posts-controller.php +++ b/src/Controllers/Version3/class-wc-rest-posts-controller.php @@ -3,7 +3,7 @@ * Abstract Rest Posts Controller Class * * @class WC_REST_Posts_Controller - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ if ( ! defined( 'ABSPATH' ) ) { @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * WC_REST_Posts_Controller * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @version 2.6.0 */ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php b/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php index ee6d7b48868..bbbdb6eb822 100644 --- a/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/attributes//terms endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Attribute Terms controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Attribute_Terms_V2_Controller */ class WC_REST_Product_Attribute_Terms_Controller extends WC_REST_Product_Attribute_Terms_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php b/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php index 6dfd84e7972..3506306c130 100644 --- a/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/attributes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Attributes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Attributes_V2_Controller */ class WC_REST_Product_Attributes_Controller extends WC_REST_Product_Attributes_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-product-categories-controller.php b/src/Controllers/Version3/class-wc-rest-product-categories-controller.php index 094c6e8bb52..c69f5640a99 100644 --- a/src/Controllers/Version3/class-wc-rest-product-categories-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-categories-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/categories endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Categories controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Categories_V2_Controller */ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php b/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php index ae0270afa12..7b4a12d2c6e 100644 --- a/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php @@ -4,7 +4,7 @@ * * Handles requests to /products/reviews. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Reviews Controller Class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php b/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php index af07ea955c4..716e40db7f4 100644 --- a/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/shipping_classes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Shipping Classes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Shipping_Classes_V2_Controller */ class WC_REST_Product_Shipping_Classes_Controller extends WC_REST_Product_Shipping_Classes_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-product-tags-controller.php b/src/Controllers/Version3/class-wc-rest-product-tags-controller.php index bb6db01e85b..1a04110f342 100644 --- a/src/Controllers/Version3/class-wc-rest-product-tags-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-tags-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the products/tags endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Product Tags controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Tags_V2_Controller */ class WC_REST_Product_Tags_Controller extends WC_REST_Product_Tags_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-product-variations-controller.php b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php index 5b69656b0ab..65cc4f11520 100644 --- a/src/Controllers/Version3/class-wc-rest-product-variations-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /products//variations endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API variations controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Product_Variations_V2_Controller */ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-products-controller.php b/src/Controllers/Version3/class-wc-rest-products-controller.php index 95c32c4b238..de21777ca9b 100644 --- a/src/Controllers/Version3/class-wc-rest-products-controller.php +++ b/src/Controllers/Version3/class-wc-rest-products-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /products endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Products controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Products_V2_Controller */ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php index d999b349703..b6bfe4304b3 100644 --- a/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/coupons/count endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Coupons Totals controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Coupons_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php index c32b170e2db..929a2f3c73a 100644 --- a/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/customers/count endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Customers Totals controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Customers_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php index 3fdc4619351..f70ebe6a5a4 100644 --- a/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/orders/count endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Orders Totals controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Orders_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php index adb42b0d276..c45671c50d9 100644 --- a/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/products/count endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Products Totals controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Products_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php index ef7ce098baa..c7b5cf2249a 100644 --- a/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /reports/reviews/count endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.5.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports Reviews Totals controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Reports_Controller */ class WC_REST_Report_Reviews_Totals_Controller extends WC_REST_Reports_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-report-sales-controller.php b/src/Controllers/Version3/class-wc-rest-report-sales-controller.php index 4712c333394..bde4bd0ae51 100644 --- a/src/Controllers/Version3/class-wc-rest-report-sales-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-sales-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports/sales endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Report Sales controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Report_Sales_V2_Controller */ class WC_REST_Report_Sales_Controller extends WC_REST_Report_Sales_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php b/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php index 1b7a3044cec..79548393fc3 100644 --- a/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports/top_sellers endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Report Top Sellers controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Report_Top_Sellers_V2_Controller */ class WC_REST_Report_Top_Sellers_Controller extends WC_REST_Report_Top_Sellers_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-reports-controller.php b/src/Controllers/Version3/class-wc-rest-reports-controller.php index b99d2c3c059..67a37e697da 100644 --- a/src/Controllers/Version3/class-wc-rest-reports-controller.php +++ b/src/Controllers/Version3/class-wc-rest-reports-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the reports endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Reports controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Reports_V2_Controller */ class WC_REST_Reports_Controller extends WC_REST_Reports_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-setting-options-controller.php b/src/Controllers/Version3/class-wc-rest-setting-options-controller.php index 41ae7ae86f7..a09e1fb5d72 100644 --- a/src/Controllers/Version3/class-wc-rest-setting-options-controller.php +++ b/src/Controllers/Version3/class-wc-rest-setting-options-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /settings/$group/$setting endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Setting Options controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Setting_Options_V2_Controller */ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-settings-controller.php b/src/Controllers/Version3/class-wc-rest-settings-controller.php index 869f725144f..77aebd681d4 100644 --- a/src/Controllers/Version3/class-wc-rest-settings-controller.php +++ b/src/Controllers/Version3/class-wc-rest-settings-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /settings endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Settings controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Settings_V2_Controller */ class WC_REST_Settings_Controller extends WC_REST_Settings_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php index ca3c36d607c..297943ae544 100644 --- a/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php +++ b/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping_methods endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * Shipping methods controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Shipping_Methods_V2_Controller */ class WC_REST_Shipping_Methods_Controller extends WC_REST_Shipping_Methods_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php index 6211eccd561..48f0ed0b0d6 100644 --- a/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php +++ b/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones//locations endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Locations class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Shipping_Zone_Locations_V2_Controller */ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zone_Locations_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php index 3ed5cf4e08b..efb56f49afd 100644 --- a/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php +++ b/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones//methods endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zone Methods class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Shipping_Zone_Methods_V2_Controller */ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zone_Methods_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php index 7b8cc282f3b..871c5199e31 100644 --- a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php +++ b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php @@ -4,7 +4,7 @@ * * Houses common functionality between Shipping Zones and Locations. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Shipping Zones base class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Controller */ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php index 778861bff5c..881d18dc3c1 100644 --- a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php +++ b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /shipping/zones endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zones class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Shipping_Zones_V2_Controller */ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-system-status-controller.php b/src/Controllers/Version3/class-wc-rest-system-status-controller.php index 71a1ce085e4..3c9ab9f2510 100644 --- a/src/Controllers/Version3/class-wc-rest-system-status-controller.php +++ b/src/Controllers/Version3/class-wc-rest-system-status-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /system_status endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * System status controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_System_Status_V2_Controller */ class WC_REST_System_Status_Controller extends WC_REST_System_Status_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php b/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php index 7e8e452f875..02e0efdd76c 100644 --- a/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php +++ b/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /system_status/tools/* endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * System status tools controller. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_System_Status_Tools_V2_Controller */ class WC_REST_System_Status_Tools_Controller extends WC_REST_System_Status_Tools_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php b/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php index 2fff460b540..df052293e6f 100644 --- a/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php +++ b/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /taxes/classes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Tax Classes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Tax_Classes_V2_Controller */ class WC_REST_Tax_Classes_Controller extends WC_REST_Tax_Classes_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-taxes-controller.php b/src/Controllers/Version3/class-wc-rest-taxes-controller.php index 5b90905cfec..f95a84ab4bd 100644 --- a/src/Controllers/Version3/class-wc-rest-taxes-controller.php +++ b/src/Controllers/Version3/class-wc-rest-taxes-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /taxes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Taxes controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Taxes_V2_Controller */ class WC_REST_Taxes_Controller extends WC_REST_Taxes_V2_Controller { diff --git a/src/Controllers/Version3/class-wc-rest-terms-controller.php b/src/Controllers/Version3/class-wc-rest-terms-controller.php index d9588099149..2422f99b286 100644 --- a/src/Controllers/Version3/class-wc-rest-terms-controller.php +++ b/src/Controllers/Version3/class-wc-rest-terms-controller.php @@ -2,7 +2,7 @@ /** * Abstract Rest Terms Controller * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @version 3.3.0 */ diff --git a/src/Controllers/Version3/class-wc-rest-webhooks-controller.php b/src/Controllers/Version3/class-wc-rest-webhooks-controller.php index 77aebc5059f..7b2817290fa 100644 --- a/src/Controllers/Version3/class-wc-rest-webhooks-controller.php +++ b/src/Controllers/Version3/class-wc-rest-webhooks-controller.php @@ -4,7 +4,7 @@ * * Handles requests to the /webhooks endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 2.6.0 */ @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API Webhooks controller class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WC_REST_Webhooks_V2_Controller */ class WC_REST_Webhooks_Controller extends WC_REST_Webhooks_V2_Controller { diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index eedc9116f41..e28d3d27729 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -7,21 +7,21 @@ * * @class \WC_REST_Controller * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; use \WP_REST_Controller; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\BatchTrait; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\BatchTrait; /** * Abstract Rest Controller Class * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends WP_REST_Controller * @version 2.6.0 */ diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index 21cec24457d..ddc32658270 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -2,15 +2,15 @@ /** * Abstract Rest CRUD Controller Class * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * CRUD Object Controller. diff --git a/src/Controllers/Version4/AbstractShippingZonesController.php b/src/Controllers/Version4/AbstractShippingZonesController.php index 42db4365326..0a3a6809ba3 100644 --- a/src/Controllers/Version4/AbstractShippingZonesController.php +++ b/src/Controllers/Version4/AbstractShippingZonesController.php @@ -4,18 +4,18 @@ * * Houses common functionality between Shipping Zones and Locations. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @since 3.0.0 */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; /** * REST API Shipping Zones base class. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi * @extends AbstractController */ abstract class AbstractShippingZonesController extends AbstractController { diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index f86b7886eae..2cb1366a42c 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -2,15 +2,15 @@ /** * Abstract Rest Terms Controller * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * Terms controller class. diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index a0af8e104b8..bbca5237287 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -4,10 +4,10 @@ * * Handles requests to the /coupons endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index 49716832190..6504eb9967d 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -4,14 +4,14 @@ * * Handles requests to the /customers//downloads endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; /** * REST API Customer Downloads controller class. diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index fc7c8af0cd5..d931c1b05f5 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -4,17 +4,17 @@ * * Handles requests to the /customers endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; use \WP_REST_Server; -use WooCommerce\RestApi\Controllers\Version4\Requests\CustomerRequest; -use WooCommerce\RestApi\Controllers\Version4\Responses\CustomerResponse; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Requests\CustomerRequest; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Responses\CustomerResponse; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * REST API Customers controller class. diff --git a/src/Controllers/Version4/Data.php b/src/Controllers/Version4/Data.php index d34bf73736c..a2fb405b9ee 100644 --- a/src/Controllers/Version4/Data.php +++ b/src/Controllers/Version4/Data.php @@ -4,10 +4,10 @@ * * Handles requests to the /data endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php index 3341425033e..07271be8432 100644 --- a/src/Controllers/Version4/Data/Continents.php +++ b/src/Controllers/Version4/Data/Continents.php @@ -4,14 +4,14 @@ * * Handles requests to the /data/continents endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Data; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Data; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Data as DataController; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Data as DataController; /** * REST API Data Continents controller class. diff --git a/src/Controllers/Version4/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php index 13136317950..bfa28bc79e3 100644 --- a/src/Controllers/Version4/Data/Countries.php +++ b/src/Controllers/Version4/Data/Countries.php @@ -4,14 +4,14 @@ * * Handles requests to the /data/countries endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Data; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Data; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Data as DataController; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Data as DataController; /** * REST API Data Countries controller class. diff --git a/src/Controllers/Version4/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php index de52a531b24..98d6e39139c 100644 --- a/src/Controllers/Version4/Data/Currencies.php +++ b/src/Controllers/Version4/Data/Currencies.php @@ -4,14 +4,14 @@ * * Handles requests to the /data/currencies endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Data; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Data; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Data as DataController; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Data as DataController; /** * REST API Data Currencies controller class. diff --git a/src/Controllers/Version4/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php index 47d4cbdc97d..5d62d801926 100644 --- a/src/Controllers/Version4/Data/DownloadIPs.php +++ b/src/Controllers/Version4/Data/DownloadIPs.php @@ -4,14 +4,14 @@ * * Handles requests to /data/download-ips * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Data; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Data; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Data as DataController; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Data as DataController; /** * Data Download IP controller. diff --git a/src/Controllers/Version4/NetworkOrders.php b/src/Controllers/Version4/NetworkOrders.php index 2db3d53916c..7fafab5b3bd 100644 --- a/src/Controllers/Version4/NetworkOrders.php +++ b/src/Controllers/Version4/NetworkOrders.php @@ -4,10 +4,10 @@ * * Handles requests to the /orders/network endpoint * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index 551ee43c02b..c2935e728d0 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -4,14 +4,14 @@ * * Handles requests to the /orders//notes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; /** * REST API Order Notes controller class. diff --git a/src/Controllers/Version4/OrderRefunds.php b/src/Controllers/Version4/OrderRefunds.php index f8869581159..ff50b60c939 100644 --- a/src/Controllers/Version4/OrderRefunds.php +++ b/src/Controllers/Version4/OrderRefunds.php @@ -4,10 +4,10 @@ * * Handles requests to the /orders//refunds endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index e45b26b6df5..dfd16519546 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -4,15 +4,15 @@ * * Handles requests to the /orders endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Requests\OrderRequest; -use WooCommerce\RestApi\Controllers\Version4\Responses\OrderResponse; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Requests\OrderRequest; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Responses\OrderResponse; /** * REST API Orders controller class. diff --git a/src/Controllers/Version4/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php index 8c1df3c60b4..0304d8dfd1f 100644 --- a/src/Controllers/Version4/PaymentGateways.php +++ b/src/Controllers/Version4/PaymentGateways.php @@ -4,14 +4,14 @@ * * Handles requests to the /payment_gateways endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; /** * Payment gateways controller class. diff --git a/src/Controllers/Version4/ProductAttributeTerms.php b/src/Controllers/Version4/ProductAttributeTerms.php index 18ed0d19edb..1ba1d73bd63 100644 --- a/src/Controllers/Version4/ProductAttributeTerms.php +++ b/src/Controllers/Version4/ProductAttributeTerms.php @@ -4,10 +4,10 @@ * * Handles requests to the products/attributes//terms endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php index 8ddb0af6317..b2176689ac7 100644 --- a/src/Controllers/Version4/ProductAttributes.php +++ b/src/Controllers/Version4/ProductAttributes.php @@ -4,10 +4,10 @@ * * Handles requests to the products/attributes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/ProductCategories.php b/src/Controllers/Version4/ProductCategories.php index ba8e27a02cc..5ad40a1eb28 100644 --- a/src/Controllers/Version4/ProductCategories.php +++ b/src/Controllers/Version4/ProductCategories.php @@ -4,10 +4,10 @@ * * Handles requests to the products/categories endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index 2b6922f330d..7c307aa80e3 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -4,16 +4,16 @@ * * Handles requests to /products//reviews. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Responses\ProductReviewResponse; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Responses\ProductReviewResponse; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * REST API Product Reviews controller class. diff --git a/src/Controllers/Version4/ProductShippingClasses.php b/src/Controllers/Version4/ProductShippingClasses.php index 4c55791ed50..3353034f847 100644 --- a/src/Controllers/Version4/ProductShippingClasses.php +++ b/src/Controllers/Version4/ProductShippingClasses.php @@ -4,10 +4,10 @@ * * Handles requests to the products/shipping_classes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/ProductTags.php b/src/Controllers/Version4/ProductTags.php index 5c3b5f01826..edc0c7610a6 100644 --- a/src/Controllers/Version4/ProductTags.php +++ b/src/Controllers/Version4/ProductTags.php @@ -4,10 +4,10 @@ * * Handles requests to the products/tags endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index 8243fdc973d..bdcb73b4573 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -4,16 +4,16 @@ * * Handles requests to the /products//variations endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Requests\ProductVariationRequest; -use WooCommerce\RestApi\Controllers\Version4\Responses\ProductVariationResponse; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Requests\ProductVariationRequest; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Responses\ProductVariationResponse; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; /** * REST API variations controller class. diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index c6e20340e88..888250eb535 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -4,16 +4,16 @@ * * Handles requests to the /products endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Requests\ProductRequest; -use WooCommerce\RestApi\Controllers\Version4\Responses\ProductResponse; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Requests\ProductRequest; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Responses\ProductResponse; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; /** * REST API Products controller class. diff --git a/src/Controllers/Version4/Requests/AbstractObjectRequest.php b/src/Controllers/Version4/Requests/AbstractObjectRequest.php index f3d6b984ebb..660040e8a87 100644 --- a/src/Controllers/Version4/Requests/AbstractObjectRequest.php +++ b/src/Controllers/Version4/Requests/AbstractObjectRequest.php @@ -2,10 +2,10 @@ /** * Convert data in the product schema format to an object. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Requests; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Requests/CustomerRequest.php b/src/Controllers/Version4/Requests/CustomerRequest.php index 5bbde2bef1a..f852f39669e 100644 --- a/src/Controllers/Version4/Requests/CustomerRequest.php +++ b/src/Controllers/Version4/Requests/CustomerRequest.php @@ -2,10 +2,10 @@ /** * Convert data in the customer schema format to a product object. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Requests; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Requests/OrderRequest.php b/src/Controllers/Version4/Requests/OrderRequest.php index 4eefbea6c08..6a8af0b97ca 100644 --- a/src/Controllers/Version4/Requests/OrderRequest.php +++ b/src/Controllers/Version4/Requests/OrderRequest.php @@ -2,10 +2,10 @@ /** * Convert data in the order schema format to a product object. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Requests; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Requests/ProductRequest.php b/src/Controllers/Version4/Requests/ProductRequest.php index 892055cd680..2593e4c4253 100644 --- a/src/Controllers/Version4/Requests/ProductRequest.php +++ b/src/Controllers/Version4/Requests/ProductRequest.php @@ -2,14 +2,14 @@ /** * Convert data in the product schema format to a product object. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Requests; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Utilities\ImageAttachment; +use Automattic\WooCommerce\RestApi\Utilities\ImageAttachment; /** * ProductRequest class. diff --git a/src/Controllers/Version4/Requests/ProductVariationRequest.php b/src/Controllers/Version4/Requests/ProductVariationRequest.php index 75d5b9922e1..76608c5d412 100644 --- a/src/Controllers/Version4/Requests/ProductVariationRequest.php +++ b/src/Controllers/Version4/Requests/ProductVariationRequest.php @@ -2,14 +2,14 @@ /** * Convert data in the product schema format to a product object. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Requests; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Requests; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Utilities\ImageAttachment; +use Automattic\WooCommerce\RestApi\Utilities\ImageAttachment; /** * ProductVariationRequest class. diff --git a/src/Controllers/Version4/Responses/AbstractObjectResponse.php b/src/Controllers/Version4/Responses/AbstractObjectResponse.php index 174a16ab833..e92882f7682 100644 --- a/src/Controllers/Version4/Responses/AbstractObjectResponse.php +++ b/src/Controllers/Version4/Responses/AbstractObjectResponse.php @@ -2,10 +2,10 @@ /** * Convert an object to the product schema format. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Responses; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Responses/CustomerResponse.php b/src/Controllers/Version4/Responses/CustomerResponse.php index 851139fdab8..3816b72c76d 100644 --- a/src/Controllers/Version4/Responses/CustomerResponse.php +++ b/src/Controllers/Version4/Responses/CustomerResponse.php @@ -2,10 +2,10 @@ /** * Convert a customer object to the product schema format. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Responses; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Responses/OrderResponse.php b/src/Controllers/Version4/Responses/OrderResponse.php index 83dadbd2238..8ccdbf4fbf9 100644 --- a/src/Controllers/Version4/Responses/OrderResponse.php +++ b/src/Controllers/Version4/Responses/OrderResponse.php @@ -2,10 +2,10 @@ /** * Convert an order object to the order schema format. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Responses; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Responses/ProductResponse.php b/src/Controllers/Version4/Responses/ProductResponse.php index cb8dd981d75..fc6839387a8 100644 --- a/src/Controllers/Version4/Responses/ProductResponse.php +++ b/src/Controllers/Version4/Responses/ProductResponse.php @@ -2,10 +2,10 @@ /** * Convert a product object to the product schema format. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Responses; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Responses/ProductReviewResponse.php b/src/Controllers/Version4/Responses/ProductReviewResponse.php index e07094827c4..63ba58e8761 100644 --- a/src/Controllers/Version4/Responses/ProductReviewResponse.php +++ b/src/Controllers/Version4/Responses/ProductReviewResponse.php @@ -2,10 +2,10 @@ /** * Convert a review to the schema format. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Responses; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Responses/ProductVariationResponse.php b/src/Controllers/Version4/Responses/ProductVariationResponse.php index 744f63dcbcc..63a96c5dd3d 100644 --- a/src/Controllers/Version4/Responses/ProductVariationResponse.php +++ b/src/Controllers/Version4/Responses/ProductVariationResponse.php @@ -2,10 +2,10 @@ /** * Convert a product variation object to the product variation schema format. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Responses; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Responses; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index c32e924c526..de2cd12bc69 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -4,10 +4,10 @@ * * Handles requests to the /settings endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index 94d57ccce94..7529ccb6580 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -4,14 +4,14 @@ * * Handles requests to the /settings/$group/$setting endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; /** * REST API Setting Options controller class. diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php index 9176f01bbab..229e9db0f8d 100644 --- a/src/Controllers/Version4/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -4,10 +4,10 @@ * * Handles requests to the /shipping_methods endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/ShippingZoneLocations.php b/src/Controllers/Version4/ShippingZoneLocations.php index f9c2a96d09c..1171b90e559 100644 --- a/src/Controllers/Version4/ShippingZoneLocations.php +++ b/src/Controllers/Version4/ShippingZoneLocations.php @@ -4,10 +4,10 @@ * * Handles requests to the /shipping/zones//locations endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php index 19ab78a9f47..d252ab17ef3 100644 --- a/src/Controllers/Version4/ShippingZoneMethods.php +++ b/src/Controllers/Version4/ShippingZoneMethods.php @@ -4,14 +4,14 @@ * * Handles requests to the /shipping/zones//methods endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; /** * REST API Shipping Zone Methods class. diff --git a/src/Controllers/Version4/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php index 8590336378a..af9da032b05 100644 --- a/src/Controllers/Version4/ShippingZones.php +++ b/src/Controllers/Version4/ShippingZones.php @@ -4,10 +4,10 @@ * * Handles requests to the /shipping/zones endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index 946d2c2fe3b..36239c6b7f6 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -4,10 +4,10 @@ * * Handles requests to the /system_status endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; @@ -554,12 +554,12 @@ class SystemStatus extends AbstractController { * @return array */ public function get_item_mappings() { - $plugin_info = new \WooCommerce\RestApi\Controllers\Version4\Utilities\PluginInformation(); - $theme_info = new \WooCommerce\RestApi\Controllers\Version4\Utilities\ThemeInformation(); - $server = new \WooCommerce\RestApi\Controllers\Version4\Utilities\ServerEnvironment(); - $database = new \WooCommerce\RestApi\Controllers\Version4\Utilities\DatabaseInformation(); - $wp_environment = new \WooCommerce\RestApi\Controllers\Version4\Utilities\WPEnvironment(); - $woo_environment = new \WooCommerce\RestApi\Controllers\Version4\Utilities\WooEnvironment(); + $plugin_info = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\PluginInformation(); + $theme_info = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\ThemeInformation(); + $server = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\ServerEnvironment(); + $database = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\DatabaseInformation(); + $wp_environment = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\WPEnvironment(); + $woo_environment = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\WooEnvironment(); return array( 'environment' => $server->get_environment_info(), diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php index 4c7a932de37..e6aaa94d0d9 100644 --- a/src/Controllers/Version4/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -4,10 +4,10 @@ * * Handles requests to the /system_status/tools/* endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/TaxClasses.php b/src/Controllers/Version4/TaxClasses.php index 460bfc6db79..2c60d447aa1 100644 --- a/src/Controllers/Version4/TaxClasses.php +++ b/src/Controllers/Version4/TaxClasses.php @@ -4,10 +4,10 @@ * * Handles requests to the /taxes/classes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php index 2fb84276569..e7ee48b7a7d 100644 --- a/src/Controllers/Version4/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -4,14 +4,14 @@ * * Handles requests to the /taxes endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * REST API Taxes controller class. diff --git a/src/Controllers/Version4/Utilities/BatchTrait.php b/src/Controllers/Version4/Utilities/BatchTrait.php index 19ae18315ab..f35f7eba96e 100644 --- a/src/Controllers/Version4/Utilities/BatchTrait.php +++ b/src/Controllers/Version4/Utilities/BatchTrait.php @@ -2,10 +2,10 @@ /** * Batch trait. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; /** * BatchTrait. diff --git a/src/Controllers/Version4/Utilities/DatabaseInformation.php b/src/Controllers/Version4/Utilities/DatabaseInformation.php index ce9dd3ff1a9..be946dc9e9e 100644 --- a/src/Controllers/Version4/Utilities/DatabaseInformation.php +++ b/src/Controllers/Version4/Utilities/DatabaseInformation.php @@ -2,10 +2,10 @@ /** * Database information for status report. * - * @package WooCommerce/Utilities + * @package Automattic/WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; /** * DatabaseInformation class. diff --git a/src/Controllers/Version4/Utilities/Pagination.php b/src/Controllers/Version4/Utilities/Pagination.php index 71b31eb19f1..68336424fa6 100644 --- a/src/Controllers/Version4/Utilities/Pagination.php +++ b/src/Controllers/Version4/Utilities/Pagination.php @@ -4,10 +4,10 @@ * * Handles permission checks for endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Utilities/Permissions.php b/src/Controllers/Version4/Utilities/Permissions.php index eaa19400b78..cb42a1150d8 100644 --- a/src/Controllers/Version4/Utilities/Permissions.php +++ b/src/Controllers/Version4/Utilities/Permissions.php @@ -4,10 +4,10 @@ * * Handles permission checks for endpoints. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; defined( 'ABSPATH' ) || exit; diff --git a/src/Controllers/Version4/Utilities/PluginInformation.php b/src/Controllers/Version4/Utilities/PluginInformation.php index 5cb411f2e35..ee7645b63d7 100644 --- a/src/Controllers/Version4/Utilities/PluginInformation.php +++ b/src/Controllers/Version4/Utilities/PluginInformation.php @@ -2,10 +2,10 @@ /** * Plugin information for status report. * - * @package WooCommerce/Utilities + * @package Automattic/WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; /** * PluginInformation class. diff --git a/src/Controllers/Version4/Utilities/ServerEnvironment.php b/src/Controllers/Version4/Utilities/ServerEnvironment.php index ef22222f442..1c7612a3bac 100644 --- a/src/Controllers/Version4/Utilities/ServerEnvironment.php +++ b/src/Controllers/Version4/Utilities/ServerEnvironment.php @@ -2,10 +2,10 @@ /** * Server information for status report. * - * @package WooCommerce/Utilities + * @package Automattic/WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; /** * ServerEnvironment class. diff --git a/src/Controllers/Version4/Utilities/SettingsTrait.php b/src/Controllers/Version4/Utilities/SettingsTrait.php index 5fed3faf7d3..68c04657177 100644 --- a/src/Controllers/Version4/Utilities/SettingsTrait.php +++ b/src/Controllers/Version4/Utilities/SettingsTrait.php @@ -2,10 +2,10 @@ /** * Settings trait. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; /** * SettingsTrait. diff --git a/src/Controllers/Version4/Utilities/ThemeInformation.php b/src/Controllers/Version4/Utilities/ThemeInformation.php index 45d6ac68072..fb99a3a48aa 100644 --- a/src/Controllers/Version4/Utilities/ThemeInformation.php +++ b/src/Controllers/Version4/Utilities/ThemeInformation.php @@ -2,10 +2,10 @@ /** * Theme information for status report. * - * @package WooCommerce/Utilities + * @package Automattic/WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; /** * ThemeInformation class. diff --git a/src/Controllers/Version4/Utilities/WPEnvironment.php b/src/Controllers/Version4/Utilities/WPEnvironment.php index ad29dd08396..5ebc5acb6d6 100644 --- a/src/Controllers/Version4/Utilities/WPEnvironment.php +++ b/src/Controllers/Version4/Utilities/WPEnvironment.php @@ -2,10 +2,10 @@ /** * WP information for status report. * - * @package WooCommerce/Utilities + * @package Automattic/WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; /** * WPEnvironment class. diff --git a/src/Controllers/Version4/Utilities/WooEnvironment.php b/src/Controllers/Version4/Utilities/WooEnvironment.php index 28a7e4fbaa1..c85fc24efc8 100644 --- a/src/Controllers/Version4/Utilities/WooEnvironment.php +++ b/src/Controllers/Version4/Utilities/WooEnvironment.php @@ -2,10 +2,10 @@ /** * WC information for status report. * - * @package WooCommerce/Utilities + * @package Automattic/WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Controllers\Version4\Utilities; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities; /** * WooEnvironment class. diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index 58cc4374dbd..17c1e911059 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -4,14 +4,14 @@ * * Handles requests to the /webhooks endpoint. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\Controllers\Version4; +namespace Automattic\WooCommerce\RestApi\Controllers\Version4; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; +use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; /** * REST API Webhooks controller class. diff --git a/src/Server.php b/src/Server.php index 68adf5e9681..f025003aba4 100644 --- a/src/Server.php +++ b/src/Server.php @@ -2,14 +2,14 @@ /** * Initialize this version of the REST API. * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi; +namespace Automattic\WooCommerce\RestApi; defined( 'ABSPATH' ) || exit; -use WooCommerce\RestApi\Utilities\SingletonTrait; +use Automattic\WooCommerce\RestApi\Utilities\SingletonTrait; /** * Class responsible for loading the REST API and all REST API namespaces. diff --git a/src/Utilities/ImageAttachment.php b/src/Utilities/ImageAttachment.php index 8abba23ab1c..a9fab68b8c7 100644 --- a/src/Utilities/ImageAttachment.php +++ b/src/Utilities/ImageAttachment.php @@ -2,10 +2,10 @@ /** * Helper to upload files via the REST API. * - * @package WooCommerce/Utilities + * @package Automattic/WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Utilities; +namespace Automattic\WooCommerce\RestApi\Utilities; /** * ImageAttachment class. diff --git a/src/Utilities/SingletonTrait.php b/src/Utilities/SingletonTrait.php index 01ff37960c8..37aef2e35c7 100644 --- a/src/Utilities/SingletonTrait.php +++ b/src/Utilities/SingletonTrait.php @@ -2,10 +2,10 @@ /** * Singleton class trait. * - * @package WooCommerce/Utilities + * @package Automattic/WooCommerce/Utilities */ -namespace WooCommerce\RestApi\Utilities; +namespace Automattic\WooCommerce\RestApi\Utilities; /** * Singleton trait. diff --git a/unit-tests/AbstractRestApiTest.php b/unit-tests/AbstractRestApiTest.php index bbf767f0136..3646b4681ff 100644 --- a/unit-tests/AbstractRestApiTest.php +++ b/unit-tests/AbstractRestApiTest.php @@ -14,17 +14,17 @@ * - Routes * - Collection params/queries * - * @package WooCommerce/RestApi/Tests + * @package Automattic/WooCommerce/RestApi/Tests */ -namespace WooCommerce\RestApi\UnitTests; +namespace Automattic\WooCommerce\RestApi\UnitTests; defined( 'ABSPATH' ) || exit; use \WC_REST_Unit_Test_Case; -use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; /** * Abstract Rest API Test Class diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index 11290cb1797..4988801e59d 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -2,13 +2,13 @@ /** * PHPUnit bootstrap file * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ -namespace WooCommerce\RestApi\UnitTests; +namespace Automattic\WooCommerce\RestApi\UnitTests; require __DIR__ . '/../src/Utilities/SingletonTrait.php'; -use WooCommerce\RestApi\Utilities\SingletonTrait; +use Automattic\WooCommerce\RestApi\Utilities\SingletonTrait; class Bootstrap { use SingletonTrait; diff --git a/unit-tests/Helpers/AdminNotesHelper.php b/unit-tests/Helpers/AdminNotesHelper.php index 87bdcd83fe6..de1c6c9da13 100644 --- a/unit-tests/Helpers/AdminNotesHelper.php +++ b/unit-tests/Helpers/AdminNotesHelper.php @@ -5,7 +5,7 @@ * @package WooCommerce\Tests\Framework\Helpers */ -namespace WooCommerce\RestApi\UnitTests\Helpers; +namespace Automattic\WooCommerce\RestApi\UnitTests\Helpers; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Helpers/CouponHelper.php b/unit-tests/Helpers/CouponHelper.php index 1ca863d1ca7..2b65987bff5 100644 --- a/unit-tests/Helpers/CouponHelper.php +++ b/unit-tests/Helpers/CouponHelper.php @@ -5,7 +5,7 @@ * This helper class should ONLY be used for unit tests!. */ -namespace WooCommerce\RestApi\UnitTests\Helpers; +namespace Automattic\WooCommerce\RestApi\UnitTests\Helpers; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Helpers/CustomerHelper.php b/unit-tests/Helpers/CustomerHelper.php index 3cf4f2ca1e5..5751cf31f32 100644 --- a/unit-tests/Helpers/CustomerHelper.php +++ b/unit-tests/Helpers/CustomerHelper.php @@ -3,7 +3,7 @@ * Customer helper. */ -namespace WooCommerce\RestApi\UnitTests\Helpers; +namespace Automattic\WooCommerce\RestApi\UnitTests\Helpers; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Helpers/OrderHelper.php b/unit-tests/Helpers/OrderHelper.php index 06c3f0c2663..c52d7cf3ce4 100644 --- a/unit-tests/Helpers/OrderHelper.php +++ b/unit-tests/Helpers/OrderHelper.php @@ -3,7 +3,7 @@ * Orders helper. */ -namespace WooCommerce\RestApi\UnitTests\Helpers; +namespace Automattic\WooCommerce\RestApi\UnitTests\Helpers; defined( 'ABSPATH' ) || exit; @@ -53,7 +53,7 @@ class OrderHelper { public static function create_order( $customer_id = 1, $product = null ) { if ( ! is_a( $product, 'WC_Product' ) ) { - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); } ShippingHelper::create_simple_flat_rate(); diff --git a/unit-tests/Helpers/ProductHelper.php b/unit-tests/Helpers/ProductHelper.php index 187cf4c7db6..5c7fffa4dd8 100644 --- a/unit-tests/Helpers/ProductHelper.php +++ b/unit-tests/Helpers/ProductHelper.php @@ -3,7 +3,7 @@ * Product helpers. */ -namespace WooCommerce\RestApi\UnitTests\Helpers; +namespace Automattic\WooCommerce\RestApi\UnitTests\Helpers; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Helpers/QueueHelper.php b/unit-tests/Helpers/QueueHelper.php index 31225a8edc3..b0afec4c6fd 100644 --- a/unit-tests/Helpers/QueueHelper.php +++ b/unit-tests/Helpers/QueueHelper.php @@ -5,7 +5,7 @@ * @package WooCommerce\Tests\Framework\Helpers */ -namespace WooCommerce\RestApi\UnitTests\Helpers; +namespace Automattic\WooCommerce\RestApi\UnitTests\Helpers; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Helpers/SettingsHelper.php b/unit-tests/Helpers/SettingsHelper.php index 928c69faa2a..d7a8efd979d 100644 --- a/unit-tests/Helpers/SettingsHelper.php +++ b/unit-tests/Helpers/SettingsHelper.php @@ -3,7 +3,7 @@ * Settings helper. */ -namespace WooCommerce\RestApi\UnitTests\Helpers; +namespace Automattic\WooCommerce\RestApi\UnitTests\Helpers; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Helpers/ShippingHelper.php b/unit-tests/Helpers/ShippingHelper.php index 8d8a2d03c6e..04d17e4274c 100644 --- a/unit-tests/Helpers/ShippingHelper.php +++ b/unit-tests/Helpers/ShippingHelper.php @@ -3,7 +3,7 @@ * Shipping helper. */ -namespace WooCommerce\RestApi\UnitTests\Helpers; +namespace Automattic\WooCommerce\RestApi\UnitTests\Helpers; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Tests/Version2/coupons.php b/unit-tests/Tests/Version2/coupons.php index 1be88f1ee4e..8c4d6024d70 100644 --- a/unit-tests/Tests/Version2/coupons.php +++ b/unit-tests/Tests/Version2/coupons.php @@ -40,9 +40,9 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { public function test_get_coupons() { wp_set_current_user( $this->user ); - $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post_1 = get_post( $coupon_1->get_id() ); - $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); + $coupon_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons' ) ); $coupons = $response->get_data(); @@ -111,7 +111,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_coupon() { wp_set_current_user( $this->user ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); $data = $response->get_data(); @@ -167,7 +167,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -275,7 +275,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_coupon() { wp_set_current_user( $this->user ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); @@ -326,7 +326,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v2/coupons/' . $coupon->get_id() ); @@ -347,7 +347,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_coupon() { wp_set_current_user( $this->user ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/' . $coupon->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -373,7 +373,7 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/' . $coupon->get_id() ); $response = $this->server->dispatch( $request ); @@ -387,10 +387,10 @@ class WC_Tests_API_Coupons_V2 extends WC_REST_Unit_Test_Case { public function test_batch_coupon() { wp_set_current_user( $this->user ); - $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); - $coupon_3 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-3' ); - $coupon_4 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-4' ); + $coupon_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); + $coupon_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-3' ); + $coupon_4 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-4' ); $request = new WP_REST_Request( 'POST', '/wc/v2/coupons/batch' ); $request->set_body_params( diff --git a/unit-tests/Tests/Version2/customers.php b/unit-tests/Tests/Version2/customers.php index 054aadbb5fe..5135bf7c967 100644 --- a/unit-tests/Tests/Version2/customers.php +++ b/unit-tests/Tests/Version2/customers.php @@ -37,7 +37,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { public function test_get_customers() { wp_set_current_user( 1 ); - $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); + $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v2/customers' ); @@ -296,7 +296,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_customer() { wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -353,7 +353,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -376,7 +376,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_customer() { wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -404,7 +404,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -428,7 +428,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_customer() { wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -455,7 +455,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -470,10 +470,10 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { public function test_batch_customer() { wp_set_current_user( 1 ); - $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); - $customer_2 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); - $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); - $customer_4 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); + $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); + $customer_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); + $customer_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); + $customer_4 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); $request = new WP_REST_Request( 'POST', '/wc/v2/customers/batch' ); $request->set_body_params( diff --git a/unit-tests/Tests/Version2/orders.php b/unit-tests/Tests/Version2/orders.php index f8cd8d497c6..9a1d5422d15 100644 --- a/unit-tests/Tests/Version2/orders.php +++ b/unit-tests/Tests/Version2/orders.php @@ -46,7 +46,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { // Create 10 orders. for ( $i = 0; $i < 10; $i++ ) { - $this->orders[] = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); + $this->orders[] = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); } $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders' ) ); @@ -63,7 +63,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_items_without_permission() { wp_set_current_user( 0 ); - $this->orders[] = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $this->orders[] = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -74,7 +74,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_item() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order->add_meta_data( 'key', 'value' ); $order->add_meta_data( 'key2', 'value2' ); $order->save(); @@ -98,7 +98,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_item_without_permission() { wp_set_current_user( 0 ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $this->orders[] = $order; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $order->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); @@ -120,7 +120,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_item_refund_id() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $refund = wc_create_refund( array( 'order_id' => $order->get_id(), @@ -136,7 +136,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_order() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); $request->set_body_params( array( @@ -217,7 +217,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_update_order_payment_method_title_sanitize() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Test when creating order. $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); @@ -292,7 +292,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_order_invalid_fields() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // non-existent customer $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); @@ -351,7 +351,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); $request->set_body_params( array( @@ -378,7 +378,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order_remove_items() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $fee = new WC_Order_Item_Fee(); $fee->set_props( array( @@ -418,9 +418,9 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order_add_coupons() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); @@ -457,9 +457,9 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order_remove_coupons() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); @@ -504,7 +504,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_order_without_permission() { wp_set_current_user( 0 ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); $request->set_body_params( array( @@ -545,7 +545,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_order() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/' . $order->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -559,7 +559,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_order_without_permission() { wp_set_current_user( 0 ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/' . $order->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -585,9 +585,9 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { public function test_orders_batch() { wp_set_current_user( $this->user ); - $order1 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order2 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order3 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'POST', '/wc/v2/orders/batch' ); $request->set_body_params( @@ -623,7 +623,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { */ public function test_order_schema() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/orders/' . $order->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version2/product-reviews.php b/unit-tests/Tests/Version2/product-reviews.php index 770a890beeb..57f8804c1c9 100644 --- a/unit-tests/Tests/Version2/product-reviews.php +++ b/unit-tests/Tests/Version2/product-reviews.php @@ -39,10 +39,10 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_reviews() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Create 10 products reviews for the product for ( $i = 0; $i < 10; $i++ ) { - $review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); } $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); @@ -92,7 +92,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_reviews_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -115,8 +115,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_review() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -147,8 +147,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_review_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -160,7 +160,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/0' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -172,7 +172,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_product_review() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); $request->set_body_params( array( @@ -212,7 +212,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_product_review_invalid_fields() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // missing review $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); @@ -261,8 +261,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_review() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -295,8 +295,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_review_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); $request->set_body_params( @@ -319,7 +319,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/0' ); $request->set_body_params( @@ -342,8 +342,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product_review() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); $request->set_param( 'force', true ); @@ -358,8 +358,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); $response = $this->server->dispatch( $request ); @@ -374,8 +374,8 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/0' ); $request->set_param( 'force', true ); @@ -389,12 +389,12 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_product_reviews_batch() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $review_1_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_2_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_3_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_4_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_1_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_2_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_3_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_4_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews/batch' ); $request->set_body_params( @@ -443,7 +443,7 @@ class WC_Tests_API_Product_Reviews_V2 extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/reviews' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version2/product-variations.php b/unit-tests/Tests/Version2/product-variations.php index b58e9076dd7..c936bd3e69d 100644 --- a/unit-tests/Tests/Version2/product-variations.php +++ b/unit-tests/Tests/Version2/product-variations.php @@ -40,7 +40,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_variations() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -56,7 +56,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_variations_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -68,7 +68,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_variation() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -87,7 +87,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ) ); @@ -101,7 +101,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_variation() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -122,7 +122,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -139,7 +139,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_with_invalid_id() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() . '/variations/0' ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -153,7 +153,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_variation() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -205,7 +205,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -226,7 +226,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_variation_with_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/0' ); $request->set_body_params( array( @@ -244,7 +244,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_variation() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); @@ -286,7 +286,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_create_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations' ); $request->set_body_params( @@ -311,7 +311,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_product_variations_batch() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations/batch' ); $request->set_body_params( @@ -367,7 +367,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_variation_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/products/' . $product->get_id() . '/variations' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -419,7 +419,7 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { public function test_update_variation_manage_stock() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $product->set_manage_stock( false ); $product->save(); diff --git a/unit-tests/Tests/Version2/products.php b/unit-tests/Tests/Version2/products.php index a6089fffa3a..4de979db12a 100644 --- a/unit-tests/Tests/Version2/products.php +++ b/unit-tests/Tests/Version2/products.php @@ -77,7 +77,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product() { wp_set_current_user( $this->user ); - $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $simple = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $simple->get_id() ) ); $product = $response->get_data(); @@ -102,7 +102,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -114,7 +114,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() ); $request->set_param( 'force', true ); @@ -133,7 +133,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -162,7 +162,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // test simple products. - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -198,7 +198,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { $product->delete( true ); // test variable product (variations are tested in product-variations.php). - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -240,7 +240,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { $product->delete( true ); // test external product. - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -268,7 +268,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); $request->set_body_params( array( @@ -286,7 +286,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_update_product_with_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' ); $request->set_body_params( array( @@ -419,8 +419,8 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_products_batch() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v2/products/batch' ); $request->set_body_params( array( @@ -477,7 +477,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { public function test_products_filter_post_status() { wp_set_current_user( $this->user ); for ( $i = 0; $i < 8; $i++ ) { - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); if ( 0 === $i % 2 ) { wp_update_post( array( @@ -525,7 +525,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_product_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/products/' . $product->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version2/settings.php b/unit-tests/Tests/Version2/settings.php index 52728d03461..777442dfff3 100644 --- a/unit-tests/Tests/Version2/settings.php +++ b/unit-tests/Tests/Version2/settings.php @@ -370,7 +370,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $controller ->expects( $this->any() ) ->method( 'get_group_settings' ) - ->will( $this->returnValue( \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); + ->will( $this->returnValue( \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); $controller ->expects( $this->any() ) diff --git a/unit-tests/Tests/Version2/system-status.php b/unit-tests/Tests/Version2/system-status.php index f9b5e471a16..dc66d1f2740 100644 --- a/unit-tests/Tests/Version2/system-status.php +++ b/unit-tests/Tests/Version2/system-status.php @@ -2,7 +2,7 @@ /** * Class WC_Tests_REST_System_Status file. * - * @package WooCommerce/Tests + * @package Automattic/WooCommerce/Tests */ /** diff --git a/unit-tests/Tests/Version3/coupons.php b/unit-tests/Tests/Version3/coupons.php index 027117ede7e..bd0564de6be 100644 --- a/unit-tests/Tests/Version3/coupons.php +++ b/unit-tests/Tests/Version3/coupons.php @@ -40,9 +40,9 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { public function test_get_coupons() { wp_set_current_user( $this->user ); - $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post_1 = get_post( $coupon_1->get_id() ); - $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); + $coupon_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons' ) ); $coupons = $response->get_data(); @@ -111,7 +111,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_get_coupon() { wp_set_current_user( $this->user ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); $data = $response->get_data(); @@ -167,7 +167,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_get_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -275,7 +275,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_update_coupon() { wp_set_current_user( $this->user ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); @@ -326,7 +326,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_update_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $post = get_post( $coupon->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v3/coupons/' . $coupon->get_id() ); @@ -347,7 +347,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_delete_coupon() { wp_set_current_user( $this->user ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/' . $coupon->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -373,7 +373,7 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { */ public function test_delete_coupon_without_permission() { wp_set_current_user( 0 ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/' . $coupon->get_id() ); $response = $this->server->dispatch( $request ); @@ -387,10 +387,10 @@ class WC_Tests_API_Coupons extends WC_REST_Unit_Test_Case { public function test_batch_coupon() { wp_set_current_user( $this->user ); - $coupon_1 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $coupon_2 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); - $coupon_3 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-3' ); - $coupon_4 = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-4' ); + $coupon_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); + $coupon_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); + $coupon_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-3' ); + $coupon_4 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-4' ); $request = new WP_REST_Request( 'POST', '/wc/v3/coupons/batch' ); $request->set_body_params( diff --git a/unit-tests/Tests/Version3/customers.php b/unit-tests/Tests/Version3/customers.php index 05ee7357d6f..bd997f5881f 100644 --- a/unit-tests/Tests/Version3/customers.php +++ b/unit-tests/Tests/Version3/customers.php @@ -43,7 +43,7 @@ class Customers extends WC_REST_Unit_Test_Case { public function test_get_customers() { wp_set_current_user( 1 ); - $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); + $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); @@ -115,7 +115,7 @@ class Customers extends WC_REST_Unit_Test_Case { ); update_option( 'timezone_tring', 'America/New York' ); - $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); + $customer_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); $request->set_query_params( @@ -368,7 +368,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_get_customer() { wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -423,7 +423,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_get_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -446,7 +446,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_update_customer() { wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); $data = $response->get_data(); @@ -474,7 +474,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_update_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -498,7 +498,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_delete_customer() { wp_set_current_user( 1 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -525,7 +525,7 @@ class Customers extends WC_REST_Unit_Test_Case { */ public function test_delete_customer_without_permission() { wp_set_current_user( 0 ); - $customer = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); + $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/' . $customer->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -540,10 +540,10 @@ class Customers extends WC_REST_Unit_Test_Case { public function test_batch_customer() { wp_set_current_user( 1 ); - $customer_1 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); - $customer_2 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); - $customer_3 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); - $customer_4 = \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); + $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); + $customer_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); + $customer_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); + $customer_4 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); $request = new WP_REST_Request( 'POST', '/wc/v3/customers/batch' ); $request->set_body_params( diff --git a/unit-tests/Tests/Version3/orders.php b/unit-tests/Tests/Version3/orders.php index 1e748674375..d537f68eb55 100644 --- a/unit-tests/Tests/Version3/orders.php +++ b/unit-tests/Tests/Version3/orders.php @@ -50,7 +50,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { // Create 10 orders. for ( $i = 0; $i < 10; $i++ ) { - $this->orders[] = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); + $this->orders[] = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); } $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders' ) ); @@ -67,7 +67,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_items_without_permission() { wp_set_current_user( 0 ); - $this->orders[] = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $this->orders[] = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -78,7 +78,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_item() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order->add_meta_data( 'key', 'value' ); $order->add_meta_data( 'key2', 'value2' ); $order->save(); @@ -102,7 +102,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_item_without_permission() { wp_set_current_user( 0 ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $this->orders[] = $order; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $order->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); @@ -124,7 +124,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_get_item_refund_id() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $refund = wc_create_refund( array( 'order_id' => $order->get_id(), @@ -140,7 +140,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_create_order() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); $request->set_body_params( array( @@ -221,7 +221,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_create_update_order_payment_method_title_sanitize() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Test when creating order. $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); @@ -296,7 +296,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_create_order_invalid_fields() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Non-existent customer. $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); @@ -355,7 +355,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_update_order() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); $request->set_body_params( array( @@ -382,7 +382,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_update_order_remove_items() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $fee = new WC_Order_Item_Fee(); $fee->set_props( array( @@ -423,9 +423,9 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { public function test_update_order_add_coupons() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); @@ -454,9 +454,9 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_update_order_remove_coupons() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); @@ -501,7 +501,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_invalid_coupon() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); $request->set_body_params( @@ -528,7 +528,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_update_order_without_permission() { wp_set_current_user( 0 ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); $request->set_body_params( array( @@ -571,7 +571,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_delete_order() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/' . $order->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -586,7 +586,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_delete_order_without_permission() { wp_set_current_user( 0 ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/' . $order->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -614,9 +614,9 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { public function test_orders_batch() { wp_set_current_user( $this->user ); - $order1 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order2 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order3 = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'POST', '/wc/v3/orders/batch' ); $request->set_body_params( @@ -653,7 +653,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { */ public function test_order_schema() { wp_set_current_user( $this->user ); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/orders/' . $order->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version3/product-reviews.php b/unit-tests/Tests/Version3/product-reviews.php index f99916fcce4..9a69f06a863 100644 --- a/unit-tests/Tests/Version3/product-reviews.php +++ b/unit-tests/Tests/Version3/product-reviews.php @@ -39,10 +39,10 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_reviews() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Create 10 products reviews for the product for ( $i = 0; $i < 10; $i++ ) { - $review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); } $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); @@ -92,7 +92,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_reviews_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -115,8 +115,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_review() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -147,8 +147,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_review_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -160,7 +160,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_get_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/0' ) ); $this->assertEquals( 404, $response->get_status() ); } @@ -172,7 +172,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_create_product_review() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); $request->set_body_params( array( @@ -212,7 +212,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_create_product_review_invalid_fields() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // missing review $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); @@ -261,8 +261,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_update_product_review() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); $data = $response->get_data(); @@ -295,8 +295,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_update_product_review_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); $request->set_body_params( @@ -319,7 +319,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_update_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/0' ); $request->set_body_params( @@ -342,8 +342,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_delete_product_review() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); $request->set_param( 'force', true ); @@ -358,8 +358,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); $response = $this->server->dispatch( $request ); @@ -374,8 +374,8 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_delete_product_review_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/0' ); $request->set_param( 'force', true ); @@ -391,12 +391,12 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_product_reviews_batch() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $review_1_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_2_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_3_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_4_id = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_1_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_2_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_3_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); + $review_4_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews/batch' ); $request->set_body_params( @@ -445,7 +445,7 @@ class WC_Tests_API_Product_Reviews extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/reviews' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version3/product-variations.php b/unit-tests/Tests/Version3/product-variations.php index b5afb865176..2539995dde0 100644 --- a/unit-tests/Tests/Version3/product-variations.php +++ b/unit-tests/Tests/Version3/product-variations.php @@ -40,7 +40,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_get_variations() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -56,7 +56,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_get_variations_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -68,7 +68,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_get_variation() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -87,7 +87,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_get_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ) ); @@ -101,7 +101,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_delete_variation() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -122,7 +122,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -139,7 +139,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_delete_variation_with_invalid_id() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() . '/variations/0' ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -153,7 +153,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_update_variation() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -205,7 +205,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_update_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $variation_id = $children[0]; @@ -226,7 +226,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_update_variation_with_invalid_id() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/0' ); $request->set_body_params( array( @@ -244,7 +244,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_create_variation() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); $variations = $response->get_data(); @@ -286,7 +286,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_create_variation_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations' ); $request->set_body_params( @@ -313,7 +313,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_product_variations_batch() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $children = $product->get_children(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations/batch' ); $request->set_body_params( @@ -369,7 +369,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { */ public function test_variation_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() . '/variations' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -420,7 +420,7 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { public function test_update_variation_manage_stock() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $product->set_manage_stock( false ); $product->save(); diff --git a/unit-tests/Tests/Version3/products.php b/unit-tests/Tests/Version3/products.php index 9ef37759cbb..aeb08700395 100644 --- a/unit-tests/Tests/Version3/products.php +++ b/unit-tests/Tests/Version3/products.php @@ -77,7 +77,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_get_product() { wp_set_current_user( $this->user ); - $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $simple = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $simple->get_id() ) ); $product = $response->get_data(); @@ -102,7 +102,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_get_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -114,7 +114,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_delete_product() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() ); $request->set_param( 'force', true ); @@ -133,7 +133,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_delete_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); @@ -162,7 +162,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // test simple products. - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); $data = $response->get_data(); $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); @@ -201,7 +201,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $product->delete( true ); // test variable product (variations are tested in product-variations.php). - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -247,7 +247,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $product->delete( true ); // test external product. - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); $data = $response->get_data(); @@ -275,7 +275,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_update_product_without_permission() { wp_set_current_user( 0 ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); $request->set_body_params( array( @@ -427,8 +427,8 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_products_batch() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'POST', '/wc/v3/products/batch' ); $request->set_body_params( array( @@ -485,7 +485,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { public function test_products_filter_post_status() { wp_set_current_user( $this->user ); for ( $i = 0; $i < 8; $i++ ) { - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); if ( 0 === $i % 2 ) { wp_update_post( array( @@ -533,7 +533,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_product_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); @@ -594,10 +594,10 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { public function test_get_products_by_type() { wp_set_current_user( $this->user ); - $simple = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $external = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - $grouped = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_grouped_product(); - $variable = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $simple = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $external = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + $grouped = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_grouped_product(); + $variable = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); $product_ids_for_type = array( 'simple' => array( $simple->get_id() ), @@ -636,12 +636,12 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // Create a featured product. - $feat_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $feat_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $feat_product->set_featured( true ); $feat_product->save(); // Create a non-featured product. - $nonfeat_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $nonfeat_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $nonfeat_product->save(); $query_params = array( @@ -710,12 +710,12 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' ); // Product with a tag. - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $product->set_tag_ids( array( $test_tag_1['term_id'] ) ); $product->save(); // Product without a tag. - $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $query_params = array( 'tag' => (string) $test_tag_1['term_id'], @@ -741,17 +741,17 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); // Variable product with 2 different variations. - $variable_product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $variable_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); // Terms created by variable product. $term_large = get_term_by( 'slug', 'large', 'pa_size' ); $term_small = get_term_by( 'slug', 'small', 'pa_size' ); // Simple product without attribute. - $product_1 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); // Simple product with attribute size = large. - $product_2 = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $product_2->set_attributes( array( 'pa_size' => 'large' ) ); $product_2->save(); diff --git a/unit-tests/Tests/Version3/reports-coupons-totals.php b/unit-tests/Tests/Version3/reports-coupons-totals.php index 10ce18f7ede..162b8af7ef7 100644 --- a/unit-tests/Tests/Version3/reports-coupons-totals.php +++ b/unit-tests/Tests/Version3/reports-coupons-totals.php @@ -89,7 +89,7 @@ class WC_Tests_API_Reports_Coupons_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/coupons/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version3/reports-customers-totals.php b/unit-tests/Tests/Version3/reports-customers-totals.php index 248f348d068..cd0e58f886f 100644 --- a/unit-tests/Tests/Version3/reports-customers-totals.php +++ b/unit-tests/Tests/Version3/reports-customers-totals.php @@ -105,7 +105,7 @@ class WC_Tests_API_Reports_Customers_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/customers/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version3/reports-orders-totals.php b/unit-tests/Tests/Version3/reports-orders-totals.php index 2c2834ea43a..93a21a87634 100644 --- a/unit-tests/Tests/Version3/reports-orders-totals.php +++ b/unit-tests/Tests/Version3/reports-orders-totals.php @@ -78,7 +78,7 @@ class WC_Tests_API_Reports_Orders_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/orders/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version3/reports-products-totals.php b/unit-tests/Tests/Version3/reports-products-totals.php index a178b492381..6243786ffad 100644 --- a/unit-tests/Tests/Version3/reports-products-totals.php +++ b/unit-tests/Tests/Version3/reports-products-totals.php @@ -85,7 +85,7 @@ class WC_Tests_API_Reports_Products_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/products/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version3/reports-reviews-totals.php b/unit-tests/Tests/Version3/reports-reviews-totals.php index 6c477e97a9c..3a2dc1622ff 100644 --- a/unit-tests/Tests/Version3/reports-reviews-totals.php +++ b/unit-tests/Tests/Version3/reports-reviews-totals.php @@ -84,7 +84,7 @@ class WC_Tests_API_Reports_Reviews_Totals extends WC_REST_Unit_Test_Case { */ public function test_product_review_schema() { wp_set_current_user( $this->user ); - $product = \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/reviews/totals' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/unit-tests/Tests/Version3/settings.php b/unit-tests/Tests/Version3/settings.php index db8b8480536..4fac9ba3509 100644 --- a/unit-tests/Tests/Version3/settings.php +++ b/unit-tests/Tests/Version3/settings.php @@ -371,7 +371,7 @@ class Settings extends WC_REST_Unit_Test_Case { $controller ->expects( $this->any() ) ->method( 'get_group_settings' ) - ->will( $this->returnValue( \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); + ->will( $this->returnValue( \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); $controller ->expects( $this->any() ) diff --git a/unit-tests/Tests/Version3/system-status.php b/unit-tests/Tests/Version3/system-status.php index 51f3016bcab..9b8a9e86345 100644 --- a/unit-tests/Tests/Version3/system-status.php +++ b/unit-tests/Tests/Version3/system-status.php @@ -2,7 +2,7 @@ /** * Class WC_Tests_REST_System_Status file. * - * @package WooCommerce/Tests + * @package Automattic/WooCommerce/Tests */ /** diff --git a/unit-tests/Tests/Version4/Coupons.php b/unit-tests/Tests/Version4/Coupons.php index 88f77929dd5..fef7f35776b 100644 --- a/unit-tests/Tests/Version4/Coupons.php +++ b/unit-tests/Tests/Version4/Coupons.php @@ -2,15 +2,15 @@ /** * Coupon REST API tests. * - * @package WooCommerce/RestApi/Tests + * @package Automattic/WooCommerce/RestApi/Tests */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; -use \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; +use Automattic\WooCommerce\RestApi\UnitTests\AbstractRestApiTest; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper; /** * Abstract Rest API Test Class diff --git a/unit-tests/Tests/Version4/Customers.php b/unit-tests/Tests/Version4/Customers.php index 842039d8ecf..a04bb241c17 100644 --- a/unit-tests/Tests/Version4/Customers.php +++ b/unit-tests/Tests/Version4/Customers.php @@ -6,13 +6,13 @@ * @since 3.5.0 */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; use \WP_REST_Request; use \WC_REST_Unit_Test_Case; -use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Tests for the Customers REST API. diff --git a/unit-tests/Tests/Version4/Data.php b/unit-tests/Tests/Version4/Data.php index 15b14b95ef7..8dd440d2ba7 100644 --- a/unit-tests/Tests/Version4/Data.php +++ b/unit-tests/Tests/Version4/Data.php @@ -5,7 +5,7 @@ * @package WooCommerce Admin\Tests\API */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; @@ -77,7 +77,7 @@ class Data extends \WC_REST_Unit_Test_Case { $product->set_regular_price( 25 ); $product->save(); - $order = \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); $order->set_status( 'completed' ); $order->set_total( 100 ); $order->save(); diff --git a/unit-tests/Tests/Version4/Orders.php b/unit-tests/Tests/Version4/Orders.php index 730245d278b..d8a5e0b955e 100644 --- a/unit-tests/Tests/Version4/Orders.php +++ b/unit-tests/Tests/Version4/Orders.php @@ -2,17 +2,17 @@ /** * Orders REST API tests. * - * @package WooCommerce/RestApi/Tests + * @package Automattic/WooCommerce/RestApi/Tests */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; -use \WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; -use \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; +use Automattic\WooCommerce\RestApi\UnitTests\AbstractRestApiTest; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper; /** * Abstract Rest API Test Class @@ -569,7 +569,7 @@ class Orders extends AbstractRestApiTest { public function test_update_order_add_coupons() { $order = OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); @@ -597,7 +597,7 @@ class Orders extends AbstractRestApiTest { public function test_update_order_remove_coupons() { $order = OrderHelper::create_order(); $order_item = current( $order->get_items() ); - $coupon = \WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); + $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); $coupon->set_amount( 5 ); $coupon->save(); $order->apply_coupon( $coupon ); diff --git a/unit-tests/Tests/Version4/PaymentGateways.php b/unit-tests/Tests/Version4/PaymentGateways.php index 5ef9e82c7ca..183dae52dda 100644 --- a/unit-tests/Tests/Version4/PaymentGateways.php +++ b/unit-tests/Tests/Version4/PaymentGateways.php @@ -7,7 +7,7 @@ */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Tests/Version4/ProductReviews.php b/unit-tests/Tests/Version4/ProductReviews.php index ec9417704db..1315d550b81 100644 --- a/unit-tests/Tests/Version4/ProductReviews.php +++ b/unit-tests/Tests/Version4/ProductReviews.php @@ -2,15 +2,15 @@ /** * Product Reviews REST API tests. * - * @package WooCommerce/RestApi/Tests + * @package Automattic/WooCommerce/RestApi/Tests */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; -use \WooCommerce\RestApi\UnitTests\AbstractRestApiTest; -use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; +use Automattic\WooCommerce\RestApi\UnitTests\AbstractRestApiTest; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; /** * Abstract Rest API Test Class diff --git a/unit-tests/Tests/Version4/ProductVariations.php b/unit-tests/Tests/Version4/ProductVariations.php index 2b9fd04d279..aa3188b3b2e 100644 --- a/unit-tests/Tests/Version4/ProductVariations.php +++ b/unit-tests/Tests/Version4/ProductVariations.php @@ -6,13 +6,13 @@ * @since 3.5.0 */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; use \WP_REST_Request; use \WC_REST_Unit_Test_Case; -use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; class ProductVariations extends WC_REST_Unit_Test_Case { diff --git a/unit-tests/Tests/Version4/Products.php b/unit-tests/Tests/Version4/Products.php index 94585a06e97..fde184ea98a 100644 --- a/unit-tests/Tests/Version4/Products.php +++ b/unit-tests/Tests/Version4/Products.php @@ -6,13 +6,13 @@ * @since 3.5.0 */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; use \WP_REST_Request; use \WC_REST_Unit_Test_Case; -use \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper; /** * Products class. diff --git a/unit-tests/Tests/Version4/Settings.php b/unit-tests/Tests/Version4/Settings.php index 2ff52c18b9e..d65a4680a32 100644 --- a/unit-tests/Tests/Version4/Settings.php +++ b/unit-tests/Tests/Version4/Settings.php @@ -6,13 +6,13 @@ * @since 3.5.0 */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; use \WP_REST_Request; use \WC_REST_Unit_Test_Case; -use \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper; +use Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper; class Settings extends WC_REST_Unit_Test_Case { diff --git a/unit-tests/Tests/Version4/ShippingMethods.php b/unit-tests/Tests/Version4/ShippingMethods.php index 18123f939e5..987f5755fa9 100644 --- a/unit-tests/Tests/Version4/ShippingMethods.php +++ b/unit-tests/Tests/Version4/ShippingMethods.php @@ -6,7 +6,7 @@ * @since 3.5.0 */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Tests/Version4/ShippingZones.php b/unit-tests/Tests/Version4/ShippingZones.php index 7ee63f08d44..38cacecda06 100644 --- a/unit-tests/Tests/Version4/ShippingZones.php +++ b/unit-tests/Tests/Version4/ShippingZones.php @@ -6,7 +6,7 @@ * @since 3.5.0 */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; diff --git a/unit-tests/Tests/Version4/SystemStatus.php b/unit-tests/Tests/Version4/SystemStatus.php index 82a558b444b..b4932e9b880 100644 --- a/unit-tests/Tests/Version4/SystemStatus.php +++ b/unit-tests/Tests/Version4/SystemStatus.php @@ -2,10 +2,10 @@ /** * Class WC_Tests_REST_System_Status file. * - * @package WooCommerce/Tests + * @package Automattic/WooCommerce/Tests */ -namespace WooCommerce\RestApi\UnitTests\Tests\Version4; +namespace Automattic\WooCommerce\RestApi\UnitTests\Tests\Version4; defined( 'ABSPATH' ) || exit; diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 18f41482ce3..c97eed5bfa1 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -9,7 +9,7 @@ * Requires PHP: 5.6 * License: GPLv3 * - * @package WooCommerce/RestApi + * @package Automattic/WooCommerce/RestApi */ defined( 'ABSPATH' ) || exit; From 2943708bb12f70b845f32e5f26893436a926a1ee Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 21 Jun 2019 14:57:26 +0100 Subject: [PATCH 172/440] Comments --- .gitattributes | 1 - package-version.php | 10 ---------- woocommerce-rest-api.php | 5 +---- 3 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 package-version.php diff --git a/.gitattributes b/.gitattributes index 63caea1317e..b5d3da03cbb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,5 @@ /phpunit.* export-ignore /unit-tests export-ignore /vendor export-ignore -/woocommerce-rest-api.php export-ignore /README.md export-ignore /readme.txt export-ignore diff --git a/package-version.php b/package-version.php deleted file mode 100644 index e43b5c3213a..00000000000 --- a/package-version.php +++ /dev/null @@ -1,10 +0,0 @@ - Date: Fri, 21 Jun 2019 19:58:20 +0100 Subject: [PATCH 173/440] Package file for entry point --- src/Package.php | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/Package.php diff --git a/src/Package.php b/src/Package.php new file mode 100644 index 00000000000..ec3cc6474d2 --- /dev/null +++ b/src/Package.php @@ -0,0 +1,48 @@ +init(); + } + + /** + * Return the version of the package. + * + * @return string + */ + public static function get_version() { + return self::VERSION; + } + + /** + * Return the path to the package. + * + * @return string + */ + public static function get_path() { + return dirname( __DIR__ ); + } +} From 854ac947d84a3093a67af6714f11378990e1a916 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jun 2019 13:01:21 +0100 Subject: [PATCH 174/440] Unique text domains --- composer.json | 3 +- .../class-wc-rest-coupons-v1-controller.php | 62 ++-- ...-rest-customer-downloads-v1-controller.php | 28 +- .../class-wc-rest-customers-v1-controller.php | 130 +++---- ...lass-wc-rest-order-notes-v1-controller.php | 46 +-- ...ss-wc-rest-order-refunds-v1-controller.php | 72 ++-- .../class-wc-rest-orders-v1-controller.php | 246 +++++++------- ...-product-attribute-terms-v1-controller.php | 24 +- ...-rest-product-attributes-v1-controller.php | 48 +-- ...-rest-product-categories-v1-controller.php | 30 +- ...-wc-rest-product-reviews-v1-controller.php | 64 ++-- ...product-shipping-classes-v1-controller.php | 10 +- ...ass-wc-rest-product-tags-v1-controller.php | 10 +- .../class-wc-rest-products-v1-controller.php | 320 +++++++++--------- ...ass-wc-rest-report-sales-v1-controller.php | 30 +- ...-rest-report-top-sellers-v1-controller.php | 6 +- .../class-wc-rest-reports-v1-controller.php | 10 +- ...lass-wc-rest-tax-classes-v1-controller.php | 22 +- .../class-wc-rest-taxes-v1-controller.php | 64 ++-- ...-rest-webhook-deliveries-v1-controller.php | 38 +-- .../class-wc-rest-webhooks-v1-controller.php | 84 ++--- .../class-wc-rest-coupons-v2-controller.php | 72 ++-- ...-rest-customer-downloads-v2-controller.php | 26 +- .../class-wc-rest-customers-v2-controller.php | 82 ++--- ...s-wc-rest-network-orders-v2-controller.php | 12 +- ...lass-wc-rest-order-notes-v2-controller.php | 14 +- ...ss-wc-rest-order-refunds-v2-controller.php | 84 ++--- .../class-wc-rest-orders-v2-controller.php | 292 ++++++++-------- ...wc-rest-payment-gateways-v2-controller.php | 46 +-- ...-rest-product-categories-v2-controller.php | 34 +- ...-wc-rest-product-reviews-v2-controller.php | 20 +- ...-rest-product-variations-v2-controller.php | 140 ++++---- .../class-wc-rest-products-v2-controller.php | 250 +++++++------- ...-wc-rest-setting-options-v2-controller.php | 40 +-- .../class-wc-rest-settings-v2-controller.php | 14 +- ...wc-rest-shipping-methods-v2-controller.php | 14 +- ...-shipping-zone-locations-v2-controller.php | 8 +- ...st-shipping-zone-methods-v2-controller.php | 56 +-- ...s-wc-rest-shipping-zones-v2-controller.php | 18 +- ...rest-system-status-tools-v2-controller.php | 134 ++++---- ...ss-wc-rest-system-status-v2-controller.php | 158 ++++----- ...-rest-webhook-deliveries-v2-controller.php | 24 +- .../class-wc-rest-webhooks-v2-controller.php | 28 +- .../Version3/class-wc-rest-controller.php | 16 +- .../class-wc-rest-crud-controller.php | 52 +-- .../class-wc-rest-customers-controller.php | 78 ++--- ...ass-wc-rest-data-continents-controller.php | 34 +- .../class-wc-rest-data-controller.php | 14 +- ...lass-wc-rest-data-countries-controller.php | 14 +- ...ass-wc-rest-data-currencies-controller.php | 10 +- .../class-wc-rest-order-notes-controller.php | 22 +- ...class-wc-rest-order-refunds-controller.php | 6 +- .../class-wc-rest-orders-controller.php | 6 +- ...ss-wc-rest-payment-gateways-controller.php | 34 +- .../class-wc-rest-posts-controller.php | 52 +-- ...-wc-rest-product-categories-controller.php | 34 +- ...ass-wc-rest-product-reviews-controller.php | 104 +++--- ...-wc-rest-product-variations-controller.php | 120 +++---- .../class-wc-rest-products-controller.php | 200 +++++------ ...-rest-report-coupons-totals-controller.php | 6 +- ...est-report-customers-totals-controller.php | 10 +- ...c-rest-report-orders-totals-controller.php | 6 +- ...rest-report-products-totals-controller.php | 6 +- ...-rest-report-reviews-totals-controller.php | 8 +- .../class-wc-rest-reports-controller.php | 16 +- ...ass-wc-rest-setting-options-controller.php | 24 +- .../class-wc-rest-settings-controller.php | 12 +- ...wc-rest-shipping-zones-controller-base.php | 18 +- .../class-wc-rest-terms-controller.php | 50 +-- .../Version4/AbstractController.php | 16 +- .../Version4/AbstractObjectsController.php | 50 +-- .../AbstractShippingZonesController.php | 10 +- .../Version4/AbstractTermsContoller.php | 34 +- src/Controllers/Version4/Coupons.php | 68 ++-- .../Version4/CustomerDownloads.php | 30 +- src/Controllers/Version4/Customers.php | 120 +++---- src/Controllers/Version4/Data.php | 12 +- src/Controllers/Version4/Data/Continents.php | 34 +- src/Controllers/Version4/Data/Countries.php | 14 +- src/Controllers/Version4/Data/Currencies.php | 10 +- src/Controllers/Version4/Data/DownloadIPs.php | 6 +- src/Controllers/Version4/NetworkOrders.php | 12 +- src/Controllers/Version4/OrderNotes.php | 52 +-- src/Controllers/Version4/OrderRefunds.php | 94 ++--- src/Controllers/Version4/Orders.php | 280 +++++++-------- src/Controllers/Version4/PaymentGateways.php | 42 +-- .../Version4/ProductAttributeTerms.php | 24 +- .../Version4/ProductAttributes.php | 30 +- .../Version4/ProductCategories.php | 34 +- src/Controllers/Version4/ProductReviews.php | 92 ++--- .../Version4/ProductShippingClasses.php | 10 +- src/Controllers/Version4/ProductTags.php | 10 +- .../Version4/ProductVariations.php | 148 ++++---- src/Controllers/Version4/Products.php | 240 ++++++------- .../Version4/Requests/CustomerRequest.php | 6 +- .../Version4/Requests/OrderRequest.php | 12 +- .../Version4/Requests/ProductRequest.php | 4 +- .../Requests/ProductVariationRequest.php | 2 +- src/Controllers/Version4/Settings.php | 12 +- src/Controllers/Version4/SettingsOptions.php | 38 +-- src/Controllers/Version4/ShippingMethods.php | 10 +- .../Version4/ShippingZoneLocations.php | 8 +- .../Version4/ShippingZoneMethods.php | 56 +-- src/Controllers/Version4/ShippingZones.php | 18 +- src/Controllers/Version4/SystemStatus.php | 140 ++++---- .../Version4/SystemStatusTools.php | 130 +++---- src/Controllers/Version4/TaxClasses.php | 16 +- src/Controllers/Version4/Taxes.php | 56 +-- .../Version4/Utilities/BatchTrait.php | 8 +- .../Utilities/DatabaseInformation.php | 4 +- .../Version4/Utilities/ServerEnvironment.php | 2 +- .../Version4/Utilities/SettingsTrait.php | 8 +- .../Version4/Utilities/ThemeInformation.php | 2 +- .../Version4/Utilities/WPEnvironment.php | 10 +- src/Controllers/Version4/Webhooks.php | 74 ++-- src/Utilities/ImageAttachment.php | 2 +- woocommerce-rest-api.php | 4 +- 117 files changed, 2979 insertions(+), 2980 deletions(-) diff --git a/composer.json b/composer.json index a1391a1f352..be084222a5c 100644 --- a/composer.json +++ b/composer.json @@ -11,8 +11,7 @@ }, "require-dev": { "phpunit/phpunit": "6.5.14", - "woocommerce/woocommerce-sniffs": "0.0.6", - "slowprog/composer-copy-file": "~0.3" + "woocommerce/woocommerce-sniffs": "0.0.6" }, "scripts": { "post-install-cmd": [ diff --git a/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php b/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php index 4fb300a9d4e..5290c9f153c 100644 --- a/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php @@ -67,7 +67,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), + 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), 'required' => true, 'type' => 'string', ), @@ -79,7 +79,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -105,7 +105,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -250,7 +250,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { // Validate required POST fields. if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { if ( empty( $request['code'] ) ) { - return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce-rest-api' ), 'code' ), array( 'status' => 400 ) ); } } @@ -266,7 +266,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); if ( $id_from_code ) { - return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $coupon->set_code( $coupon_code ); @@ -307,7 +307,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $coupon_id = $this->save_coupon( $request ); @@ -348,7 +348,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { $post_id = (int) $request['id']; if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $coupon_id = $this->save_coupon( $request ); @@ -412,64 +412,64 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the object.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), + 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Coupon description.', 'woocommerce' ), + 'description' => __( 'Coupon description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'discount_type' => array( - 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'fixed_cart', 'enum' => array_keys( wc_get_coupon_types() ), 'context' => array( 'view', 'edit' ), ), 'amount' => array( - 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'expiry_date' => array( - 'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce' ), + 'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'usage_count' => array( - 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'individual_use' => array( - 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_ids' => array( - 'description' => __( "List of product IDs the coupon can be used on.", 'woocommerce' ), + 'description' => __( "List of product IDs the coupon can be used on.", 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -477,7 +477,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'exclude_product_ids' => array( - 'description' => __( "List of product IDs the coupon cannot be used on.", 'woocommerce' ), + 'description' => __( "List of product IDs the coupon cannot be used on.", 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -485,28 +485,28 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'usage_limit' => array( - 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'usage_limit_per_user' => array( - 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'limit_usage_to_x_items' => array( - 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'free_shipping' => array( - 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_categories' => array( - 'description' => __( "List of category IDs the coupon applies to.", 'woocommerce' ), + 'description' => __( "List of category IDs the coupon applies to.", 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -514,7 +514,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'excluded_product_categories' => array( - 'description' => __( "List of category IDs the coupon does not apply to.", 'woocommerce' ), + 'description' => __( "List of category IDs the coupon does not apply to.", 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -522,23 +522,23 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'exclude_sale_items' => array( - 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'minimum_amount' => array( - 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'maximum_amount' => array( - 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email_restrictions' => array( - 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -546,7 +546,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'used_by' => array( - 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -569,7 +569,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { $params = parent::get_collection_params(); $params['code'] = array( - 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php b/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php index 0161f47a0df..0d65f93dff9 100644 --- a/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php @@ -43,7 +43,7 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'customer_id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -67,11 +67,11 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { $customer = get_user_by( 'id', (int) $request['customer_id'] ); if ( ! $customer ) { - return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_user_permissions( 'read', $customer->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -166,67 +166,67 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'download_url' => array( - 'description' => __( 'Download file URL.', 'woocommerce' ), + 'description' => __( 'Download file URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'download_id' => array( - 'description' => __( 'Download ID (MD5).', 'woocommerce' ), + 'description' => __( 'Download ID (MD5).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Downloadable product ID.', 'woocommerce' ), + 'description' => __( 'Downloadable product ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'download_name' => array( - 'description' => __( 'Downloadable file name.', 'woocommerce' ), + 'description' => __( 'Downloadable file name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce' ), + 'description' => __( 'Order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce' ), + 'description' => __( 'Order key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'downloads_remaining' => array( - 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), + 'description' => __( 'Number of downloads remaining.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'access_expires' => array( - 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File details.', 'woocommerce' ), + 'description' => __( 'File details.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php b/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php index 18b8d9786f6..8fc2687ca16 100644 --- a/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php @@ -55,16 +55,16 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'email' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'New user email address.', 'woocommerce' ), + 'description' => __( 'New user email address.', 'woocommerce-rest-api' ), ), 'username' => array( 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), - 'description' => __( 'New user username.', 'woocommerce' ), + 'description' => __( 'New user username.', 'woocommerce-rest-api' ), 'type' => 'string', ), 'password' => array( 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), - 'description' => __( 'New user password.', 'woocommerce' ), + 'description' => __( 'New user password.', 'woocommerce-rest-api' ), 'type' => 'string', ), ) ), @@ -75,7 +75,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -101,12 +101,12 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), 'reassign' => array( 'default' => 0, 'type' => 'integer', - 'description' => __( 'ID to reassign posts to.', 'woocommerce' ), + 'description' => __( 'ID to reassign posts to.', 'woocommerce-rest-api' ), ), ), ), @@ -132,7 +132,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -147,7 +147,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -163,7 +163,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'read', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -180,7 +180,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'edit', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -197,7 +197,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'delete', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -212,7 +212,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -324,7 +324,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { public function create_item( $request ) { try { if ( ! empty( $request['id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), 400 ); } // Sets the username. @@ -342,7 +342,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $customer->save(); if ( ! $customer->get_id() ) { - throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce-rest-api' ), 400 ); } $user_data = get_userdata( $customer->get_id() ); @@ -380,7 +380,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $user_data = get_userdata( $id ); if ( empty( $id ) || empty( $user_data->ID ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $customer = $this->prepare_item_for_response( $user_data, $request ); @@ -401,15 +401,15 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $customer = new WC_Customer( $id ); if ( ! $customer->get_id() ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), 400 ); } if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->get_email() ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce-rest-api' ), 400 ); } if ( ! empty( $request['username'] ) && $request['username'] !== $customer->get_username() ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce-rest-api' ), 400 ); } // Customer email. @@ -463,17 +463,17 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $user_data = get_userdata( $id ); if ( ! $user_data ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } if ( ! empty( $reassign ) ) { if ( $reassign === $id || ! get_userdata( $reassign ) ) { - return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -492,7 +492,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { } if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -629,31 +629,31 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce' ), + 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -661,7 +661,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ), ), 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce' ), + 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -669,7 +669,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ), ), 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce' ), + 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -677,24 +677,24 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ), ), 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce' ), + 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'last_order' => array( - 'description' => __( 'Last order data.', 'woocommerce' ), + 'description' => __( 'Last order data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => array( 'id' => array( - 'description' => __( 'Last order ID.', 'woocommerce' ), + 'description' => __( 'Last order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date' => array( - 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce' ), + 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -702,133 +702,133 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ), ), 'orders_count' => array( - 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_spent' => array( - 'description' => __( 'Total amount spent.', 'woocommerce' ), + 'description' => __( 'Total amount spent.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce' ), + 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce' ), + 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce' ), + 'description' => __( 'Email address.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce' ), + 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce' ), + 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce' ), + 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -862,7 +862,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -871,7 +871,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -880,14 +880,14 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'enum' => array( 'asc', 'desc' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', @@ -895,7 +895,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ); $params['orderby'] = array( 'default' => 'name', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'enum' => array( 'id', 'include', @@ -907,13 +907,13 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['email'] = array( - 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'validate_callback' => 'rest_validate_request_arg', ); $params['role'] = array( - 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'customer', 'enum' => array_merge( array( 'all' ), $this->get_role_names() ), diff --git a/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php index 731e5c9c4e6..785ff4627b4 100644 --- a/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php @@ -50,7 +50,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -67,7 +67,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'note' => array( 'type' => 'string', - 'description' => __( 'Order note content.', 'woocommerce' ), + 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), 'required' => true, ), ) ), @@ -78,11 +78,11 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -102,7 +102,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -118,7 +118,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -133,7 +133,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -149,7 +149,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -166,7 +166,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -183,7 +183,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $args = array( @@ -217,20 +217,20 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } // Create the note. $note_id = $order->add_order_note( $request['note'], $request['customer_note'] ); if ( ! $note_id ) { - return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $note = get_comment( $note_id ); @@ -265,13 +265,13 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $order_note = $this->prepare_item_for_response( $note, $request ); @@ -292,19 +292,19 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); @@ -313,7 +313,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $result = wc_delete_order_note( $note->comment_ID ); if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), 'order_note' ), array( 'status' => 500 ) ); } /** @@ -398,24 +398,24 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'note' => array( - 'description' => __( 'Order note.', 'woocommerce' ), + 'description' => __( 'Order note.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_note' => array( - 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce' ), + 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), diff --git a/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php b/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php index d5a02e06ac0..659ffa844ae 100644 --- a/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php @@ -58,7 +58,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -80,11 +80,11 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -104,7 +104,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'force' => array( 'default' => true, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -124,13 +124,13 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); } $refund = wc_get_order( $post ); if ( ! $refund || $refund->get_parent_id() !== $order->get_id() ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce-rest-api' ), 404 ); } $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); @@ -278,17 +278,17 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $order_data = get_post( (int) $request['order_id'] ); if ( empty( $order_data ) ) { - return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); + return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce-rest-api' ), 400 ); } if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); } // Create the refund. @@ -305,7 +305,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { } if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); } $post = get_post( $refund->get_id() ); @@ -341,29 +341,29 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'amount' => array( - 'description' => __( 'Refund amount.', 'woocommerce' ), + 'description' => __( 'Refund amount.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'reason' => array( - 'description' => __( 'Reason for refund.', 'woocommerce' ), + 'description' => __( 'Reason for refund.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce' ), + 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -371,79 +371,79 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce' ), + 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce' ), + 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce' ), + 'description' => __( 'Product price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -451,19 +451,19 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -472,7 +472,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { ), ), 'meta' => array( - 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'description' => __( 'Line item meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -480,19 +480,19 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'type' => 'object', 'properties' => array( 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Meta label.', 'woocommerce' ), + 'description' => __( 'Meta label.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -519,7 +519,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { $params['dp'] = array( 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php b/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php index 28bdf2c5eca..34570cda3d7 100644 --- a/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php @@ -73,7 +73,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -99,7 +99,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -531,7 +531,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { try { // Make sure customer exists. if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] && false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); } // Make sure customer is part of blog. @@ -618,7 +618,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } elseif ( ! empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['variation_id']; } else { - throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); } return $product_id; } @@ -690,7 +690,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { if ( 'create' === $action ) { if ( empty( $posted['method_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce-rest-api' ), 400 ); } } @@ -713,7 +713,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { if ( 'create' === $action ) { if ( empty( $posted['name'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce-rest-api' ), 400 ); } } @@ -736,7 +736,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { if ( 'create' === $action ) { if ( empty( $posted['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); } } @@ -774,7 +774,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { absint( $order->get_id() ) ) ); if ( is_null( $result ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce-rest-api' ), 400 ); } } @@ -823,7 +823,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $order_id = $this->create_order( $request ); @@ -862,7 +862,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { $post_id = (int) $request['id']; if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $order_id = $this->update_order( $request ); @@ -916,236 +916,236 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'parent_id' => array( - 'description' => __( 'Parent order ID.', 'woocommerce' ), + 'description' => __( 'Parent order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Order status.', 'woocommerce' ), + 'description' => __( 'Order status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'pending', 'enum' => $this->get_order_statuses(), 'context' => array( 'view', 'edit' ), ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce' ), + 'description' => __( 'Order key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'number' => array( - 'description' => __( 'Order number.', 'woocommerce' ), + 'description' => __( 'Order number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'currency' => array( - 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => get_woocommerce_currency(), 'enum' => array_keys( get_woocommerce_currencies() ), 'context' => array( 'view', 'edit' ), ), 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order was created, as GMT.", 'woocommerce' ), + 'description' => __( "The date the order was created, as GMT.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce' ), + 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 0, 'context' => array( 'view', 'edit' ), ), 'discount_total' => array( - 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), + 'description' => __( 'Total discount amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_tax' => array( - 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_total' => array( - 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), + 'description' => __( 'Total shipping amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax' => array( - 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_tax' => array( - 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), + 'description' => __( 'Sum of line item taxes only.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Grand total.', 'woocommerce' ), + 'description' => __( 'Grand total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Sum of all taxes.', 'woocommerce' ), + 'description' => __( 'Sum of all taxes.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'billing' => array( - 'description' => __( 'Billing address.', 'woocommerce' ), + 'description' => __( 'Billing address.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce' ), + 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce' ), + 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce' ), + 'description' => __( 'Email address.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce' ), + 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'Shipping address.', 'woocommerce' ), + 'description' => __( 'Shipping address.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce' ), + 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce' ), + 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'payment_method' => array( - 'description' => __( 'Payment method ID.', 'woocommerce' ), + 'description' => __( 'Payment method ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'payment_method_title' => array( - 'description' => __( 'Payment method title.', 'woocommerce' ), + 'description' => __( 'Payment method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -1153,131 +1153,131 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'edit' ), ), 'transaction_id' => array( - 'description' => __( 'Unique transaction ID.', 'woocommerce' ), + 'description' => __( 'Unique transaction ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'description' => __( "Customer's IP address.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'description' => __( 'User agent of the customer.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'description' => __( 'Shows where the order was created.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'description' => __( 'Note left by customer during checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_paid' => array( - 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_hash' => array( - 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce' ), + 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce' ), + 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce' ), + 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce' ), + 'description' => __( 'Product price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1285,19 +1285,19 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1306,7 +1306,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'meta' => array( - 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'description' => __( 'Line item meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1314,19 +1314,19 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Meta label.', 'woocommerce' ), + 'description' => __( 'Meta label.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1338,7 +1338,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'tax_lines' => array( - 'description' => __( 'Tax lines data.', 'woocommerce' ), + 'description' => __( 'Tax lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1346,43 +1346,43 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_code' => array( - 'description' => __( 'Tax rate code.', 'woocommerce' ), + 'description' => __( 'Tax rate code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Tax rate label.', 'woocommerce' ), + 'description' => __( 'Tax rate label.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'compound' => array( - 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_total' => array( - 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax_total' => array( - 'description' => __( 'Shipping tax total.', 'woocommerce' ), + 'description' => __( 'Shipping tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1391,41 +1391,41 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'shipping_lines' => array( - 'description' => __( 'Shipping lines data.', 'woocommerce' ), + 'description' => __( 'Shipping lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_title' => array( - 'description' => __( 'Shipping method name.', 'woocommerce' ), + 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1433,13 +1433,13 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1451,46 +1451,46 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'fee_lines' => array( - 'description' => __( 'Fee lines data.', 'woocommerce' ), + 'description' => __( 'Fee lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Fee name.', 'woocommerce' ), + 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of fee.', 'woocommerce' ), + 'description' => __( 'Tax class of fee.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status of fee.', 'woocommerce' ), + 'description' => __( 'Tax status of fee.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'taxable', 'none' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1498,19 +1498,19 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1522,30 +1522,30 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'coupon_lines' => array( - 'description' => __( 'Coupons line data.', 'woocommerce' ), + 'description' => __( 'Coupons line data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), + 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'discount' => array( - 'description' => __( 'Discount total.', 'woocommerce' ), + 'description' => __( 'Discount total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'discount_tax' => array( - 'description' => __( 'Discount total tax.', 'woocommerce' ), + 'description' => __( 'Discount total tax.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1554,7 +1554,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'refunds' => array( - 'description' => __( 'List of refunds.', 'woocommerce' ), + 'description' => __( 'List of refunds.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1562,19 +1562,19 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Refund ID.', 'woocommerce' ), + 'description' => __( 'Refund ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reason' => array( - 'description' => __( 'Refund reason.', 'woocommerce' ), + 'description' => __( 'Refund reason.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Refund total.', 'woocommerce' ), + 'description' => __( 'Refund total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1598,27 +1598,27 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_merge( array( 'any' ), $this->get_order_statuses() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['customer'] = array( - 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['product'] = array( - 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['dp'] = array( 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php index 4d115f5ae2a..361febd1dcf 100644 --- a/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php @@ -44,7 +44,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro array( 'args' => array( 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -61,7 +61,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'name' => array( 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), 'required' => true, ), ) ), @@ -72,11 +72,11 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -102,7 +102,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -112,7 +112,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( 'args' => array( 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -193,13 +193,13 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Term name.', 'woocommerce' ), + 'description' => __( 'Term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -207,7 +207,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -215,7 +215,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -223,12 +223,12 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php index 93b535937d6..3c9fa646a84 100644 --- a/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php @@ -60,7 +60,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'name' => array( - 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'required' => true, ), @@ -72,7 +72,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -98,7 +98,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => true, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -124,7 +124,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -138,7 +138,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -152,11 +152,11 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -170,11 +170,11 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function update_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -188,11 +188,11 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function delete_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -207,7 +207,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -354,7 +354,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $attribute = $this->get_attribute( (int) $request['id'] ); @@ -369,7 +369,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { $deleted = wc_delete_attribute( $attribute->attribute_id ); if ( false === $deleted ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -453,13 +453,13 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -467,7 +467,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -475,21 +475,21 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { ), ), 'type' => array( - 'description' => __( 'Type of attribute.', 'woocommerce' ), + 'description' => __( 'Type of attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'select', 'enum' => array_keys( wc_get_attribute_types() ), 'context' => array( 'view', 'edit' ), ), 'order_by' => array( - 'description' => __( 'Default sort order.', 'woocommerce' ), + 'description' => __( 'Default sort order.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'menu_order', 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ), 'context' => array( 'view', 'edit' ), ), 'has_archives' => array( - 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce' ), + 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), @@ -548,7 +548,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { ", $id ) ); if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { - return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $attribute; @@ -564,11 +564,11 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ protected function validate_attribute_slug( $slug, $new_data = true ) { if ( strlen( $slug ) >= 28 ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); } return true; diff --git a/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php index 22d16a0d0bc..956d5cd43b3 100644 --- a/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php @@ -171,13 +171,13 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), + 'description' => __( 'Category name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -185,7 +185,7 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -193,12 +193,12 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller ), ), 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -206,59 +206,59 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller ), ), 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'default', 'enum' => array( 'default', 'products', 'subcategories', 'both' ), 'context' => array( 'view', 'edit' ), ), 'image' => array( - 'description' => __( 'Image data.', 'woocommerce' ), + 'description' => __( 'Image data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'title' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php index f52b7e098ab..e4d9b93075b 100644 --- a/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php @@ -43,11 +43,11 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variation.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -65,17 +65,17 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { 'review' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce' ), + 'description' => __( 'Review content.', 'woocommerce-rest-api' ), ), 'name' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + 'description' => __( 'Name of the reviewer.', 'woocommerce-rest-api' ), ), 'email' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + 'description' => __( 'Email of the reviewer.', 'woocommerce-rest-api' ), ), ) ), ), @@ -85,11 +85,11 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -115,7 +115,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -131,7 +131,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( 'product', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -147,7 +147,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $post = get_post( (int) $request['product_id'] ); if ( $post && ! wc_rest_check_post_permissions( 'product', 'read', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -162,7 +162,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { public function create_item_permissions_check( $request ) { $post = get_post( (int) $request['product_id'] ); if ( $post && ! wc_rest_check_post_permissions( 'product', 'create', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -176,7 +176,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { public function update_item_permissions_check( $request ) { $post = get_post( (int) $request['product_id'] ); if ( $post && ! wc_rest_check_post_permissions( 'product', 'edit', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -190,7 +190,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { public function delete_item_permissions_check( $request ) { $post = get_post( (int) $request['product_id'] ); if ( $post && ! wc_rest_check_post_permissions( 'product', 'delete', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -206,7 +206,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $reviews = get_approved_comments( $product_id ); @@ -231,13 +231,13 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $review = get_comment( $id ); if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $delivery = $this->prepare_item_for_response( $review, $request ); @@ -257,7 +257,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $prepared_review = $this->prepare_item_for_database( $request ); @@ -274,7 +274,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_review_id = wp_insert_comment( $prepared_review ); if ( ! $product_review_id ) { - return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); @@ -312,20 +312,20 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $review = get_comment( $product_review_id ); if ( empty( $product_review_id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $prepared_review = $this->prepare_item_for_database( $request ); $updated = wp_update_comment( $prepared_review ); if ( 0 === $updated ) { - return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } if ( ! empty( $request['rating'] ) ) { @@ -363,7 +363,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_review = get_comment( $product_review_id ); if ( empty( $product_review_id ) || empty( $product_review->comment_ID ) || empty( $product_review->comment_post_ID ) ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } /** @@ -383,18 +383,18 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $result = wp_delete_comment( $product_review_id, true ); } else { if ( ! $supports_trash ) { - return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } if ( 'trash' === $product_review->comment_approved ) { - return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce-rest-api' ), array( 'status' => 410 ) ); } $result = wp_trash_comment( $product_review->comment_ID ); } if ( ! $result ) { - return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -523,38 +523,38 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce' ), + 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php index fb2326df2dd..92ab292f1a0 100644 --- a/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php @@ -91,13 +91,13 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Shipping class name.', 'woocommerce' ), + 'description' => __( 'Shipping class name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -105,7 +105,7 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -113,7 +113,7 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -121,7 +121,7 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php index a43ef8b43f6..c4e587b44da 100644 --- a/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php @@ -91,13 +91,13 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce' ), + 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -105,7 +105,7 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -113,7 +113,7 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -121,7 +121,7 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-products-v1-controller.php b/src/Controllers/Version1/class-wc-rest-products-v1-controller.php index cbe7a37f5eb..73cd14ea769 100644 --- a/src/Controllers/Version1/class-wc-rest-products-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-products-v1-controller.php @@ -74,7 +74,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -99,7 +99,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'args' => array( 'force' => array( 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), 'type' => 'boolean', ), ), @@ -310,8 +310,8 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), // Default to now. 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), 'src' => wc_placeholder_img_src(), - 'name' => __( 'Placeholder', 'woocommerce' ), - 'alt' => __( 'Placeholder', 'woocommerce' ), + 'name' => __( 'Placeholder', 'woocommerce-rest-api' ), + 'alt' => __( 'Placeholder', 'woocommerce-rest-api' ), 'position' => 0, ); } @@ -736,7 +736,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $product_id = 0; @@ -781,7 +781,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $post_id = (int) $request['id']; if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } try { @@ -864,7 +864,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { } if ( ! wp_attachment_is_image( $attachment_id ) ) { - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); } if ( isset( $image['position'] ) && 0 === absint( $image['position'] ) ) { @@ -1369,7 +1369,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { // Create initial name and status. if ( ! $variation->get_slug() ) { /* translators: 1: variation id 2: product name */ - $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); + $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce-rest-api' ), $variation->get_id(), $product->get_name() ) ); $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); } @@ -1634,9 +1634,9 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $product = wc_get_product( $id ); if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0; @@ -1653,7 +1653,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -1685,13 +1685,13 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( 'trash' === $post->post_status ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); } // (Note that internally this falls through to `wp_delete_post` if @@ -1702,7 +1702,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); } // Delete parent product transients. @@ -1736,163 +1736,163 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce' ), + 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce' ), + 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), + 'description' => __( 'Product type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'simple', 'enum' => array_keys( wc_get_product_types() ), 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), 'context' => array( 'view', 'edit' ), ), 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce' ), + 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'visible', 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Product description.', 'woocommerce' ), + 'description' => __( 'Product description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce' ), + 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce' ), + 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce' ), + 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce' ), + 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( 'Start date of sale price.', 'woocommerce' ), + 'description' => __( 'Start date of sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( 'End date of sale price.', 'woocommerce' ), + 'description' => __( 'End date of sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), + 'description' => __( 'File ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1900,163 +1900,163 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_type' => array( - 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce' ), + 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'standard', 'enum' => array( 'standard' ), 'context' => array( 'view', 'edit' ), ), 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), + 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'in_stock' => array( - 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2065,7 +2065,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'readonly' => true, ), 'upsell_ids' => array( - 'description' => __( 'List of upsell products IDs.', 'woocommerce' ), + 'description' => __( 'List of upsell products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2073,7 +2073,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2081,35 +2081,35 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce' ), + 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce' ), + 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), + 'description' => __( 'Category name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce' ), + 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -2118,25 +2118,25 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce' ), + 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce' ), + 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce' ), + 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce' ), + 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -2145,47 +2145,47 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'images' => array( - 'description' => __( 'List of images.', 'woocommerce' ), + 'description' => __( 'List of images.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), @@ -2193,41 +2193,41 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), + 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce' ), + 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), ), @@ -2235,24 +2235,24 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -2260,116 +2260,116 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'variations' => array( - 'description' => __( 'List of variations.', 'woocommerce' ), + 'description' => __( 'List of variations.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Variation ID.', 'woocommerce' ), + 'description' => __( 'Variation ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce' ), + 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce' ), + 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( 'Start date of sale price.', 'woocommerce' ), + 'description' => __( 'Start date of sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( 'End date of sale price.', 'woocommerce' ), + 'description' => __( 'End date of sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'visible' => array( - 'description' => __( 'If the variation is visible.', 'woocommerce' ), + 'description' => __( 'If the variation is visible.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), + 'description' => __( 'File ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -2377,171 +2377,171 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => null, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => null, 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), + 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'in_stock' => array( - 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce' ), + 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), + 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -2552,7 +2552,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2561,7 +2561,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'readonly' => true, ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), @@ -2580,57 +2580,57 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $params = parent::get_collection_params(); $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_types() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['sku'] = array( - 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php b/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php index d880c86e7e5..57bd5da4490 100644 --- a/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php @@ -66,7 +66,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -287,67 +287,67 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'total_sales' => array( - 'description' => __( 'Gross sales in the period.', 'woocommerce' ), + 'description' => __( 'Gross sales in the period.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'net_sales' => array( - 'description' => __( 'Net sales in the period.', 'woocommerce' ), + 'description' => __( 'Net sales in the period.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'average_sales' => array( - 'description' => __( 'Average net daily sales.', 'woocommerce' ), + 'description' => __( 'Average net daily sales.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total_orders' => array( - 'description' => __( 'Total of orders placed.', 'woocommerce' ), + 'description' => __( 'Total of orders placed.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'total_items' => array( - 'description' => __( 'Total of items purchased.', 'woocommerce' ), + 'description' => __( 'Total of items purchased.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Total charged for taxes.', 'woocommerce' ), + 'description' => __( 'Total charged for taxes.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total_shipping' => array( - 'description' => __( 'Total charged for shipping.', 'woocommerce' ), + 'description' => __( 'Total charged for shipping.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total_refunds' => array( - 'description' => __( 'Total of refunded orders.', 'woocommerce' ), + 'description' => __( 'Total of refunded orders.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'total_discount' => array( - 'description' => __( 'Total of coupons used.', 'woocommerce' ), + 'description' => __( 'Total of coupons used.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'totals_grouped_by' => array( - 'description' => __( 'Group type.', 'woocommerce' ), + 'description' => __( 'Group type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'totals' => array( - 'description' => __( 'Totals.', 'woocommerce' ), + 'description' => __( 'Totals.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'array', @@ -370,7 +370,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'period' => array( - 'description' => __( 'Report period.', 'woocommerce' ), + 'description' => __( 'Report period.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array( 'week', 'month', 'last_month', 'year' ), 'validate_callback' => 'rest_validate_request_arg', @@ -378,7 +378,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { ), 'date_min' => array( /* translators: %s: date format */ - 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), + 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce-rest-api' ), 'YYYY-MM-DD' ), 'type' => 'string', 'format' => 'date', 'validate_callback' => 'wc_rest_validate_reports_request_arg', @@ -386,7 +386,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { ), 'date_max' => array( /* translators: %s: date format */ - 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), + 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce-rest-api' ), 'YYYY-MM-DD' ), 'type' => 'string', 'format' => 'date', 'validate_callback' => 'wc_rest_validate_reports_request_arg', diff --git a/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php b/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php index 22e928e05b8..76d0aa9d2ae 100644 --- a/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php @@ -149,19 +149,19 @@ class WC_REST_Report_Top_Sellers_V1_Controller extends WC_REST_Report_Sales_V1_C 'type' => 'object', 'properties' => array( 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce' ), + 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'quantity' => array( - 'description' => __( 'Total number of purchases.', 'woocommerce' ), + 'description' => __( 'Total number of purchases.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php b/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php index c35b9e6329b..1f1463ae2b5 100644 --- a/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php @@ -59,7 +59,7 @@ class WC_REST_Reports_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -75,11 +75,11 @@ class WC_REST_Reports_V1_Controller extends WC_REST_Controller { return array( array( 'slug' => 'sales', - 'description' => __( 'List of sales reports.', 'woocommerce' ), + 'description' => __( 'List of sales reports.', 'woocommerce-rest-api' ), ), array( 'slug' => 'top_sellers', - 'description' => __( 'List of top sellers products.', 'woocommerce' ), + 'description' => __( 'List of top sellers products.', 'woocommerce-rest-api' ), ), ); } @@ -154,13 +154,13 @@ class WC_REST_Reports_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), + 'description' => __( 'A human-readable description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php index 6d0a4d406e7..365d0c440f8 100644 --- a/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php @@ -59,7 +59,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', array( 'args' => array( 'slug' => array( - 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), + 'description' => __( 'Unique slug for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -71,7 +71,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -87,7 +87,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -102,7 +102,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -117,7 +117,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -135,7 +135,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { // Add standard class. $tax_classes[] = array( 'slug' => 'standard', - 'name' => __( 'Standard rate', 'woocommerce' ), + 'name' => __( 'Standard rate', 'woocommerce-rest-api' ), ); $classes = WC_Tax::get_tax_classes(); @@ -181,7 +181,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { // Return error if tax class already exists. if ( $exists ) { - return new WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } // Add the new class. @@ -222,7 +222,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $tax_class = array( @@ -242,7 +242,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { } if ( ! $deleted ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); @@ -331,13 +331,13 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Tax class name.', 'woocommerce' ), + 'description' => __( 'Tax class name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'required' => true, diff --git a/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php index bbbc1869314..ae81985a3d2 100644 --- a/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php @@ -59,7 +59,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -85,7 +85,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -111,7 +111,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -126,7 +126,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -140,7 +140,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -155,7 +155,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -170,7 +170,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -185,7 +185,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -361,7 +361,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $tax = $this->create_or_update_tax( $request ); @@ -397,7 +397,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $tax = $this->prepare_item_for_response( $tax_obj, $request ); @@ -417,7 +417,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $tax = $this->create_or_update_tax( $request, $tax_obj ); @@ -454,13 +454,13 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $tax = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $request->set_param( 'context', 'edit' ); @@ -469,7 +469,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { WC_Tax::_delete_tax_rate( $id ); if ( 0 === $wpdb->rows_affected ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -573,66 +573,66 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'country' => array( - 'description' => __( 'Country ISO 3166 code.', 'woocommerce' ), + 'description' => __( 'Country ISO 3166 code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'State code.', 'woocommerce' ), + 'description' => __( 'State code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postcode / ZIP.', 'woocommerce' ), + 'description' => __( 'Postcode / ZIP.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'rate' => array( - 'description' => __( 'Tax rate.', 'woocommerce' ), + 'description' => __( 'Tax rate.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tax rate name.', 'woocommerce' ), + 'description' => __( 'Tax rate name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'priority' => array( - 'description' => __( 'Tax priority.', 'woocommerce' ), + 'description' => __( 'Tax priority.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 1, 'context' => array( 'view', 'edit' ), ), 'compound' => array( - 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce' ), + 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'shipping' => array( - 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce' ), + 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'order' => array( - 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce' ), + 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'standard', 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), @@ -655,7 +655,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -663,7 +663,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -672,14 +672,14 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'enum' => array( 'asc', 'desc' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', @@ -687,7 +687,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { ); $params['orderby'] = array( 'default' => 'order', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'enum' => array( 'id', 'order', @@ -697,7 +697,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['class'] = array( - 'description' => __( 'Sort by tax class.', 'woocommerce' ), + 'description' => __( 'Sort by tax class.', 'woocommerce-rest-api' ), 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), 'sanitize_callback' => 'sanitize_title', 'type' => 'string', diff --git a/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php b/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php index 033a2c797c8..adbd3f62b2f 100644 --- a/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php @@ -44,7 +44,7 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'webhook_id' => array( - 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -60,11 +60,11 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'webhook_id' => array( - 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -88,7 +88,7 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -102,7 +102,7 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -119,7 +119,7 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { $webhook = wc_get_webhook( (int) $request['webhook_id'] ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $logs = array(); @@ -144,13 +144,13 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { $webhook = wc_get_webhook( (int) $request['webhook_id'] ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $log = array(); if ( empty( $id ) || empty( $log ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $delivery = $this->prepare_item_for_response( (object) $log, $request ); @@ -223,32 +223,32 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'duration' => array( - 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'summary' => array( - 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'request_url' => array( - 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'request_headers' => array( - 'description' => __( 'Request headers.', 'woocommerce' ), + 'description' => __( 'Request headers.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -257,25 +257,25 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { ), ), 'request_body' => array( - 'description' => __( 'Request body.', 'woocommerce' ), + 'description' => __( 'Request body.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_code' => array( - 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_message' => array( - 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_headers' => array( - 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -284,13 +284,13 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { ), ), 'response_body' => array( - 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), + 'description' => __( 'The response body from the receiving server.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php b/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php index 9ad7e982b25..d9f6c611c8a 100644 --- a/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php @@ -60,12 +60,12 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'topic' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), ), 'delivery_url' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), + 'description' => __( 'Webhook delivery URL.', 'woocommerce-rest-api' ), ), ) ), ), @@ -75,7 +75,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -101,7 +101,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -127,7 +127,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -142,7 +142,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -156,7 +156,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -171,7 +171,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -186,7 +186,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -201,7 +201,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -297,7 +297,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { $id = (int) $request['id']; if ( empty( $id ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $id, $request ); @@ -315,17 +315,17 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } // Validate topic. if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } // Validate delivery URL. if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -377,7 +377,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } // Update topic. @@ -385,7 +385,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { $webhook->set_topic( $request['topic'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -394,7 +394,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { if ( wc_is_valid_url( $request['delivery_url'] ) ) { $webhook->set_delivery_url( $request['delivery_url'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -408,7 +408,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { $webhook->set_status( $request['status'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -452,13 +452,13 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); @@ -467,7 +467,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -498,7 +498,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { // Validate required POST fields. if ( 'POST' === $request->get_method() && empty( $data->ID ) ) { - $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ); // @codingStandardsIgnoreLine + $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce-rest-api' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce-rest-api' ) ) ); // @codingStandardsIgnoreLine // Post author. $data->post_author = get_current_user_id(); @@ -546,7 +546,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $data = array( @@ -612,42 +612,42 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), + 'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Webhook status.', 'woocommerce' ), + 'description' => __( 'Webhook status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'active', 'enum' => array_keys( wc_get_webhook_statuses() ), 'context' => array( 'view', 'edit' ), ), 'topic' => array( - 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'resource' => array( - 'description' => __( 'Webhook resource.', 'woocommerce' ), + 'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'event' => array( - 'description' => __( 'Webhook event.', 'woocommerce' ), + 'description' => __( 'Webhook event.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hooks' => array( - 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -656,25 +656,25 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { ), ), 'delivery_url' => array( - 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'secret' => array( - 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -696,19 +696,19 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), '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' ), + 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -717,7 +717,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -726,20 +726,20 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), 'validate_callback' => 'rest_validate_request_arg', ); $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -751,7 +751,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { ); $params['status'] = array( 'default' => 'all', - 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array( 'all', 'active', 'paused', 'disabled' ), 'sanitize_callback' => 'sanitize_key', diff --git a/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php b/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php index 687b4ed466a..5f3ac9fcbab 100644 --- a/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php @@ -58,7 +58,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), + 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), 'required' => true, 'type' => 'string', ), @@ -73,7 +73,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -99,7 +99,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -268,7 +268,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { // Validate required POST fields. if ( $creating && empty( $request['code'] ) ) { - return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce-rest-api' ), 'code' ), array( 'status' => 400 ) ); } // Handle all writable props. @@ -283,7 +283,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); if ( $id_from_code ) { - return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $coupon->set_code( $coupon_code ); @@ -332,81 +332,81 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the object.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), + 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'amount' => array( - 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_type' => array( - 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'fixed_cart', 'enum' => array_keys( wc_get_coupon_types() ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Coupon description.', 'woocommerce' ), + 'description' => __( 'Coupon description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_expires' => array( - 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_expires_gmt' => array( - 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'usage_count' => array( - 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'individual_use' => array( - 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_ids' => array( - 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce' ), + 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -414,7 +414,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'excluded_product_ids' => array( - 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce' ), + 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -422,28 +422,28 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'usage_limit' => array( - 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'usage_limit_per_user' => array( - 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'limit_usage_to_x_items' => array( - 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'free_shipping' => array( - 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_categories' => array( - 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce' ), + 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -451,7 +451,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'excluded_product_categories' => array( - 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce' ), + 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -459,23 +459,23 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'exclude_sale_items' => array( - 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'minimum_amount' => array( - 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'maximum_amount' => array( - 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email_restrictions' => array( - 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -483,7 +483,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'used_by' => array( - 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -492,25 +492,25 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -531,7 +531,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { $params = parent::get_collection_params(); $params['code'] = array( - 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php index e403442f484..1b7c0de9fd6 100644 --- a/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php @@ -78,79 +78,79 @@ class WC_REST_Customer_Downloads_V2_Controller extends WC_REST_Customer_Download 'type' => 'object', 'properties' => array( 'download_id' => array( - 'description' => __( 'Download ID.', 'woocommerce' ), + 'description' => __( 'Download ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'download_url' => array( - 'description' => __( 'Download file URL.', 'woocommerce' ), + 'description' => __( 'Download file URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Downloadable product ID.', 'woocommerce' ), + 'description' => __( 'Downloadable product ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'product_name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'download_name' => array( - 'description' => __( 'Downloadable file name.', 'woocommerce' ), + 'description' => __( 'Downloadable file name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce' ), + 'description' => __( 'Order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce' ), + 'description' => __( 'Order key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'downloads_remaining' => array( - 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), + 'description' => __( 'Number of downloads remaining.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'access_expires' => array( - 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'access_expires_gmt' => array( - 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce' ), + 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File details.', 'woocommerce' ), + 'description' => __( 'File details.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php index de079d1ac2f..bc72be9664e 100644 --- a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php @@ -121,43 +121,43 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce' ), + 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -165,7 +165,7 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { ), ), 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce' ), + 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -173,13 +173,13 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { ), ), 'role' => array( - 'description' => __( 'Customer role.', 'woocommerce' ), + 'description' => __( 'Customer role.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce' ), + 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -187,169 +187,169 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { ), ), 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce' ), + 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce' ), + 'description' => __( 'Email address.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce' ), + 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'is_paying_customer' => array( - 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), + 'description' => __( 'Is the customer a paying customer?', 'woocommerce-rest-api' ), 'type' => 'bool', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'orders_count' => array( - 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_spent' => array( - 'description' => __( 'Total amount spent.', 'woocommerce' ), + 'description' => __( 'Total amount spent.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), diff --git a/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php index 45d0f8b483d..357082d1b65 100644 --- a/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php @@ -55,31 +55,31 @@ class WC_REST_Network_Orders_V2_Controller extends WC_REST_Orders_V2_Controller $schema = parent::get_public_item_schema(); $schema['properties']['blog'] = array( - 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce' ), + 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['edit_url'] = array( - 'description' => __( 'URL to edit the order', 'woocommerce' ), + 'description' => __( 'URL to edit the order', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['customer'][] = array( - 'description' => __( 'Name of the customer for the order', 'woocommerce' ), + 'description' => __( 'Name of the customer for the order', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['status_name'][] = array( - 'description' => __( 'Order Status', 'woocommerce' ), + 'description' => __( 'Order Status', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['formatted_total'][] = array( - 'description' => __( 'Order total formatted for locale', 'woocommerce' ), + 'description' => __( 'Order total formatted for locale', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, @@ -146,7 +146,7 @@ class WC_REST_Network_Orders_V2_Controller extends WC_REST_Orders_V2_Controller $current_order['blog'] = get_blog_details( get_current_blog_id() ); $current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' ); /* translators: 1: first name 2: last name */ - $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); + $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce-rest-api' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); $current_order['status_name'] = wc_get_order_status_name( $order->get_status() ); $current_order['formatted_total'] = $order->get_formatted_order_total(); } diff --git a/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php index f3d269c963f..6ecd15e3165 100644 --- a/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php @@ -36,7 +36,7 @@ class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controlle $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $args = array( @@ -126,30 +126,30 @@ class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controlle 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'note' => array( - 'description' => __( 'Order note content.', 'woocommerce' ), + 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_note' => array( - 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), @@ -170,7 +170,7 @@ class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controlle $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['type'] = array( 'default' => 'any', - 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce' ), + 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array( 'any', 'customer', 'internal' ), 'sanitize_callback' => 'sanitize_key', diff --git a/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php b/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php index 508db09352b..dff06e2d063 100644 --- a/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php @@ -61,7 +61,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -85,11 +85,11 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -109,7 +109,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'force' => array( 'default' => true, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -188,11 +188,11 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); } if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce-rest-api' ), 404 ); } $data = $this->get_formatted_item_data( $object ); @@ -270,11 +270,11 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); } if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); } // Create the refund. @@ -293,7 +293,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { } if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); } if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { @@ -352,64 +352,64 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'amount' => array( - 'description' => __( 'Refund amount.', 'woocommerce' ), + 'description' => __( 'Refund amount.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'reason' => array( - 'description' => __( 'Reason for refund.', 'woocommerce' ), + 'description' => __( 'Reason for refund.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'refunded_by' => array( - 'description' => __( 'User ID of user who created the refund.', 'woocommerce' ), + 'description' => __( 'User ID of user who created the refund.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'refunded_payment' => array( - 'description' => __( 'If the payment was refunded via the API.', 'woocommerce' ), + 'description' => __( 'If the payment was refunded via the API.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -417,7 +417,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce' ), + 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -425,67 +425,67 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce' ), + 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -493,19 +493,19 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -514,7 +514,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -522,19 +522,19 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -543,13 +543,13 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce' ), + 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce' ), + 'description' => __( 'Product price.', 'woocommerce-rest-api' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -558,7 +558,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), ), 'api_refund' => array( - 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce' ), + 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'default' => true, diff --git a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php index 197d5a0e1dc..b073f04c5a1 100644 --- a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -83,7 +83,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -109,7 +109,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -529,7 +529,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { // Make sure customer exists. if ( false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); } // Make sure customer is part of blog. @@ -601,7 +601,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { } elseif ( ! empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['variation_id']; } else { - throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); } return $product_id; } @@ -693,7 +693,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( 'create' === $action ) { if ( empty( $posted['method_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce-rest-api' ), 400 ); } } @@ -717,7 +717,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( 'create' === $action ) { if ( empty( $posted['name'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce-rest-api' ), 400 ); } } @@ -741,7 +741,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( 'create' === $action ) { if ( empty( $posted['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); } } @@ -778,7 +778,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { $item = $order->get_item( absint( $posted['id'] ), false ); if ( ! $item ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce-rest-api' ), 400 ); } } @@ -841,271 +841,271 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'parent_id' => array( - 'description' => __( 'Parent order ID.', 'woocommerce' ), + 'description' => __( 'Parent order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'number' => array( - 'description' => __( 'Order number.', 'woocommerce' ), + 'description' => __( 'Order number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce' ), + 'description' => __( 'Order key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'description' => __( 'Shows where the order was created.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Order status.', 'woocommerce' ), + 'description' => __( 'Order status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'pending', 'enum' => $this->get_order_statuses(), 'context' => array( 'view', 'edit' ), ), 'currency' => array( - 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => get_woocommerce_currency(), 'enum' => array_keys( get_woocommerce_currencies() ), 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_total' => array( - 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), + 'description' => __( 'Total discount amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_tax' => array( - 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_total' => array( - 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), + 'description' => __( 'Total shipping amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax' => array( - 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_tax' => array( - 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), + 'description' => __( 'Sum of line item taxes only.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Grand total.', 'woocommerce' ), + 'description' => __( 'Grand total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Sum of all taxes.', 'woocommerce' ), + 'description' => __( 'Sum of all taxes.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 0, 'context' => array( 'view', 'edit' ), ), 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'description' => __( "Customer's IP address.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'description' => __( 'User agent of the customer.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'description' => __( 'Note left by customer during checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'billing' => array( - 'description' => __( 'Billing address.', 'woocommerce' ), + 'description' => __( 'Billing address.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce' ), + 'description' => __( 'Email address.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce' ), + 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'Shipping address.', 'woocommerce' ), + 'description' => __( 'Shipping address.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'payment_method' => array( - 'description' => __( 'Payment method ID.', 'woocommerce' ), + 'description' => __( 'Payment method ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'payment_method_title' => array( - 'description' => __( 'Payment method title.', 'woocommerce' ), + 'description' => __( 'Payment method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -1113,60 +1113,60 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'transaction_id' => array( - 'description' => __( 'Unique transaction ID.', 'woocommerce' ), + 'description' => __( 'Unique transaction ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_paid' => array( - 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_paid_gmt' => array( - 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_completed_gmt' => array( - 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_hash' => array( - 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1174,67 +1174,67 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce' ), + 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce' ), + 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1242,17 +1242,17 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1260,25 +1260,25 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1286,13 +1286,13 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce' ), + 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce' ), + 'description' => __( 'Product price.', 'woocommerce-rest-api' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1301,7 +1301,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'tax_lines' => array( - 'description' => __( 'Tax lines data.', 'woocommerce' ), + 'description' => __( 'Tax lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1309,67 +1309,67 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_code' => array( - 'description' => __( 'Tax rate code.', 'woocommerce' ), + 'description' => __( 'Tax rate code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Tax rate label.', 'woocommerce' ), + 'description' => __( 'Tax rate label.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'compound' => array( - 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_total' => array( - 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax_total' => array( - 'description' => __( 'Shipping tax total.', 'woocommerce' ), + 'description' => __( 'Shipping tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1380,46 +1380,46 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'shipping_lines' => array( - 'description' => __( 'Shipping lines data.', 'woocommerce' ), + 'description' => __( 'Shipping lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_title' => array( - 'description' => __( 'Shipping method name.', 'woocommerce' ), + 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'instance_id' => array( - 'description' => __( 'Shipping instance ID.', 'woocommerce' ), + 'description' => __( 'Shipping instance ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1427,13 +1427,13 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1442,25 +1442,25 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1471,47 +1471,47 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'fee_lines' => array( - 'description' => __( 'Fee lines data.', 'woocommerce' ), + 'description' => __( 'Fee lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Fee name.', 'woocommerce' ), + 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of fee.', 'woocommerce' ), + 'description' => __( 'Tax class of fee.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status of fee.', 'woocommerce' ), + 'description' => __( 'Tax status of fee.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'taxable', 'none' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1519,19 +1519,19 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1540,25 +1540,25 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1569,54 +1569,54 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'coupon_lines' => array( - 'description' => __( 'Coupons line data.', 'woocommerce' ), + 'description' => __( 'Coupons line data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), + 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'discount' => array( - 'description' => __( 'Discount total.', 'woocommerce' ), + 'description' => __( 'Discount total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'discount_tax' => array( - 'description' => __( 'Discount total tax.', 'woocommerce' ), + 'description' => __( 'Discount total tax.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1627,7 +1627,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'refunds' => array( - 'description' => __( 'List of refunds.', 'woocommerce' ), + 'description' => __( 'List of refunds.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1635,19 +1635,19 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Refund ID.', 'woocommerce' ), + 'description' => __( 'Refund ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reason' => array( - 'description' => __( 'Refund reason.', 'woocommerce' ), + 'description' => __( 'Refund reason.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Refund total.', 'woocommerce' ), + 'description' => __( 'Refund total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1656,7 +1656,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'edit' ), @@ -1677,27 +1677,27 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['customer'] = array( - 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['product'] = array( - 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['dp'] = array( 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php b/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php index 69bfc51f418..a652ea1fab3 100644 --- a/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php @@ -51,7 +51,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -82,7 +82,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -95,7 +95,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -108,7 +108,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { */ public function update_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -141,7 +141,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { $gateway = $this->get_gateway( $request ); if ( is_null( $gateway ) ) { - return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $gateway = $this->prepare_item_for_response( $gateway, $request ); @@ -158,7 +158,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { $gateway = $this->get_gateway( $request ); if ( is_null( $gateway ) ) { - return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } // Get settings. @@ -184,7 +184,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { } if ( $errors_found ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -351,23 +351,23 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'description' => __( 'Payment gateway ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'description' => __( 'Payment gateway sort order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -375,71 +375,71 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { ), ), 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'description' => __( 'Payment gateway enabled status.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'description' => __( 'Payment gateway method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'description' => __( 'Payment gateway method description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'description' => __( 'Payment gateway settings.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), + 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), + 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php index 08c5f8f1980..5c065477ffa 100644 --- a/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php @@ -100,13 +100,13 @@ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categorie 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), + 'description' => __( 'Category name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -114,7 +114,7 @@ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categorie ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -122,12 +122,12 @@ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categorie ), ), 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -135,71 +135,71 @@ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categorie ), ), 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'default', 'enum' => array( 'default', 'products', 'subcategories', 'both' ), 'context' => array( 'view', 'edit' ), ), 'image' => array( - 'description' => __( 'Image data.', 'woocommerce' ), + 'description' => __( 'Image data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'title' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php index 12ab7d62655..a90d4ad232e 100644 --- a/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php @@ -42,7 +42,7 @@ class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_C $this->namespace, '/' . $this->rest_base . '/batch', array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -65,7 +65,7 @@ class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_C */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( 'product', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -150,43 +150,43 @@ class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_C 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce' ), + 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_created_gmt' => array( - 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php index 7e051263f93..81c8e7884c6 100644 --- a/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php @@ -47,7 +47,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -70,11 +70,11 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variation.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -104,7 +104,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -115,7 +115,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $this->namespace, '/' . $this->rest_base . '/batch', array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -151,12 +151,12 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } // Check if variation belongs to the correct parent product. if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -488,7 +488,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( ! $object || 0 === $object->get_id() ) { return new WP_Error( - "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( + "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404, ) ); @@ -509,7 +509,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { return new WP_Error( /* translators: %s: post type */ - "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( + "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code(), ) ); @@ -527,7 +527,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( ! $supports_trash ) { return new WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( + 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501, ) ); @@ -538,7 +538,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( 'trash' === $object->get_status() ) { return new WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( + 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410, ) ); @@ -552,7 +552,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( ! $result ) { return new WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( + 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500, ) ); @@ -646,125 +646,125 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce' ), + 'description' => __( 'Variation description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce' ), + 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce' ), + 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'visible' => array( - 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce' ), + 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), + 'description' => __( 'File ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -772,183 +772,183 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), + 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'in_stock' => array( - 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce' ), + 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), + 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -956,30 +956,30 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), diff --git a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php index f092749d5fe..97c4ec0a716 100644 --- a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php @@ -83,7 +83,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -112,7 +112,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'args' => array( 'force' => array( 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), 'type' => 'boolean', ), ), @@ -423,8 +423,8 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), 'date_modified_gmt' => wc_rest_prepare_date_response( current_time( 'timestamp', true ) ), 'src' => wc_placeholder_img_src(), - 'name' => __( 'Placeholder', 'woocommerce' ), - 'alt' => __( 'Placeholder', 'woocommerce' ), + 'name' => __( 'Placeholder', 'woocommerce-rest-api' ), + 'alt' => __( 'Placeholder', 'woocommerce-rest-api' ), 'position' => 0, ); } @@ -730,7 +730,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( 'variation' === $product->get_type() ) { return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404, ) @@ -1120,7 +1120,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( ! wp_attachment_is_image( $attachment_id ) ) { /* translators: %s: attachment id */ - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); } $gallery_positions[ $attachment_id ] = absint( isset( $image['position'] ) ? $image['position'] : $index ); @@ -1351,7 +1351,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( ! $object || 0 === $object->get_id() ) { return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", - __( 'Invalid ID.', 'woocommerce' ), + __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404, ) @@ -1361,7 +1361,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( 'variation' === $object->get_type() ) { return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404, ) @@ -1384,7 +1384,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", /* translators: %s: post type */ - sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), + sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code(), ) @@ -1422,7 +1422,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { return new WP_Error( 'woocommerce_rest_trash_not_supported', /* translators: %s: post type */ - sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), + sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501, ) @@ -1435,7 +1435,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { return new WP_Error( 'woocommerce_rest_already_trashed', /* translators: %s: post type */ - sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), + sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410, ) @@ -1451,7 +1451,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { return new WP_Error( 'woocommerce_rest_cannot_delete', /* translators: %s: post type */ - sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), + sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500, ) @@ -1489,185 +1489,185 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce' ), + 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce' ), + 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), + 'description' => __( 'Product type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'simple', 'enum' => array_keys( wc_get_product_types() ), 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), 'context' => array( 'view', 'edit' ), ), 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce' ), + 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'visible', 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Product description.', 'woocommerce' ), + 'description' => __( 'Product description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce' ), + 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce' ), + 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce' ), + 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce' ), + 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), + 'description' => __( 'File ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1675,156 +1675,156 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), + 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'in_stock' => array( - 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1833,7 +1833,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'readonly' => true, ), 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'description' => __( 'List of up-sell products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1841,7 +1841,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1849,35 +1849,35 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce' ), + 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce' ), + 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), + 'description' => __( 'Category name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce' ), + 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1886,25 +1886,25 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce' ), + 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce' ), + 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce' ), + 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce' ), + 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1913,59 +1913,59 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'images' => array( - 'description' => __( 'List of images.', 'woocommerce' ), + 'description' => __( 'List of images.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), @@ -1973,41 +1973,41 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), + 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce' ), + 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -2018,24 +2018,24 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -2043,7 +2043,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'description' => __( 'List of variations IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -2052,7 +2052,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'readonly' => true, ), 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2060,30 +2060,30 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -2105,63 +2105,63 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { $params = parent::get_collection_params(); $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_types() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['sku'] = array( - 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['featured'] = array( - 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), + 'description' => __( 'Limit result set to featured products.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -2169,7 +2169,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( wc_tax_enabled() ) { $params['tax_class'] = array( - 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), 'sanitize_callback' => 'sanitize_text_field', @@ -2178,25 +2178,25 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { } $params['in_stock'] = array( - 'description' => __( 'Limit result set to products in stock or out of stock.', 'woocommerce' ), + 'description' => __( 'Limit result set to products in stock or out of stock.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); $params['on_sale'] = array( - 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), + 'description' => __( 'Limit result set to products on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); $params['min_price'] = array( - 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), + 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['max_price'] = array( - 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), + 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php b/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php index 0b1d988f941..7c8a72a1220 100644 --- a/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php @@ -42,7 +42,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -59,7 +59,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/batch', array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -77,11 +77,11 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), 'type' => 'string', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -156,13 +156,13 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ public function get_group_settings( $group_id ) { if ( empty( $group_id ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $filtered_settings = array(); @@ -231,7 +231,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ public function get_setting( $group_id, $setting_id ) { if ( empty( $setting_id ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $settings = $this->get_group_settings( $group_id ); @@ -243,13 +243,13 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); if ( empty( $array_key ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $setting = $settings[ $array_key[0] ]; if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $setting; @@ -373,7 +373,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -388,7 +388,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ 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 new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -502,7 +502,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', @@ -511,7 +511,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -520,7 +520,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -529,18 +529,18 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), + 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -549,7 +549,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -558,7 +558,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), + 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -568,7 +568,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php b/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php index f41c91e722d..1ca5f153b40 100644 --- a/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php @@ -60,7 +60,7 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { public function get_items( $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $defaults = $this->group_defaults(); @@ -176,7 +176,7 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -195,31 +195,31 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'description' => __( 'ID of parent grouping.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'description' => __( 'IDs for settings sub groups.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php index 795c92b3e18..0c4a0ff8fcd 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php @@ -51,7 +51,7 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -76,7 +76,7 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -89,7 +89,7 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -121,7 +121,7 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { $wc_shipping = WC_Shipping::instance(); $methods = $wc_shipping->get_shipping_methods(); if ( empty( $methods[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $method = $methods[ $request['id'] ]; @@ -195,19 +195,19 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Method ID.', 'woocommerce' ), + 'description' => __( 'Method ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php index 9e171814f70..434906709c7 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php @@ -26,7 +26,7 @@ class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zon $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/locations', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), + 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -85,7 +85,7 @@ class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zon } if ( 0 === $zone->get_id() ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); } $raw_locations = $request->get_json_params(); @@ -166,12 +166,12 @@ class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zon 'type' => 'object', 'properties' => array( 'code' => array( - 'description' => __( 'Shipping zone location code.', 'woocommerce' ), + 'description' => __( 'Shipping zone location code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'type' => array( - 'description' => __( 'Shipping zone location type.', 'woocommerce' ), + 'description' => __( 'Shipping zone location type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'country', 'enum' => array( diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php index c753fd8e42f..67ad37bfd26 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php @@ -26,7 +26,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods', array( 'args' => array( 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -44,7 +44,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones 'method_id' => array( 'required' => true, 'readonly' => false, - 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), ), ) ), @@ -57,11 +57,11 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', array( 'args' => array( 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'instance_id' => array( - 'description' => __( 'Unique ID for the instance.', 'woocommerce' ), + 'description' => __( 'Unique ID for the instance.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -84,7 +84,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -118,7 +118,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $method, $request ); @@ -174,7 +174,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -212,7 +212,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -227,7 +227,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones if ( $force ) { $zone->delete_shipping_method( $instance_id ); } else { - return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } /** @@ -266,7 +266,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -311,7 +311,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( $errors_found ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); @@ -433,100 +433,100 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'instance_id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Shipping method customer facing title.', 'woocommerce' ), + 'description' => __( 'Shipping method customer facing title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'order' => array( - 'description' => __( 'Shipping method sort order.', 'woocommerce' ), + 'description' => __( 'Shipping method sort order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'enabled' => array( - 'description' => __( 'Shipping method enabled status.', 'woocommerce' ), + 'description' => __( 'Shipping method enabled status.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'settings' => array( - 'description' => __( 'Shipping method settings.', 'woocommerce' ), + 'description' => __( 'Shipping method settings.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), + 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), + 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php index db881b97fbe..d3abcf9ff46 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php @@ -38,7 +38,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro 'name' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Shipping zone name.', 'woocommerce' ), + 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), ), ) ), @@ -51,7 +51,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro $this->namespace, '/' . $this->rest_base . '/(?P[\d-]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), + 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -74,7 +74,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -151,7 +151,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); return $response; } else { - return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } } @@ -169,7 +169,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro } if ( 0 === $zone->get_id() ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); } $zone_changed = false; @@ -211,7 +211,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro if ( $force ) { $zone->delete(); } else { - return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } return $response; @@ -278,13 +278,13 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Shipping zone name.', 'woocommerce' ), + 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -292,7 +292,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro ), ), 'order' => array( - 'description' => __( 'Shipping zone order.', 'woocommerce' ), + 'description' => __( 'Shipping zone order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 4842a63c4fb..37394960d2a 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -56,7 +56,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -84,7 +84,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { */ 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 new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -97,7 +97,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { */ 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 view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -110,7 +110,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -124,79 +124,79 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { public function get_tools() { $tools = array( 'clear_transients' => array( - 'name' => __( 'WooCommerce transients', 'woocommerce' ), - 'button' => __( 'Clear transients', 'woocommerce' ), - 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ), + 'name' => __( 'WooCommerce transients', 'woocommerce-rest-api' ), + 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce-rest-api' ), ), 'clear_expired_transients' => array( - 'name' => __( 'Expired transients', 'woocommerce' ), - 'button' => __( 'Clear transients', 'woocommerce' ), - 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce' ), + 'name' => __( 'Expired transients', 'woocommerce-rest-api' ), + 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce-rest-api' ), ), 'delete_orphaned_variations' => array( - 'name' => __( 'Orphaned variations', 'woocommerce' ), - 'button' => __( 'Delete orphaned variations', 'woocommerce' ), - 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce' ), + 'name' => __( 'Orphaned variations', 'woocommerce-rest-api' ), + 'button' => __( 'Delete orphaned variations', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce-rest-api' ), ), 'clear_expired_download_permissions' => array( - 'name' => __( 'Used-up download permissions', 'woocommerce' ), - 'button' => __( 'Clean up download permissions', 'woocommerce' ), - 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ), + 'name' => __( 'Used-up download permissions', 'woocommerce-rest-api' ), + 'button' => __( 'Clean up download permissions', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce-rest-api' ), ), 'regenerate_product_lookup_tables' => array( - 'name' => __( 'Product lookup tables', 'woocommerce' ), - 'button' => __( 'Regenerate', 'woocommerce' ), - 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce' ), + 'name' => __( 'Product lookup tables', 'woocommerce-rest-api' ), + 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce-rest-api' ), ), 'recount_terms' => array( - 'name' => __( 'Term counts', 'woocommerce' ), - 'button' => __( 'Recount terms', 'woocommerce' ), - 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ), + 'name' => __( 'Term counts', 'woocommerce-rest-api' ), + 'button' => __( 'Recount terms', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce-rest-api' ), ), 'reset_roles' => array( - 'name' => __( 'Capabilities', 'woocommerce' ), - 'button' => __( 'Reset capabilities', 'woocommerce' ), - 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ), + 'name' => __( 'Capabilities', 'woocommerce-rest-api' ), + 'button' => __( 'Reset capabilities', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce-rest-api' ), ), 'clear_sessions' => array( - 'name' => __( 'Clear customer sessions', 'woocommerce' ), - 'button' => __( 'Clear', 'woocommerce' ), + 'name' => __( 'Clear customer sessions', 'woocommerce-rest-api' ), + 'button' => __( 'Clear', 'woocommerce-rest-api' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce' ) + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce-rest-api' ) ), ), 'install_pages' => array( - 'name' => __( 'Create default WooCommerce pages', 'woocommerce' ), - 'button' => __( 'Create pages', 'woocommerce' ), + 'name' => __( 'Create default WooCommerce pages', 'woocommerce-rest-api' ), + 'button' => __( 'Create pages', 'woocommerce-rest-api' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce' ) + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce-rest-api' ) ), ), 'delete_taxes' => array( - 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce' ), - 'button' => __( 'Delete tax rates', 'woocommerce' ), + 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce-rest-api' ), + 'button' => __( 'Delete tax rates', 'woocommerce-rest-api' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce' ) + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce-rest-api' ) ), ), 'regenerate_thumbnails' => array( - 'name' => __( 'Regenerate shop thumbnails', 'woocommerce' ), - 'button' => __( 'Regenerate', 'woocommerce' ), - 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce' ), + 'name' => __( 'Regenerate shop thumbnails', 'woocommerce-rest-api' ), + 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), + 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce-rest-api' ), ), 'db_update_routine' => array( - 'name' => __( 'Update database', 'woocommerce' ), - 'button' => __( 'Update database', 'woocommerce' ), + 'name' => __( 'Update database', 'woocommerce-rest-api' ), + 'button' => __( 'Update database', 'woocommerce-rest-api' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce' ) + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce-rest-api' ) ), ), ); @@ -244,7 +244,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { public function get_item( $request ) { $tools = $this->get_tools(); if ( empty( $tools[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $tool = $tools[ $request['id'] ]; return rest_ensure_response( @@ -269,7 +269,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { public function update_item( $request ) { $tools = $this->get_tools(); if ( empty( $tools[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $tool = $tools[ $request['id'] ]; @@ -327,7 +327,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the tool.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the tool.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -335,7 +335,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), 'name' => array( - 'description' => __( 'Tool name.', 'woocommerce' ), + 'description' => __( 'Tool name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -343,7 +343,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), 'action' => array( - 'description' => __( 'What running the tool will do.', 'woocommerce' ), + 'description' => __( 'What running the tool will do.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -351,7 +351,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), 'description' => array( - 'description' => __( 'Tool description.', 'woocommerce' ), + 'description' => __( 'Tool description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -359,12 +359,12 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), 'success' => array( - 'description' => __( 'Did the tool run successfully?', 'woocommerce' ), + 'description' => __( 'Did the tool run successfully?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'edit' ), ), 'message' => array( - 'description' => __( 'Tool return message.', 'woocommerce' ), + 'description' => __( 'Tool return message.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( @@ -430,12 +430,12 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { } WC_Cache_Helper::get_transient_version( 'shipping', true ); - $message = __( 'Product transients cleared', 'woocommerce' ); + $message = __( 'Product transients cleared', 'woocommerce-rest-api' ); break; case 'clear_expired_transients': /* translators: %d: amount of expired transients */ - $message = sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() ); + $message = sprintf( __( '%d transients rows cleared', 'woocommerce-rest-api' ), wc_delete_expired_transients() ); break; case 'delete_orphaned_variations': @@ -449,7 +449,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ) ); /* translators: %d: amount of orphaned variations */ - $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result ); + $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce-rest-api' ), $result ); break; case 'clear_expired_download_permissions': @@ -464,20 +464,20 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ) ); /* translators: %d: amount of permissions */ - $message = sprintf( __( '%d permissions deleted', 'woocommerce' ), $result ); + $message = sprintf( __( '%d permissions deleted', 'woocommerce-rest-api' ), $result ); break; case 'regenerate_product_lookup_tables': if ( ! wc_update_product_lookup_tables_is_running() ) { wc_update_product_lookup_tables(); } - $message = __( 'Lookup tables are regenerating', 'woocommerce' ); + $message = __( 'Lookup tables are regenerating', 'woocommerce-rest-api' ); break; case 'reset_roles': // Remove then re-add caps and roles. WC_Install::remove_roles(); WC_Install::create_roles(); - $message = __( 'Roles successfully reset', 'woocommerce' ); + $message = __( 'Roles successfully reset', 'woocommerce-rest-api' ); break; case 'recount_terms': @@ -497,7 +497,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ) ); _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); - $message = __( 'Terms successfully recounted', 'woocommerce' ); + $message = __( 'Terms successfully recounted', 'woocommerce-rest-api' ); break; case 'clear_sessions': @@ -505,24 +505,24 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. wp_cache_flush(); /* translators: %d: amount of sessions */ - $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) ); + $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce-rest-api' ), absint( $result ) ); break; case 'install_pages': WC_Install::create_pages(); - $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); + $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce-rest-api' ); break; case 'delete_taxes': $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); WC_Cache_Helper::incr_cache_prefix( 'taxes' ); - $message = __( 'Tax rates successfully deleted', 'woocommerce' ); + $message = __( 'Tax rates successfully deleted', 'woocommerce-rest-api' ); break; case 'regenerate_thumbnails': WC_Regenerate_Images::queue_image_regeneration(); - $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); + $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce-rest-api' ); break; case 'db_update_routine': @@ -530,7 +530,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); - $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' ); + $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce-rest-api' ); break; default: @@ -544,13 +544,13 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $callback_string = is_array( $callback ) ? get_class( $callback[0] ) . '::' . $callback[1] : $callback; $ran = false; /* translators: %s: callback string */ - $message = sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback_string ); + $message = sprintf( __( 'There was an error calling %s', 'woocommerce-rest-api' ), $callback_string ); } else { - $message = __( 'Tool ran.', 'woocommerce' ); + $message = __( 'Tool ran.', 'woocommerce-rest-api' ); } } else { $ran = false; - $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ); + $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce-rest-api' ); } break; } diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 9b4fcec7b38..0f97047dcb0 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -59,7 +59,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { */ 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 new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -102,195 +102,195 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'environment' => array( - 'description' => __( 'Environment.', 'woocommerce' ), + 'description' => __( 'Environment.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'home_url' => array( - 'description' => __( 'Home URL.', 'woocommerce' ), + 'description' => __( 'Home URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'site_url' => array( - 'description' => __( 'Site URL.', 'woocommerce' ), + 'description' => __( 'Site URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'wc_version' => array( - 'description' => __( 'WooCommerce version.', 'woocommerce' ), + 'description' => __( 'WooCommerce version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'log_directory' => array( - 'description' => __( 'Log directory.', 'woocommerce' ), + 'description' => __( 'Log directory.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'log_directory_writable' => array( - 'description' => __( 'Is log directory writable?', 'woocommerce' ), + 'description' => __( 'Is log directory writable?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_version' => array( - 'description' => __( 'WordPress version.', 'woocommerce' ), + 'description' => __( 'WordPress version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_multisite' => array( - 'description' => __( 'Is WordPress multisite?', 'woocommerce' ), + 'description' => __( 'Is WordPress multisite?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_memory_limit' => array( - 'description' => __( 'WordPress memory limit.', 'woocommerce' ), + 'description' => __( 'WordPress memory limit.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_debug_mode' => array( - 'description' => __( 'Is WordPress debug mode active?', 'woocommerce' ), + 'description' => __( 'Is WordPress debug mode active?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_cron' => array( - 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce' ), + 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'language' => array( - 'description' => __( 'WordPress language.', 'woocommerce' ), + 'description' => __( 'WordPress language.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'server_info' => array( - 'description' => __( 'Server info.', 'woocommerce' ), + 'description' => __( 'Server info.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'php_version' => array( - 'description' => __( 'PHP version.', 'woocommerce' ), + 'description' => __( 'PHP version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'php_post_max_size' => array( - 'description' => __( 'PHP post max size.', 'woocommerce' ), + 'description' => __( 'PHP post max size.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'php_max_execution_time' => array( - 'description' => __( 'PHP max execution time.', 'woocommerce' ), + 'description' => __( 'PHP max execution time.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'php_max_input_vars' => array( - 'description' => __( 'PHP max input vars.', 'woocommerce' ), + 'description' => __( 'PHP max input vars.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'curl_version' => array( - 'description' => __( 'cURL version.', 'woocommerce' ), + 'description' => __( 'cURL version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'suhosin_installed' => array( - 'description' => __( 'Is SUHOSIN installed?', 'woocommerce' ), + 'description' => __( 'Is SUHOSIN installed?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'max_upload_size' => array( - 'description' => __( 'Max upload size.', 'woocommerce' ), + 'description' => __( 'Max upload size.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'mysql_version' => array( - 'description' => __( 'MySQL version.', 'woocommerce' ), + 'description' => __( 'MySQL version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'mysql_version_string' => array( - 'description' => __( 'MySQL version string.', 'woocommerce' ), + 'description' => __( 'MySQL version string.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'default_timezone' => array( - 'description' => __( 'Default timezone.', 'woocommerce' ), + 'description' => __( 'Default timezone.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'fsockopen_or_curl_enabled' => array( - 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce' ), + 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'soapclient_enabled' => array( - 'description' => __( 'Is SoapClient class enabled?', 'woocommerce' ), + 'description' => __( 'Is SoapClient class enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'domdocument_enabled' => array( - 'description' => __( 'Is DomDocument class enabled?', 'woocommerce' ), + 'description' => __( 'Is DomDocument class enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'gzip_enabled' => array( - 'description' => __( 'Is GZip enabled?', 'woocommerce' ), + 'description' => __( 'Is GZip enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'mbstring_enabled' => array( - 'description' => __( 'Is mbstring enabled?', 'woocommerce' ), + 'description' => __( 'Is mbstring enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_post_successful' => array( - 'description' => __( 'Remote POST successful?', 'woocommerce' ), + 'description' => __( 'Remote POST successful?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_post_response' => array( - 'description' => __( 'Remote POST response.', 'woocommerce' ), + 'description' => __( 'Remote POST response.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_get_successful' => array( - 'description' => __( 'Remote GET successful?', 'woocommerce' ), + 'description' => __( 'Remote GET successful?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_get_response' => array( - 'description' => __( 'Remote GET response.', 'woocommerce' ), + 'description' => __( 'Remote GET response.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, @@ -298,31 +298,31 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'database' => array( - 'description' => __( 'Database.', 'woocommerce' ), + 'description' => __( 'Database.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'wc_database_version' => array( - 'description' => __( 'WC database version.', 'woocommerce' ), + 'description' => __( 'WC database version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'database_prefix' => array( - 'description' => __( 'Database prefix.', 'woocommerce' ), + 'description' => __( 'Database prefix.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'maxmind_geoip_database' => array( - 'description' => __( 'MaxMind GeoIP database.', 'woocommerce' ), + 'description' => __( 'MaxMind GeoIP database.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'database_tables' => array( - 'description' => __( 'Database tables.', 'woocommerce' ), + 'description' => __( 'Database tables.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -333,7 +333,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'active_plugins' => array( - 'description' => __( 'Active plugins.', 'woocommerce' ), + 'description' => __( 'Active plugins.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -342,7 +342,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'inactive_plugins' => array( - 'description' => __( 'Inactive plugins.', 'woocommerce' ), + 'description' => __( 'Inactive plugins.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -351,7 +351,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'dropins_mu_plugins' => array( - 'description' => __( 'Dropins & MU plugins.', 'woocommerce' ), + 'description' => __( 'Dropins & MU plugins.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -360,62 +360,62 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'theme' => array( - 'description' => __( 'Theme.', 'woocommerce' ), + 'description' => __( 'Theme.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'name' => array( - 'description' => __( 'Theme name.', 'woocommerce' ), + 'description' => __( 'Theme name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'version' => array( - 'description' => __( 'Theme version.', 'woocommerce' ), + 'description' => __( 'Theme version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'version_latest' => array( - 'description' => __( 'Latest version of theme.', 'woocommerce' ), + 'description' => __( 'Latest version of theme.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'author_url' => array( - 'description' => __( 'Theme author URL.', 'woocommerce' ), + 'description' => __( 'Theme author URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'is_child_theme' => array( - 'description' => __( 'Is this theme a child theme?', 'woocommerce' ), + 'description' => __( 'Is this theme a child theme?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_woocommerce_support' => array( - 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ), + 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_woocommerce_file' => array( - 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ), + 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_outdated_templates' => array( - 'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ), + 'description' => __( 'Does this theme have outdated templates?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'overrides' => array( - 'description' => __( 'Template overrides.', 'woocommerce' ), + 'description' => __( 'Template overrides.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -424,19 +424,19 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'parent_name' => array( - 'description' => __( 'Parent theme name.', 'woocommerce' ), + 'description' => __( 'Parent theme name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'parent_version' => array( - 'description' => __( 'Parent theme version.', 'woocommerce' ), + 'description' => __( 'Parent theme version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'parent_author_url' => array( - 'description' => __( 'Parent theme author URL.', 'woocommerce' ), + 'description' => __( 'Parent theme author URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), @@ -445,67 +445,67 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'settings' => array( - 'description' => __( 'Settings.', 'woocommerce' ), + 'description' => __( 'Settings.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'api_enabled' => array( - 'description' => __( 'REST API enabled?', 'woocommerce' ), + 'description' => __( 'REST API enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'force_ssl' => array( - 'description' => __( 'SSL forced?', 'woocommerce' ), + 'description' => __( 'SSL forced?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'currency' => array( - 'description' => __( 'Currency.', 'woocommerce' ), + 'description' => __( 'Currency.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'currency_symbol' => array( - 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'currency_position' => array( - 'description' => __( 'Currency position.', 'woocommerce' ), + 'description' => __( 'Currency position.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'thousand_separator' => array( - 'description' => __( 'Thousand separator.', 'woocommerce' ), + 'description' => __( 'Thousand separator.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'decimal_separator' => array( - 'description' => __( 'Decimal separator.', 'woocommerce' ), + 'description' => __( 'Decimal separator.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'number_of_decimals' => array( - 'description' => __( 'Number of decimals.', 'woocommerce' ), + 'description' => __( 'Number of decimals.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'geolocation_enabled' => array( - 'description' => __( 'Geolocation enabled?', 'woocommerce' ), + 'description' => __( 'Geolocation enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'taxonomies' => array( - 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce' ), + 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -514,7 +514,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'product_visibility_terms' => array( - 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce' ), + 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -525,19 +525,19 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'security' => array( - 'description' => __( 'Security.', 'woocommerce' ), + 'description' => __( 'Security.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'secure_connection' => array( - 'description' => __( 'Is the connection to your store secure?', 'woocommerce' ), + 'description' => __( 'Is the connection to your store secure?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'hide_errors' => array( - 'description' => __( 'Hide errors from visitors?', 'woocommerce' ), + 'description' => __( 'Hide errors from visitors?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, @@ -545,7 +545,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'pages' => array( - 'description' => __( 'WooCommerce pages.', 'woocommerce' ), + 'description' => __( 'WooCommerce pages.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -593,7 +593,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { $curl_version = curl_version(); $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; } elseif ( extension_loaded( 'curl' ) ) { - $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); + $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce-rest-api' ); } // WP memory limit. @@ -744,7 +744,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. */ $tables = array( - 'woocommerce' => array_fill_keys( $core_tables, false ), + 'woocommerce-rest-api' => array_fill_keys( $core_tables, false ), 'other' => array(), ); @@ -760,7 +760,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { continue; } - $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce' : 'other'; + $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce-rest-api' : 'other'; $tables[ $table_type ][ $table->name ] = array( 'data' => $table->data, @@ -1001,7 +1001,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ), 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), 'is_child_theme' => is_child_theme(), - 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), + 'has_woocommerce_support' => current_theme_supports( 'woocommerce-rest-api' ), 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), 'has_outdated_templates' => $outdated_templates, 'overrides' => $override_files, @@ -1077,23 +1077,23 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { public function get_pages() { // WC pages to check against. $check_pages = array( - _x( 'Shop base', 'Page setting', 'woocommerce' ) => array( + _x( 'Shop base', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_shop_page_id', 'shortcode' => '', ), - _x( 'Cart', 'Page setting', 'woocommerce' ) => array( + _x( 'Cart', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_cart_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', ), - _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( + _x( 'Checkout', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_checkout_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', ), - _x( 'My account', 'Page setting', 'woocommerce' ) => array( + _x( 'My account', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_myaccount_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', ), - _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( + _x( 'Terms and conditions', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_terms_page_id', 'shortcode' => '', ), diff --git a/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php b/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php index 778a805d1e2..30639073e92 100644 --- a/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php @@ -67,32 +67,32 @@ class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliverie 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'duration' => array( - 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'summary' => array( - 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'request_url' => array( - 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'request_headers' => array( - 'description' => __( 'Request headers.', 'woocommerce' ), + 'description' => __( 'Request headers.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -101,25 +101,25 @@ class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliverie ), ), 'request_body' => array( - 'description' => __( 'Request body.', 'woocommerce' ), + 'description' => __( 'Request body.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_code' => array( - 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_message' => array( - 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_headers' => array( - 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -128,19 +128,19 @@ class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliverie ), ), 'response_body' => array( - 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), + 'description' => __( 'The response body from the receiving server.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the webhook delivery was logged, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the webhook delivery was logged, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php b/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php index ede2c1d121a..d30967f2392 100644 --- a/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php @@ -36,7 +36,7 @@ class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller { $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $data = array( @@ -95,42 +95,42 @@ class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), + 'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Webhook status.', 'woocommerce' ), + 'description' => __( 'Webhook status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'active', 'enum' => array_keys( wc_get_webhook_statuses() ), 'context' => array( 'view', 'edit' ), ), 'topic' => array( - 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'resource' => array( - 'description' => __( 'Webhook resource.', 'woocommerce' ), + 'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'event' => array( - 'description' => __( 'Webhook event.', 'woocommerce' ), + 'description' => __( 'Webhook event.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hooks' => array( - 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -139,37 +139,37 @@ class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller { ), ), 'delivery_url' => array( - 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'secret' => array( - 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-controller.php b/src/Controllers/Version3/class-wc-rest-controller.php index 0c7278ab2cd..4fa75d21259 100644 --- a/src/Controllers/Version3/class-wc-rest-controller.php +++ b/src/Controllers/Version3/class-wc-rest-controller.php @@ -110,7 +110,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { if ( $total > $limit ) { /* translators: %s: items limit */ - return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); + return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce-rest-api' ), $limit ), array( 'status' => 413 ) ); } return true; @@ -254,7 +254,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { if ( array_key_exists( $value, $setting['options'] ) ) { return $value; } else { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -272,7 +272,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { } if ( ! is_array( $values ) ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $final_values = array(); @@ -295,7 +295,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { */ public function validate_setting_image_width_field( $values, $setting ) { if ( ! is_array( $values ) ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $current = $setting['value']; @@ -338,7 +338,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; return $value; } else { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -398,7 +398,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { 'type' => 'object', 'properties' => array( 'create' => array( - 'description' => __( 'List of created resources.', 'woocommerce' ), + 'description' => __( 'List of created resources.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -406,7 +406,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { ), ), 'update' => array( - 'description' => __( 'List of updated resources.', 'woocommerce' ), + 'description' => __( 'List of updated resources.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -414,7 +414,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { ), ), 'delete' => array( - 'description' => __( 'List of delete resources.', 'woocommerce' ), + 'description' => __( 'List of delete resources.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( diff --git a/src/Controllers/Version3/class-wc-rest-crud-controller.php b/src/Controllers/Version3/class-wc-rest-crud-controller.php index 5733ddbb37d..1c66e9bbd20 100644 --- a/src/Controllers/Version3/class-wc-rest-crud-controller.php +++ b/src/Controllers/Version3/class-wc-rest-crud-controller.php @@ -40,7 +40,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { */ protected function get_object( $id ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce-rest-api' ), __METHOD__ ), array( 'status' => 405 ) ); } /** @@ -53,7 +53,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -69,7 +69,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -85,7 +85,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -111,7 +111,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { */ protected function prepare_object_for_response( $object, $request ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce-rest-api' ), __METHOD__ ), array( 'status' => 405 ) ); } /** @@ -124,7 +124,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { */ protected function prepare_object_for_database( $request, $creating = false ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce-rest-api' ), __METHOD__ ), array( 'status' => 405 ) ); } /** @@ -137,7 +137,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $data = $this->prepare_object_for_response( $object, $request ); @@ -185,7 +185,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $object = $this->save_object( $request, true ); @@ -232,7 +232,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $object = $this->save_object( $request, false ); @@ -415,7 +415,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $result = false; if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); @@ -432,7 +432,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -446,14 +446,14 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( is_callable( array( $object, 'get_status' ) ) ) { if ( 'trash' === $object->get_status() ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); } $object->delete(); @@ -463,7 +463,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -509,7 +509,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $params['context']['default'] = 'view'; $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -517,7 +517,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -526,25 +526,25 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['search'] = array( - 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), + 'description' => __( 'Limit results to those matching a string.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), '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' ), + 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -553,7 +553,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -562,20 +562,20 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), 'validate_callback' => 'rest_validate_request_arg', ); $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -590,7 +590,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { if ( $this->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -599,7 +599,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'default' => array(), ); $params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', diff --git a/src/Controllers/Version3/class-wc-rest-customers-controller.php b/src/Controllers/Version3/class-wc-rest-customers-controller.php index b577fe89792..65ce592cd55 100644 --- a/src/Controllers/Version3/class-wc-rest-customers-controller.php +++ b/src/Controllers/Version3/class-wc-rest-customers-controller.php @@ -76,43 +76,43 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce' ), + 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -120,7 +120,7 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { ), ), 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce' ), + 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -128,13 +128,13 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { ), ), 'role' => array( - 'description' => __( 'Customer role.', 'woocommerce' ), + 'description' => __( 'Customer role.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce' ), + 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -142,157 +142,157 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { ), ), 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce' ), + 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce' ), + 'description' => __( 'Email address.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce' ), + 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'is_paying_customer' => array( - 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), + 'description' => __( 'Is the customer a paying customer?', 'woocommerce-rest-api' ), 'type' => 'bool', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), diff --git a/src/Controllers/Version3/class-wc-rest-data-continents-controller.php b/src/Controllers/Version3/class-wc-rest-data-continents-controller.php index 37d3a55630d..7b79f969397 100644 --- a/src/Controllers/Version3/class-wc-rest-data-continents-controller.php +++ b/src/Controllers/Version3/class-wc-rest-data-continents-controller.php @@ -56,7 +56,7 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'continent' => array( - 'description' => __( '2 character continent code.', 'woocommerce' ), + 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -182,7 +182,7 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { public function get_item( $request ) { $data = $this->get_continent( strtoupper( $request['location'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -247,19 +247,19 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( '2 character continent code.', 'woocommerce' ), + 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of continent.', 'woocommerce' ), + 'description' => __( 'Full name of continent.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'countries' => array( 'type' => 'array', - 'description' => __( 'List of countries on this continent.', 'woocommerce' ), + 'description' => __( 'List of countries on this continent.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -269,49 +269,49 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'currency_code' => array( 'type' => 'string', - 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce' ), + 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'currency_pos' => array( 'type' => 'string', - 'description' => __( 'Currency symbol position for this country.', 'woocommerce' ), + 'description' => __( 'Currency symbol position for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'decimal_sep' => array( 'type' => 'string', - 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce' ), + 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'dimension_unit' => array( 'type' => 'string', - 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce' ), + 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce' ), + 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'num_decimals' => array( 'type' => 'integer', - 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce' ), + 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'states' => array( 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -321,13 +321,13 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce' ), + 'description' => __( 'State code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce' ), + 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), @@ -336,13 +336,13 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { ), 'thousand_sep' => array( 'type' => 'string', - 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce' ), + 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'weight_unit' => array( 'type' => 'string', - 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce' ), + 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/src/Controllers/Version3/class-wc-rest-data-controller.php b/src/Controllers/Version3/class-wc-rest-data-controller.php index 67a69f025a5..e6b794a2ba7 100644 --- a/src/Controllers/Version3/class-wc-rest-data-controller.php +++ b/src/Controllers/Version3/class-wc-rest-data-controller.php @@ -58,7 +58,7 @@ class WC_REST_Data_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -72,7 +72,7 @@ class WC_REST_Data_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -90,15 +90,15 @@ class WC_REST_Data_Controller extends WC_REST_Controller { $resources = array( array( 'slug' => 'continents', - 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce' ), + 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce-rest-api' ), ), array( 'slug' => 'countries', - 'description' => __( 'List of supported states in a given country.', 'woocommerce' ), + 'description' => __( 'List of supported states in a given country.', 'woocommerce-rest-api' ), ), array( 'slug' => 'currencies', - 'description' => __( 'List of supported currencies.', 'woocommerce' ), + 'description' => __( 'List of supported currencies.', 'woocommerce-rest-api' ), ), ); @@ -165,13 +165,13 @@ class WC_REST_Data_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'Data resource ID.', 'woocommerce' ), + 'description' => __( 'Data resource ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Data resource description.', 'woocommerce' ), + 'description' => __( 'Data resource description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-data-countries-controller.php b/src/Controllers/Version3/class-wc-rest-data-countries-controller.php index d8219a77439..aaed5e2f30d 100644 --- a/src/Controllers/Version3/class-wc-rest-data-countries-controller.php +++ b/src/Controllers/Version3/class-wc-rest-data-countries-controller.php @@ -56,7 +56,7 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'location' => array( - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -130,7 +130,7 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { public function get_item( $request ) { $data = $this->get_country( strtoupper( $request['location'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -197,19 +197,19 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce' ), + 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'states' => array( 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -219,13 +219,13 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce' ), + 'description' => __( 'State code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce' ), + 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php b/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php index 574d9d4c571..eb62a89f048 100644 --- a/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php +++ b/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php @@ -63,7 +63,7 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'location' => array( - 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -123,7 +123,7 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { public function get_item( $request ) { $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -197,19 +197,19 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of currency.', 'woocommerce' ), + 'description' => __( 'Full name of currency.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'symbol' => array( 'type' => 'string', - 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/src/Controllers/Version3/class-wc-rest-order-notes-controller.php b/src/Controllers/Version3/class-wc-rest-order-notes-controller.php index 738961591e4..6015634664b 100644 --- a/src/Controllers/Version3/class-wc-rest-order-notes-controller.php +++ b/src/Controllers/Version3/class-wc-rest-order-notes-controller.php @@ -35,7 +35,7 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { public function prepare_item_for_response( $note, $request ) { $data = array( 'id' => (int) $note->comment_ID, - 'author' => __( 'WooCommerce', 'woocommerce' ) === $note->comment_author ? 'system' : $note->comment_author, + 'author' => __( 'woocommerce-rest-api', 'woocommerce-rest-api' ) === $note->comment_author ? 'system' : $note->comment_author, 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), 'note' => $note->comment_content, @@ -70,20 +70,20 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } // Create the note. $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); if ( ! $note_id ) { - return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $note = get_comment( $note_id ); @@ -119,42 +119,42 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'author' => array( - 'description' => __( 'Order note author.', 'woocommerce' ), + 'description' => __( 'Order note author.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'note' => array( - 'description' => __( 'Order note content.', 'woocommerce' ), + 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_note' => array( - 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'added_by_user' => array( - 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce' ), + 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'edit' ), diff --git a/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php b/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php index 98731f5756c..865634affe0 100644 --- a/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php +++ b/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php @@ -37,11 +37,11 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controll $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); } if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); } // Create the refund. @@ -61,7 +61,7 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controll } if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); } if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { diff --git a/src/Controllers/Version3/class-wc-rest-orders-controller.php b/src/Controllers/Version3/class-wc-rest-orders-controller.php index 5e4ea622fc8..1d2ad09d5d7 100644 --- a/src/Controllers/Version3/class-wc-rest-orders-controller.php +++ b/src/Controllers/Version3/class-wc-rest-orders-controller.php @@ -47,7 +47,7 @@ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller { if ( is_array( $item ) ) { if ( empty( $item['id'] ) ) { if ( empty( $item['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); } $results = $order->apply_coupon( wc_clean( $item['code'] ) ); @@ -157,7 +157,7 @@ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller { if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { // Make sure customer exists. if ( false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); } // Make sure customer is part of blog. @@ -257,7 +257,7 @@ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller { $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'string', diff --git a/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php b/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php index 5c0eb9c8ac9..f48b155f3dd 100644 --- a/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php +++ b/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php @@ -114,23 +114,23 @@ class WC_REST_Payment_Gateways_Controller extends WC_REST_Payment_Gateways_V2_Co 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'description' => __( 'Payment gateway ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'description' => __( 'Payment gateway sort order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -138,24 +138,24 @@ class WC_REST_Payment_Gateways_Controller extends WC_REST_Payment_Gateways_V2_Co ), ), 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'description' => __( 'Payment gateway enabled status.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'description' => __( 'Payment gateway method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'description' => __( 'Payment gateway method description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_supports' => array( - 'description' => __( 'Supported features for this payment gateway.', 'woocommerce' ), + 'description' => __( 'Supported features for this payment gateway.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -164,54 +164,54 @@ class WC_REST_Payment_Gateways_Controller extends WC_REST_Payment_Gateways_V2_Co ), ), 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'description' => __( 'Payment gateway settings.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), + 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), + 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-posts-controller.php b/src/Controllers/Version3/class-wc-rest-posts-controller.php index 078f5cee4dd..7c04b058923 100644 --- a/src/Controllers/Version3/class-wc-rest-posts-controller.php +++ b/src/Controllers/Version3/class-wc-rest-posts-controller.php @@ -54,7 +54,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -68,7 +68,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -84,7 +84,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -100,7 +100,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -116,7 +116,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -131,7 +131,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -148,9 +148,9 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( $id ); if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $post, $request ); @@ -172,7 +172,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -255,9 +255,9 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( $id ); if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -418,7 +418,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( $id ); if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0; @@ -435,7 +435,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -448,13 +448,13 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( 'trash' === $post->post_status ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); } // (Note that internally this falls through to `wp_delete_post` if @@ -464,7 +464,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -621,19 +621,19 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), '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' ), + 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -642,7 +642,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -651,20 +651,20 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), 'validate_callback' => 'rest_validate_request_arg', ); $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -681,7 +681,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -690,7 +690,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { 'default' => array(), ); $params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -703,7 +703,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( 'wc/v1' === $this->namespace ) { $params['filter'] = array( 'type' => 'object', - 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce' ), + 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce-rest-api' ), ); } diff --git a/src/Controllers/Version3/class-wc-rest-product-categories-controller.php b/src/Controllers/Version3/class-wc-rest-product-categories-controller.php index c69f5640a99..63ced695fec 100644 --- a/src/Controllers/Version3/class-wc-rest-product-categories-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-categories-controller.php @@ -100,13 +100,13 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), + 'description' => __( 'Category name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -114,7 +114,7 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -122,12 +122,12 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V ), ), 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -135,71 +135,71 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V ), ), 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'default', 'enum' => array( 'default', 'products', 'subcategories', 'both' ), 'context' => array( 'view', 'edit' ), ), 'image' => array( - 'description' => __( 'Image data.', 'woocommerce' ), + 'description' => __( 'Image data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php b/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php index 7b4a12d2c6e..aee1016454f 100644 --- a/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php @@ -52,23 +52,23 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'product_id' => array( 'required' => true, - 'description' => __( 'Unique identifier for the product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'review' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce' ), + 'description' => __( 'Review content.', 'woocommerce-rest-api' ), ), 'reviewer' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + 'description' => __( 'Name of the reviewer.', 'woocommerce-rest-api' ), ), 'reviewer_email' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + 'description' => __( 'Email of the reviewer.', 'woocommerce-rest-api' ), ), ) ), @@ -81,7 +81,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -107,7 +107,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -136,7 +136,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -153,7 +153,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -167,7 +167,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -184,7 +184,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'edit', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -201,7 +201,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'delete', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -215,7 +215,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -371,13 +371,13 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $prepared_review = $this->prepare_item_for_database( $request ); @@ -391,7 +391,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). */ if ( empty( $prepared_review['comment_content'] ) ) { - return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). @@ -416,7 +416,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $prepared_review['comment_parent'] = 0; @@ -457,7 +457,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); if ( ! $review_id ) { - return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { @@ -527,7 +527,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $id = (int) $review->comment_ID; if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { - return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $prepared_args = $this->prepare_item_for_database( $request ); @@ -537,7 +537,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { if ( ! empty( $prepared_args['comment_post_ID'] ) ) { if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } } @@ -546,7 +546,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $change = $this->handle_status_param( $request['status'], $id ); if ( ! $change ) { - return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } } elseif ( ! empty( $prepared_args ) ) { if ( is_wp_error( $prepared_args ) ) { @@ -554,7 +554,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { } if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { - return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $prepared_args['comment_ID'] = $id; @@ -562,13 +562,13 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); if ( false === $updated ) { - return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { @@ -639,11 +639,11 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { // If this type doesn't support trashing, error out. if ( ! $supports_trash ) { /* translators: %s: force=true */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce' ), 'force=true' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce-rest-api' ), 'force=true' ), array( 'status' => 501 ) ); } if ( 'trash' === $review->comment_approved ) { - return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce-rest-api' ), array( 'status' => 410 ) ); } $result = wp_trash_comment( $review->comment_ID ); @@ -652,7 +652,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { } if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -828,48 +828,48 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Status of the review.', 'woocommerce' ), + 'description' => __( 'Status of the review.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'approved', 'enum' => array( 'approved', 'hold', 'spam', 'unspam', 'trash', 'untrash' ), 'context' => array( 'view', 'edit' ), ), 'reviewer' => array( - 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'reviewer_email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce' ), + 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -877,12 +877,12 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ), ), 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -897,14 +897,14 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { foreach ( $avatar_sizes as $size ) { $avatar_properties[ $size ] = array( /* translators: %d: avatar image size in pixels */ - 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce' ), $size ), + 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce-rest-api' ), $size ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ); } $schema['properties']['reviewer_avatar_urls'] = array( - 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce' ), + 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -926,17 +926,17 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', ); $params['before'] = array( - 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -944,7 +944,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'default' => array(), ); $params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -952,11 +952,11 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'default' => array(), ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( @@ -965,7 +965,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ), ); $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'date_gmt', 'enum' => array( @@ -977,14 +977,14 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ), ); $params['reviewer'] = array( - 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $params['reviewer_exclude'] = array( - 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -992,13 +992,13 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ); $params['reviewer_email'] = array( 'default' => null, - 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce' ), + 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce-rest-api' ), 'format' => 'email', 'type' => 'string', ); $params['product'] = array( 'default' => array(), - 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1006,7 +1006,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ); $params['status'] = array( 'default' => 'approved', - 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce-rest-api' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', 'enum' => array( @@ -1040,7 +1040,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ protected function get_review( $id ) { $id = (int) $id; - $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); if ( 0 >= $id ) { return $error; @@ -1055,7 +1055,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $post = get_post( (int) $review->comment_post_ID ); if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } } diff --git a/src/Controllers/Version3/class-wc-rest-product-variations-controller.php b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php index 65cc4f11520..0477e818df9 100644 --- a/src/Controllers/Version3/class-wc-rest-product-variations-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php @@ -234,7 +234,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V if ( ! $parent ) { return new WP_Error( // Translators: %d parent ID. - "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $variation->get_parent_id() ), array( + "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce-rest-api' ), $variation->get_parent_id() ), array( 'status' => 404, ) ); @@ -368,7 +368,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V if ( ! wp_attachment_is_image( $attachment_id ) ) { /* translators: %s: attachment ID */ - throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); } $variation->set_image_id( $attachment_id ); @@ -405,126 +405,126 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce' ), + 'description' => __( 'Variation description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce' ), + 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce' ), + 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Variation status.', 'woocommerce' ), + 'description' => __( 'Variation status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_keys( get_post_statuses() ), 'context' => array( 'view', 'edit' ), ), 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), + 'description' => __( 'File ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -532,179 +532,179 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), + 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'instock', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce' ), + 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), + 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -712,30 +712,30 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -848,7 +848,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ); $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'sanitize_callback' => 'sanitize_text_field', diff --git a/src/Controllers/Version3/class-wc-rest-products-controller.php b/src/Controllers/Version3/class-wc-rest-products-controller.php index de21777ca9b..5dcc4cb5e9a 100644 --- a/src/Controllers/Version3/class-wc-rest-products-controller.php +++ b/src/Controllers/Version3/class-wc-rest-products-controller.php @@ -250,7 +250,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { if ( ! wp_attachment_is_image( $attachment_id ) ) { /* translators: %s: image ID */ - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); } $featured_image = $product->get_image_id(); @@ -313,7 +313,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { if ( 'variation' === $product->get_type() ) { return new WP_Error( - "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( + "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404, ) ); @@ -698,183 +698,183 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce' ), + 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce' ), + 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), + 'description' => __( 'Product type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'simple', 'enum' => array_keys( wc_get_product_types() ), 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), 'context' => array( 'view', 'edit' ), ), 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce' ), + 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'visible', 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Product description.', 'woocommerce' ), + 'description' => __( 'Product description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce' ), + 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce' ), + 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce' ), + 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce' ), + 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), + 'description' => __( 'File ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -882,157 +882,157 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), + 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'instock', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1041,7 +1041,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'readonly' => true, ), 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'description' => __( 'List of up-sell products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1049,7 +1049,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'context' => array( 'view', 'edit' ), ), 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1057,35 +1057,35 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce' ), + 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce' ), + 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), + 'description' => __( 'Category name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce' ), + 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1094,25 +1094,25 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce' ), + 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce' ), + 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce' ), + 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce' ), + 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1121,54 +1121,54 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'images' => array( - 'description' => __( 'List of images.', 'woocommerce' ), + 'description' => __( 'List of images.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1176,41 +1176,41 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), + 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce' ), + 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -1221,24 +1221,24 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1246,7 +1246,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'description' => __( 'List of variations IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -1255,7 +1255,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'readonly' => true, ), 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1264,30 +1264,30 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'readonly' => true, ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1310,7 +1310,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { unset( $params['in_stock'] ); $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'sanitize_callback' => 'sanitize_text_field', diff --git a/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php index b6bfe4304b3..85d4ae34795 100644 --- a/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php @@ -118,19 +118,19 @@ class WC_REST_Report_Coupons_Totals_Controller extends WC_REST_Reports_Controlle 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Coupon type name.', 'woocommerce' ), + 'description' => __( 'Coupon type name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of coupons.', 'woocommerce' ), + 'description' => __( 'Amount of coupons.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php index 929a2f3c73a..38867bd7135 100644 --- a/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php @@ -71,12 +71,12 @@ class WC_REST_Report_Customers_Totals_Controller extends WC_REST_Reports_Control $data = array( array( 'slug' => 'paying', - 'name' => __( 'Paying customer', 'woocommerce' ), + 'name' => __( 'Paying customer', 'woocommerce-rest-api' ), 'total' => $total_paying, ), array( 'slug' => 'non_paying', - 'name' => __( 'Non-paying customer', 'woocommerce' ), + 'name' => __( 'Non-paying customer', 'woocommerce-rest-api' ), 'total' => $total_customers - $total_paying, ), ); @@ -129,19 +129,19 @@ class WC_REST_Report_Customers_Totals_Controller extends WC_REST_Reports_Control 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Customer type name.', 'woocommerce' ), + 'description' => __( 'Customer type name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of customers.', 'woocommerce' ), + 'description' => __( 'Amount of customers.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php index f70ebe6a5a4..4c7c9289806 100644 --- a/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php @@ -102,19 +102,19 @@ class WC_REST_Report_Orders_Totals_Controller extends WC_REST_Reports_Controller 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Order status name.', 'woocommerce' ), + 'description' => __( 'Order status name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of orders.', 'woocommerce' ), + 'description' => __( 'Amount of orders.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php index c45671c50d9..d855b6298b9 100644 --- a/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php @@ -108,19 +108,19 @@ class WC_REST_Report_Products_Totals_Controller extends WC_REST_Reports_Controll 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product type name.', 'woocommerce' ), + 'description' => __( 'Product type name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of products.', 'woocommerce' ), + 'description' => __( 'Amount of products.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php index c7b5cf2249a..d585d586d27 100644 --- a/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php +++ b/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php @@ -54,7 +54,7 @@ class WC_REST_Report_Reviews_Totals_Controller extends WC_REST_Reports_Controlle $data[] = array( 'slug' => 'rated_' . $i . '_out_of_5', /* translators: %s: average rating */ - 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $i ), + 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce-rest-api' ), $i ), 'total' => (int) get_comments( $query_data ), ); } @@ -107,19 +107,19 @@ class WC_REST_Report_Reviews_Totals_Controller extends WC_REST_Reports_Controlle 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Review type name.', 'woocommerce' ), + 'description' => __( 'Review type name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of reviews.', 'woocommerce' ), + 'description' => __( 'Amount of reviews.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-reports-controller.php b/src/Controllers/Version3/class-wc-rest-reports-controller.php index 67a37e697da..2ae97fbb4c0 100644 --- a/src/Controllers/Version3/class-wc-rest-reports-controller.php +++ b/src/Controllers/Version3/class-wc-rest-reports-controller.php @@ -36,35 +36,35 @@ class WC_REST_Reports_Controller extends WC_REST_Reports_V2_Controller { $reports[] = array( 'slug' => 'orders/totals', - 'description' => __( 'Orders totals.', 'woocommerce' ), + 'description' => __( 'Orders totals.', 'woocommerce-rest-api' ), ); $reports[] = array( 'slug' => 'products/totals', - 'description' => __( 'Products totals.', 'woocommerce' ), + 'description' => __( 'Products totals.', 'woocommerce-rest-api' ), ); $reports[] = array( 'slug' => 'customers/totals', - 'description' => __( 'Customers totals.', 'woocommerce' ), + 'description' => __( 'Customers totals.', 'woocommerce-rest-api' ), ); $reports[] = array( 'slug' => 'coupons/totals', - 'description' => __( 'Coupons totals.', 'woocommerce' ), + 'description' => __( 'Coupons totals.', 'woocommerce-rest-api' ), ); $reports[] = array( 'slug' => 'reviews/totals', - 'description' => __( 'Reviews totals.', 'woocommerce' ), + 'description' => __( 'Reviews totals.', 'woocommerce-rest-api' ), ); $reports[] = array( 'slug' => 'categories/totals', - 'description' => __( 'Categories totals.', 'woocommerce' ), + 'description' => __( 'Categories totals.', 'woocommerce-rest-api' ), ); $reports[] = array( 'slug' => 'tags/totals', - 'description' => __( 'Tags totals.', 'woocommerce' ), + 'description' => __( 'Tags totals.', 'woocommerce-rest-api' ), ); $reports[] = array( 'slug' => 'attributes/totals', - 'description' => __( 'Attributes totals.', 'woocommerce' ), + 'description' => __( 'Attributes totals.', 'woocommerce-rest-api' ), ); return $reports; diff --git a/src/Controllers/Version3/class-wc-rest-setting-options-controller.php b/src/Controllers/Version3/class-wc-rest-setting-options-controller.php index a09e1fb5d72..b7255694912 100644 --- a/src/Controllers/Version3/class-wc-rest-setting-options-controller.php +++ b/src/Controllers/Version3/class-wc-rest-setting-options-controller.php @@ -73,13 +73,13 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont */ public function get_group_settings( $group_id ) { if ( empty( $group_id ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $filtered_settings = array(); @@ -162,7 +162,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', @@ -171,7 +171,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'group_id' => array( - 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ), + 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', @@ -180,7 +180,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -189,7 +189,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -198,18 +198,18 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), + 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -218,7 +218,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -227,7 +227,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), + 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -237,7 +237,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-settings-controller.php b/src/Controllers/Version3/class-wc-rest-settings-controller.php index 77aebd681d4..0762c090fd4 100644 --- a/src/Controllers/Version3/class-wc-rest-settings-controller.php +++ b/src/Controllers/Version3/class-wc-rest-settings-controller.php @@ -48,7 +48,7 @@ class WC_REST_Settings_Controller extends WC_REST_Settings_V2_Controller { */ 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 new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -80,27 +80,27 @@ class WC_REST_Settings_Controller extends WC_REST_Settings_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'description' => __( 'ID of parent grouping.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'description' => __( 'IDs for settings sub groups.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), diff --git a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php index 871c5199e31..250269663d0 100644 --- a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php +++ b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php @@ -44,7 +44,7 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller $zone = WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id ); if ( false === $zone ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $zone; @@ -58,11 +58,11 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function get_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -76,11 +76,11 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function create_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -94,11 +94,11 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function update_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -112,11 +112,11 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function delete_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; diff --git a/src/Controllers/Version3/class-wc-rest-terms-controller.php b/src/Controllers/Version3/class-wc-rest-terms-controller.php index 2422f99b286..5722aeb8b5d 100644 --- a/src/Controllers/Version3/class-wc-rest-terms-controller.php +++ b/src/Controllers/Version3/class-wc-rest-terms-controller.php @@ -52,7 +52,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { array( 'name' => array( 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), 'required' => true, ), ) @@ -68,7 +68,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -94,7 +94,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -130,7 +130,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -149,7 +149,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -168,7 +168,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -187,7 +187,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -206,7 +206,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -225,7 +225,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -242,7 +242,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { // Get taxonomy. $taxonomy = $this->get_taxonomy( $request ); if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } // Check permissions for a single term. @@ -251,7 +251,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { $term = get_term( $id, $taxonomy ); if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { - return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id ); @@ -390,7 +390,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $args['parent'] = $request['parent']; } @@ -487,7 +487,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $prepared_args['parent'] = $request['parent']; } @@ -536,7 +536,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $term = get_term( (int) $request['id'], $taxonomy ); @@ -545,7 +545,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { // Prevent deleting the default product category. if ( $default_category_id === (int) $request['id'] ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $request->set_param( 'context', 'edit' ); @@ -553,7 +553,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { $retval = wp_delete_term( $term->term_id, $term->taxonomy ); if ( ! $retval ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -701,7 +701,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -710,7 +710,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -720,14 +720,14 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { ); if ( ! $taxonomy->hierarchical ) { $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); } $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'asc', @@ -738,7 +738,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['orderby'] = array( - 'description' => __( 'Sort collection by resource attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by resource attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'name', @@ -754,27 +754,27 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['hide_empty'] = array( - 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce' ), + 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'validate_callback' => 'rest_validate_request_arg', ); if ( $taxonomy->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); } $params['product'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => null, 'validate_callback' => 'rest_validate_request_arg', ); $params['slug'] = array( - 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php index e28d3d27729..9916af122ed 100644 --- a/src/Controllers/Version4/AbstractController.php +++ b/src/Controllers/Version4/AbstractController.php @@ -94,7 +94,7 @@ abstract class AbstractController extends WP_REST_Controller { $routes['schema'] = [ $this, 'get_public_item_schema' ]; $routes['args'] = [ 'id' => [ - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ], ]; @@ -131,7 +131,7 @@ abstract class AbstractController extends WP_REST_Controller { 'args' => array( 'force' => array( 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), 'type' => 'boolean', ), ), @@ -171,7 +171,7 @@ abstract class AbstractController extends WP_REST_Controller { $permission = Permissions::user_can_list( $this->get_item_title() ); if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return $permission; @@ -188,7 +188,7 @@ abstract class AbstractController extends WP_REST_Controller { $permission = Permissions::user_can_create( $this->get_item_title() ); if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return $permission; @@ -205,7 +205,7 @@ abstract class AbstractController extends WP_REST_Controller { $permission = Permissions::user_can_read( $this->get_item_title(), $id ); if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return $permission; @@ -223,7 +223,7 @@ abstract class AbstractController extends WP_REST_Controller { $permission = Permissions::user_can_edit( $this->get_item_title(), $id ); if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return $permission; @@ -241,7 +241,7 @@ abstract class AbstractController extends WP_REST_Controller { $permission = Permissions::user_can_delete( $this->get_item_title(), $id ); if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return $permission; @@ -258,7 +258,7 @@ abstract class AbstractController extends WP_REST_Controller { $permission = Permissions::user_can_batch( $this->get_item_title() ); if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return $permission; diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php index ddc32658270..332ae8828b7 100644 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ b/src/Controllers/Version4/AbstractObjectsController.php @@ -68,7 +68,7 @@ abstract class AbstractObjectsController extends AbstractController { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $object, $request ); @@ -112,7 +112,7 @@ abstract class AbstractObjectsController extends AbstractController { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $object = $this->save_object( $request, true ); @@ -159,7 +159,7 @@ abstract class AbstractObjectsController extends AbstractController { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $object = $this->save_object( $request, false ); @@ -318,14 +318,14 @@ abstract class AbstractObjectsController extends AbstractController { $result = false; if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $supports_trash = $this->supports_trash( $object ); if ( ! Permissions::user_can_delete( $this->post_type, $object->get_id() ) ) { /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -339,13 +339,13 @@ abstract class AbstractObjectsController extends AbstractController { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( is_callable( array( $object, 'get_status' ) ) && 'trash' === $object->get_status() ) { /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + return new \WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); } else { $object->delete(); $result = is_callable( array( $object, 'get_status' ) ) ? 'trash' === $object->get_status() : true; @@ -354,7 +354,7 @@ abstract class AbstractObjectsController extends AbstractController { if ( ! $result ) { /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); } $response = new \WP_REST_Response(); @@ -428,7 +428,7 @@ abstract class AbstractObjectsController extends AbstractController { $params['context']['default'] = 'view'; $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -437,7 +437,7 @@ abstract class AbstractObjectsController extends AbstractController { ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -447,28 +447,28 @@ abstract class AbstractObjectsController extends AbstractController { ); $params['search'] = array( - 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), + 'description' => __( 'Limit results to those matching a string.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources created after a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources created after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); $params['before'] = array( - 'description' => __( 'Limit response to resources created before a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources created before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); $params['date_column'] = array( - 'description' => __( 'When limiting response using after/before, which date column to compare against.', 'woocommerce' ), + 'description' => __( 'When limiting response using after/before, which date column to compare against.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -481,14 +481,14 @@ abstract class AbstractObjectsController extends AbstractController { ); $params['modified_before'] = array( - 'description' => __( 'Limit response to resources modified before a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources modified before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -498,7 +498,7 @@ abstract class AbstractObjectsController extends AbstractController { ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -508,14 +508,14 @@ abstract class AbstractObjectsController extends AbstractController { ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), @@ -523,7 +523,7 @@ abstract class AbstractObjectsController extends AbstractController { ); $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -539,7 +539,7 @@ abstract class AbstractObjectsController extends AbstractController { if ( $this->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -549,7 +549,7 @@ abstract class AbstractObjectsController extends AbstractController { ); $params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -723,7 +723,7 @@ abstract class AbstractObjectsController extends AbstractController { $object = $this->get_object( $id ); if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return parent::get_item_permissions_check( $request ); @@ -741,7 +741,7 @@ abstract class AbstractObjectsController extends AbstractController { $object = $this->get_object( $id ); if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return parent::update_item_permissions_check( $request ); @@ -759,7 +759,7 @@ abstract class AbstractObjectsController extends AbstractController { $object = $this->get_object( $id ); if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return parent::delete_item_permissions_check( $request ); diff --git a/src/Controllers/Version4/AbstractShippingZonesController.php b/src/Controllers/Version4/AbstractShippingZonesController.php index 0a3a6809ba3..88f7e9d7f7e 100644 --- a/src/Controllers/Version4/AbstractShippingZonesController.php +++ b/src/Controllers/Version4/AbstractShippingZonesController.php @@ -44,7 +44,7 @@ abstract class AbstractShippingZonesController extends AbstractController { $zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id ); if ( false === $zone ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $zone; @@ -58,7 +58,7 @@ abstract class AbstractShippingZonesController extends AbstractController { */ public function get_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return parent::get_items_permissions_check( $request ); } @@ -71,7 +71,7 @@ abstract class AbstractShippingZonesController extends AbstractController { */ public function create_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return parent::create_item_permissions_check( $request ); } @@ -84,7 +84,7 @@ abstract class AbstractShippingZonesController extends AbstractController { */ public function update_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return parent::update_item_permissions_check( $request ); } @@ -97,7 +97,7 @@ abstract class AbstractShippingZonesController extends AbstractController { */ public function delete_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return parent::delete_item_permissions_check( $request ); } diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php index 2cb1366a42c..68a41e8418a 100644 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ b/src/Controllers/Version4/AbstractTermsContoller.php @@ -68,7 +68,7 @@ abstract class AbstractTermsContoller extends AbstractController { array( 'name' => array( 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), 'required' => true, ), ) @@ -85,7 +85,7 @@ abstract class AbstractTermsContoller extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -111,7 +111,7 @@ abstract class AbstractTermsContoller extends AbstractController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -234,7 +234,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new \WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $args['parent'] = $request['parent']; } @@ -331,7 +331,7 @@ abstract class AbstractTermsContoller extends AbstractController { } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new \WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $prepared_args['parent'] = $request['parent']; } @@ -380,7 +380,7 @@ abstract class AbstractTermsContoller extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $term = get_term( (int) $request['id'], $taxonomy ); @@ -389,7 +389,7 @@ abstract class AbstractTermsContoller extends AbstractController { // Prevent deleting the default product category. if ( $default_category_id === (int) $request['id'] ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $request->set_param( 'context', 'edit' ); @@ -397,7 +397,7 @@ abstract class AbstractTermsContoller extends AbstractController { $retval = wp_delete_term( $term->term_id, $term->taxonomy ); if ( ! $retval ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -545,7 +545,7 @@ abstract class AbstractTermsContoller extends AbstractController { $params['context']['default'] = 'view'; $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -554,7 +554,7 @@ abstract class AbstractTermsContoller extends AbstractController { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -564,14 +564,14 @@ abstract class AbstractTermsContoller extends AbstractController { ); if ( ! $taxonomy->hierarchical ) { $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); } $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'asc', @@ -582,7 +582,7 @@ abstract class AbstractTermsContoller extends AbstractController { 'validate_callback' => 'rest_validate_request_arg', ); $params['orderby'] = array( - 'description' => __( 'Sort collection by resource attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by resource attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'name', @@ -598,27 +598,27 @@ abstract class AbstractTermsContoller extends AbstractController { 'validate_callback' => 'rest_validate_request_arg', ); $params['hide_empty'] = array( - 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce' ), + 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'validate_callback' => 'rest_validate_request_arg', ); if ( $taxonomy->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); } $params['product'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => null, 'validate_callback' => 'rest_validate_request_arg', ); $params['slug'] = array( - 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php index bbca5237287..10dff13fc62 100644 --- a/src/Controllers/Version4/Coupons.php +++ b/src/Controllers/Version4/Coupons.php @@ -141,7 +141,7 @@ class Coupons extends AbstractObjectsController { // Validate required POST fields. if ( $creating && empty( $request['code'] ) ) { - return new \WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce-rest-api' ), 'code' ), array( 'status' => 400 ) ); } // Handle all writable props. @@ -156,7 +156,7 @@ class Coupons extends AbstractObjectsController { $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); if ( $id_from_code ) { - return new \WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $coupon->set_code( $coupon_code ); @@ -205,82 +205,82 @@ class Coupons extends AbstractObjectsController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the object.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), + 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'required' => true, ), 'amount' => array( - 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_type' => array( - 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'fixed_cart', 'enum' => array_keys( wc_get_coupon_types() ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Coupon description.', 'woocommerce' ), + 'description' => __( 'Coupon description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_expires' => array( - 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_expires_gmt' => array( - 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'usage_count' => array( - 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'individual_use' => array( - 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_ids' => array( - 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce' ), + 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -288,7 +288,7 @@ class Coupons extends AbstractObjectsController { 'context' => array( 'view', 'edit' ), ), 'excluded_product_ids' => array( - 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce' ), + 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -296,28 +296,28 @@ class Coupons extends AbstractObjectsController { 'context' => array( 'view', 'edit' ), ), 'usage_limit' => array( - 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'usage_limit_per_user' => array( - 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'limit_usage_to_x_items' => array( - 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'free_shipping' => array( - 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_categories' => array( - 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce' ), + 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -325,7 +325,7 @@ class Coupons extends AbstractObjectsController { 'context' => array( 'view', 'edit' ), ), 'excluded_product_categories' => array( - 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce' ), + 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -333,23 +333,23 @@ class Coupons extends AbstractObjectsController { 'context' => array( 'view', 'edit' ), ), 'exclude_sale_items' => array( - 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'minimum_amount' => array( - 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'maximum_amount' => array( - 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email_restrictions' => array( - 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -357,7 +357,7 @@ class Coupons extends AbstractObjectsController { 'context' => array( 'view', 'edit' ), ), 'used_by' => array( - 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -366,25 +366,25 @@ class Coupons extends AbstractObjectsController { 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -405,14 +405,14 @@ class Coupons extends AbstractObjectsController { $params = parent::get_collection_params(); $params['code'] = array( - 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['search'] = array( - 'description' => __( 'Limit results to coupons with codes matching a given string.', 'woocommerce' ), + 'description' => __( 'Limit results to coupons with codes matching a given string.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php index 6504eb9967d..c63fe2b875b 100644 --- a/src/Controllers/Version4/CustomerDownloads.php +++ b/src/Controllers/Version4/CustomerDownloads.php @@ -49,11 +49,11 @@ class CustomerDownloads extends AbstractController { $customer = get_user_by( 'id', (int) $request['customer_id'] ); if ( ! $customer ) { - return new \WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( ! Permissions::user_can_read( $this->resource_type, $customer->ID ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -137,79 +137,79 @@ class CustomerDownloads extends AbstractController { 'type' => 'object', 'properties' => array( 'download_id' => array( - 'description' => __( 'Download ID.', 'woocommerce' ), + 'description' => __( 'Download ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'download_url' => array( - 'description' => __( 'Download file URL.', 'woocommerce' ), + 'description' => __( 'Download file URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Downloadable product ID.', 'woocommerce' ), + 'description' => __( 'Downloadable product ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'product_name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'download_name' => array( - 'description' => __( 'Downloadable file name.', 'woocommerce' ), + 'description' => __( 'Downloadable file name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce' ), + 'description' => __( 'Order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce' ), + 'description' => __( 'Order key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'downloads_remaining' => array( - 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), + 'description' => __( 'Number of downloads remaining.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'access_expires' => array( - 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'access_expires_gmt' => array( - 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce' ), + 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File details.', 'woocommerce' ), + 'description' => __( 'File details.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php index d931c1b05f5..38688b23f0e 100644 --- a/src/Controllers/Version4/Customers.php +++ b/src/Controllers/Version4/Customers.php @@ -59,16 +59,16 @@ class Customers extends AbstractController { 'email' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'New user email address.', 'woocommerce' ), + 'description' => __( 'New user email address.', 'woocommerce-rest-api' ), ), 'username' => array( 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), - 'description' => __( 'New user username.', 'woocommerce' ), + 'description' => __( 'New user username.', 'woocommerce-rest-api' ), 'type' => 'string', ), 'password' => array( 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), - 'description' => __( 'New user password.', 'woocommerce' ), + 'description' => __( 'New user password.', 'woocommerce-rest-api' ), 'type' => 'string', ), ) @@ -85,7 +85,7 @@ class Customers extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -111,12 +111,12 @@ class Customers extends AbstractController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), 'reassign' => array( 'default' => 0, 'type' => 'integer', - 'description' => __( 'ID to reassign posts to.', 'woocommerce' ), + 'description' => __( 'ID to reassign posts to.', 'woocommerce-rest-api' ), ), ), ), @@ -223,7 +223,7 @@ class Customers extends AbstractController { public function create_item( $request ) { try { if ( ! empty( $request['id'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), 400 ); } $customer_request = new CustomerRequest( $request ); @@ -231,7 +231,7 @@ class Customers extends AbstractController { $customer->save(); if ( ! $customer->get_id() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce-rest-api' ), 400 ); } $this->update_additional_fields_for_object( $customer, $request ); @@ -268,7 +268,7 @@ class Customers extends AbstractController { $customer = new \WC_Customer( $id ); if ( empty( $id ) || ! $customer->get_id() ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $response = $this->prepare_item_for_response( $customer, $request ); @@ -328,16 +328,16 @@ class Customers extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } if ( ! get_userdata( $id ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } if ( ! empty( $reassign ) ) { if ( $reassign === $id || ! get_userdata( $reassign ) ) { - return new \WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -356,7 +356,7 @@ class Customers extends AbstractController { } if ( ! $result ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -415,43 +415,43 @@ class Customers extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce' ), + 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -459,7 +459,7 @@ class Customers extends AbstractController { ), ), 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce' ), + 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -467,13 +467,13 @@ class Customers extends AbstractController { ), ), 'role' => array( - 'description' => __( 'Customer role.', 'woocommerce' ), + 'description' => __( 'Customer role.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce' ), + 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -481,157 +481,157 @@ class Customers extends AbstractController { ), ), 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce' ), + 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce' ), + 'description' => __( 'Email address.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce' ), + 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'is_paying_customer' => array( - 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), + 'description' => __( 'Is the customer a paying customer?', 'woocommerce-rest-api' ), 'type' => 'bool', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -666,7 +666,7 @@ class Customers extends AbstractController { $params['context']['default'] = 'view'; $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -675,7 +675,7 @@ class Customers extends AbstractController { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -684,14 +684,14 @@ class Customers extends AbstractController { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'enum' => array( 'asc', 'desc' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', @@ -699,7 +699,7 @@ class Customers extends AbstractController { ); $params['orderby'] = array( 'default' => 'name', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'enum' => array( 'id', 'include', @@ -711,13 +711,13 @@ class Customers extends AbstractController { 'validate_callback' => 'rest_validate_request_arg', ); $params['email'] = array( - 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'validate_callback' => 'rest_validate_request_arg', ); $params['role'] = array( - 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce' ), + 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'customer', 'enum' => array_merge( array( 'all' ), $this->get_role_names() ), @@ -737,7 +737,7 @@ class Customers extends AbstractController { $user = get_userdata( $id ); if ( false === $user ) { - return new \WP_Error( 'woocommerce_rest_customer_invalid_id', __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_customer_invalid_id', __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return true; } diff --git a/src/Controllers/Version4/Data.php b/src/Controllers/Version4/Data.php index a2fb405b9ee..f8a322a47de 100644 --- a/src/Controllers/Version4/Data.php +++ b/src/Controllers/Version4/Data.php @@ -63,19 +63,19 @@ class Data extends AbstractController { $resources = array( array( 'slug' => 'continents', - 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce' ), + 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce-rest-api' ), ), array( 'slug' => 'countries', - 'description' => __( 'List of supported states in a given country.', 'woocommerce' ), + 'description' => __( 'List of supported states in a given country.', 'woocommerce-rest-api' ), ), array( 'slug' => 'currencies', - 'description' => __( 'List of supported currencies.', 'woocommerce' ), + 'description' => __( 'List of supported currencies.', 'woocommerce-rest-api' ), ), array( 'slug' => 'download-ips', - 'description' => __( 'An endpoint used for searching download logs for a specific IP address.', 'woocommerce' ), + 'description' => __( 'An endpoint used for searching download logs for a specific IP address.', 'woocommerce-rest-api' ), ), ); @@ -134,13 +134,13 @@ class Data extends AbstractController { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'Data resource ID.', 'woocommerce' ), + 'description' => __( 'Data resource ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Data resource description.', 'woocommerce' ), + 'description' => __( 'Data resource description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version4/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php index 07271be8432..c95b0b782bd 100644 --- a/src/Controllers/Version4/Data/Continents.php +++ b/src/Controllers/Version4/Data/Continents.php @@ -53,7 +53,7 @@ class Continents extends DataController { 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'continent' => array( - 'description' => __( '2 character continent code.', 'woocommerce' ), + 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -180,7 +180,7 @@ class Continents extends DataController { public function get_item( $request ) { $data = $this->get_continent( strtoupper( $request['location'] ), $request ); if ( empty( $data ) ) { - return new \WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -230,19 +230,19 @@ class Continents extends DataController { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( '2 character continent code.', 'woocommerce' ), + 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of continent.', 'woocommerce' ), + 'description' => __( 'Full name of continent.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'countries' => array( 'type' => 'array', - 'description' => __( 'List of countries on this continent.', 'woocommerce' ), + 'description' => __( 'List of countries on this continent.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -252,49 +252,49 @@ class Continents extends DataController { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'currency_code' => array( 'type' => 'string', - 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce' ), + 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'currency_pos' => array( 'type' => 'string', - 'description' => __( 'Currency symbol position for this country.', 'woocommerce' ), + 'description' => __( 'Currency symbol position for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'decimal_sep' => array( 'type' => 'string', - 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce' ), + 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'dimension_unit' => array( 'type' => 'string', - 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce' ), + 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce' ), + 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'num_decimals' => array( 'type' => 'integer', - 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce' ), + 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'states' => array( 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -304,13 +304,13 @@ class Continents extends DataController { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce' ), + 'description' => __( 'State code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce' ), + 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), @@ -319,13 +319,13 @@ class Continents extends DataController { ), 'thousand_sep' => array( 'type' => 'string', - 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce' ), + 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'weight_unit' => array( 'type' => 'string', - 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce' ), + 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/src/Controllers/Version4/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php index bfa28bc79e3..cca85709109 100644 --- a/src/Controllers/Version4/Data/Countries.php +++ b/src/Controllers/Version4/Data/Countries.php @@ -53,7 +53,7 @@ class Countries extends DataController { 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'location' => array( - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -127,7 +127,7 @@ class Countries extends DataController { public function get_item( $request ) { $data = $this->get_country( strtoupper( $request['location'] ), $request ); if ( empty( $data ) ) { - return new \WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -179,19 +179,19 @@ class Countries extends DataController { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce' ), + 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'states' => array( 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -201,13 +201,13 @@ class Countries extends DataController { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce' ), + 'description' => __( 'State code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce' ), + 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/src/Controllers/Version4/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php index 98d6e39139c..cb87d6d242c 100644 --- a/src/Controllers/Version4/Data/Currencies.php +++ b/src/Controllers/Version4/Data/Currencies.php @@ -63,7 +63,7 @@ class Currencies extends DataController { 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'location' => array( - 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -123,7 +123,7 @@ class Currencies extends DataController { public function get_item( $request ) { $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); if ( empty( $data ) ) { - return new \WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -185,19 +185,19 @@ class Currencies extends DataController { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of currency.', 'woocommerce' ), + 'description' => __( 'Full name of currency.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), 'symbol' => array( 'type' => 'string', - 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/src/Controllers/Version4/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php index 5d62d801926..14a47ff7f85 100644 --- a/src/Controllers/Version4/Data/DownloadIPs.php +++ b/src/Controllers/Version4/Data/DownloadIPs.php @@ -65,7 +65,7 @@ class DownloadIPs extends DataController { ) ); } else { - return new \WP_Error( 'woocommerce_rest_data_download_ips_invalid_request', __( 'Invalid request. Please pass the match parameter.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_data_download_ips_invalid_request', __( 'Invalid request. Please pass the match parameter.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $data = array(); @@ -116,7 +116,7 @@ class DownloadIPs extends DataController { $params = array(); $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['match'] = array( - 'description' => __( 'A partial IP address can be passed and matching results will be returned.', 'woocommerce' ), + 'description' => __( 'A partial IP address can be passed and matching results will be returned.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); @@ -137,7 +137,7 @@ class DownloadIPs extends DataController { 'properties' => array( 'user_ip_address' => array( 'type' => 'string', - 'description' => __( 'IP address.', 'woocommerce' ), + 'description' => __( 'IP address.', 'woocommerce-rest-api' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/src/Controllers/Version4/NetworkOrders.php b/src/Controllers/Version4/NetworkOrders.php index 7fafab5b3bd..a721b5cd5a0 100644 --- a/src/Controllers/Version4/NetworkOrders.php +++ b/src/Controllers/Version4/NetworkOrders.php @@ -47,31 +47,31 @@ class NetworkOrders extends Orders { $schema = parent::get_public_item_schema(); $schema['properties']['blog'] = array( - 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce' ), + 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['edit_url'] = array( - 'description' => __( 'URL to edit the order', 'woocommerce' ), + 'description' => __( 'URL to edit the order', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['customer'][] = array( - 'description' => __( 'Name of the customer for the order', 'woocommerce' ), + 'description' => __( 'Name of the customer for the order', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['status_name'][] = array( - 'description' => __( 'Order Status', 'woocommerce' ), + 'description' => __( 'Order Status', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['formatted_total'][] = array( - 'description' => __( 'Order total formatted for locale', 'woocommerce' ), + 'description' => __( 'Order total formatted for locale', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, @@ -138,7 +138,7 @@ class NetworkOrders extends Orders { $current_order['blog'] = get_blog_details( get_current_blog_id() ); $current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' ); /* translators: 1: first name 2: last name */ - $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); + $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce-rest-api' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); $current_order['status_name'] = wc_get_order_status_name( $order->get_status() ); $current_order['formatted_total'] = $order->get_formatted_order_total(); } diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index c2935e728d0..d95de72528f 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -42,7 +42,7 @@ class OrderNotes extends AbstractController { array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -61,7 +61,7 @@ class OrderNotes extends AbstractController { array( 'note' => array( 'type' => 'string', - 'description' => __( 'Order note content.', 'woocommerce' ), + 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), 'required' => true, ), ) @@ -78,11 +78,11 @@ class OrderNotes extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -102,7 +102,7 @@ class OrderNotes extends AbstractController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -122,7 +122,7 @@ class OrderNotes extends AbstractController { $order = wc_get_order( (int) $request['order_id'] ); if ( $order && ! Permissions::user_can_read( $this->post_type, $order->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -139,7 +139,7 @@ class OrderNotes extends AbstractController { $order = wc_get_order( (int) $request['order_id'] ); if ( $order && ! Permissions::user_can_delete( $this->post_type, $order->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -156,7 +156,7 @@ class OrderNotes extends AbstractController { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $args = array( @@ -208,20 +208,20 @@ class OrderNotes extends AbstractController { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } // Create the note. $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); if ( ! $note_id ) { - return new \WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $note = get_comment( $note_id ); @@ -256,13 +256,13 @@ class OrderNotes extends AbstractController { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $order_note = $this->prepare_item_for_response( $note, $request ); @@ -283,19 +283,19 @@ class OrderNotes extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); @@ -303,7 +303,7 @@ class OrderNotes extends AbstractController { $result = wc_delete_order_note( $note->comment_ID ); if ( ! $result ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), 'order_note' ), array( 'status' => 500 ) ); } $response = new \WP_REST_Response(); @@ -336,7 +336,7 @@ class OrderNotes extends AbstractController { protected function get_data_for_response( $object, $request ) { return array( 'id' => (int) $object->comment_ID, - 'author' => __( 'WooCommerce', 'woocommerce' ) === $object->comment_author ? 'system' : $object->comment_author, + 'author' => __( 'woocommerce-rest-api', 'woocommerce-rest-api' ) === $object->comment_author ? 'system' : $object->comment_author, 'date_created' => wc_rest_prepare_date_response( $object->comment_date ), 'date_created_gmt' => wc_rest_prepare_date_response( $object->comment_date_gmt ), 'note' => $object->comment_content, @@ -381,42 +381,42 @@ class OrderNotes extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'author' => array( - 'description' => __( 'Order note author.', 'woocommerce' ), + 'description' => __( 'Order note author.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'note' => array( - 'description' => __( 'Order note content.', 'woocommerce' ), + 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_note' => array( - 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'added_by_user' => array( - 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce' ), + 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'edit' ), @@ -437,7 +437,7 @@ class OrderNotes extends AbstractController { $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['type'] = array( 'default' => 'any', - 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce' ), + 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array( 'any', 'customer', 'internal' ), 'sanitize_callback' => 'sanitize_key', diff --git a/src/Controllers/Version4/OrderRefunds.php b/src/Controllers/Version4/OrderRefunds.php index ff50b60c939..1f27254ef2c 100644 --- a/src/Controllers/Version4/OrderRefunds.php +++ b/src/Controllers/Version4/OrderRefunds.php @@ -47,7 +47,7 @@ class OrderRefunds extends Orders { array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -74,11 +74,11 @@ class OrderRefunds extends Orders { array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce' ), + 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -98,7 +98,7 @@ class OrderRefunds extends Orders { 'force' => array( 'default' => true, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -132,11 +132,11 @@ class OrderRefunds extends Orders { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); } if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce-rest-api' ), 404 ); } $data = $object->get_data(); @@ -277,17 +277,17 @@ class OrderRefunds extends Orders { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } $order_data = get_post( (int) $request['order_id'] ); if ( empty( $order_data ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); + return new \WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce-rest-api' ), 400 ); } if ( 0 > $request['amount'] ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); } // Create the refund. @@ -306,7 +306,7 @@ class OrderRefunds extends Orders { } if ( ! $refund ) { - return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); } $post = get_post( $refund->get_id() ); @@ -342,11 +342,11 @@ class OrderRefunds extends Orders { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); } if ( 0 > $request['amount'] ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + return new \WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); } // Create the refund. @@ -366,7 +366,7 @@ class OrderRefunds extends Orders { } if ( ! $refund ) { - return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); } if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { @@ -425,64 +425,64 @@ class OrderRefunds extends Orders { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'amount' => array( - 'description' => __( 'Refund amount.', 'woocommerce' ), + 'description' => __( 'Refund amount.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'reason' => array( - 'description' => __( 'Reason for refund.', 'woocommerce' ), + 'description' => __( 'Reason for refund.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'refunded_by' => array( - 'description' => __( 'User ID of user who created the refund.', 'woocommerce' ), + 'description' => __( 'User ID of user who created the refund.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'refunded_payment' => array( - 'description' => __( 'If the payment was refunded via the API.', 'woocommerce' ), + 'description' => __( 'If the payment was refunded via the API.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -490,7 +490,7 @@ class OrderRefunds extends Orders { ), ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce' ), + 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -498,67 +498,67 @@ class OrderRefunds extends Orders { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce' ), + 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -566,19 +566,19 @@ class OrderRefunds extends Orders { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -587,7 +587,7 @@ class OrderRefunds extends Orders { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -595,19 +595,19 @@ class OrderRefunds extends Orders { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -616,13 +616,13 @@ class OrderRefunds extends Orders { ), ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce' ), + 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce' ), + 'description' => __( 'Product price.', 'woocommerce-rest-api' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -631,7 +631,7 @@ class OrderRefunds extends Orders { ), ), 'api_refund' => array( - 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce' ), + 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'default' => true, @@ -652,7 +652,7 @@ class OrderRefunds extends Orders { $params['dp'] = array( 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php index dfd16519546..25923a1c9b4 100644 --- a/src/Controllers/Version4/Orders.php +++ b/src/Controllers/Version4/Orders.php @@ -303,277 +303,277 @@ class Orders extends AbstractObjectsController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'parent_id' => array( - 'description' => __( 'Parent order ID.', 'woocommerce' ), + 'description' => __( 'Parent order ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'number' => array( - 'description' => __( 'Order number.', 'woocommerce' ), + 'description' => __( 'Order number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce' ), + 'description' => __( 'Order key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'description' => __( 'Shows where the order was created.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Order status.', 'woocommerce' ), + 'description' => __( 'Order status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'pending', 'enum' => $this->get_order_statuses(), 'context' => array( 'view', 'edit' ), ), 'currency' => array( - 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => get_woocommerce_currency(), 'enum' => array_keys( get_woocommerce_currencies() ), 'context' => array( 'view', 'edit' ), ), 'currency_symbol' => array( - 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_total' => array( - 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), + 'description' => __( 'Total discount amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_tax' => array( - 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_total' => array( - 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), + 'description' => __( 'Total shipping amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax' => array( - 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_tax' => array( - 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), + 'description' => __( 'Sum of line item taxes only.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Grand total.', 'woocommerce' ), + 'description' => __( 'Grand total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Sum of all taxes.', 'woocommerce' ), + 'description' => __( 'Sum of all taxes.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 0, 'context' => array( 'view', 'edit' ), ), 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'description' => __( "Customer's IP address.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'description' => __( 'User agent of the customer.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'description' => __( 'Note left by customer during checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'billing' => array( - 'description' => __( 'Billing address.', 'woocommerce' ), + 'description' => __( 'Billing address.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce' ), + 'description' => __( 'Email address.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce' ), + 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'Shipping address.', 'woocommerce' ), + 'description' => __( 'Shipping address.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce' ), + 'description' => __( 'First name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce' ), + 'description' => __( 'Last name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce' ), + 'description' => __( 'Company name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce' ), + 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce' ), + 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce' ), + 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'payment_method' => array( - 'description' => __( 'Payment method ID.', 'woocommerce' ), + 'description' => __( 'Payment method ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'payment_method_title' => array( - 'description' => __( 'Payment method title.', 'woocommerce' ), + 'description' => __( 'Payment method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -581,60 +581,60 @@ class Orders extends AbstractObjectsController { ), ), 'transaction_id' => array( - 'description' => __( 'Unique transaction ID.', 'woocommerce' ), + 'description' => __( 'Unique transaction ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_paid' => array( - 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_paid_gmt' => array( - 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_completed_gmt' => array( - 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_hash' => array( - 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -642,67 +642,67 @@ class Orders extends AbstractObjectsController { ), ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce' ), + 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce' ), + 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -710,17 +710,17 @@ class Orders extends AbstractObjectsController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -728,25 +728,25 @@ class Orders extends AbstractObjectsController { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -754,13 +754,13 @@ class Orders extends AbstractObjectsController { ), ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce' ), + 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce' ), + 'description' => __( 'Product price.', 'woocommerce-rest-api' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -769,7 +769,7 @@ class Orders extends AbstractObjectsController { ), ), 'tax_lines' => array( - 'description' => __( 'Tax lines data.', 'woocommerce' ), + 'description' => __( 'Tax lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -777,67 +777,67 @@ class Orders extends AbstractObjectsController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_code' => array( - 'description' => __( 'Tax rate code.', 'woocommerce' ), + 'description' => __( 'Tax rate code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Tax rate label.', 'woocommerce' ), + 'description' => __( 'Tax rate label.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'compound' => array( - 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_total' => array( - 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax_total' => array( - 'description' => __( 'Shipping tax total.', 'woocommerce' ), + 'description' => __( 'Shipping tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -848,46 +848,46 @@ class Orders extends AbstractObjectsController { ), ), 'shipping_lines' => array( - 'description' => __( 'Shipping lines data.', 'woocommerce' ), + 'description' => __( 'Shipping lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_title' => array( - 'description' => __( 'Shipping method name.', 'woocommerce' ), + 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'instance_id' => array( - 'description' => __( 'Shipping instance ID.', 'woocommerce' ), + 'description' => __( 'Shipping instance ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -895,13 +895,13 @@ class Orders extends AbstractObjectsController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -910,25 +910,25 @@ class Orders extends AbstractObjectsController { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -939,47 +939,47 @@ class Orders extends AbstractObjectsController { ), ), 'fee_lines' => array( - 'description' => __( 'Fee lines data.', 'woocommerce' ), + 'description' => __( 'Fee lines data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Fee name.', 'woocommerce' ), + 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of fee.', 'woocommerce' ), + 'description' => __( 'Tax class of fee.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status of fee.', 'woocommerce' ), + 'description' => __( 'Tax status of fee.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'taxable', 'none' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce' ), + 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -987,19 +987,19 @@ class Orders extends AbstractObjectsController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce' ), + 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1008,25 +1008,25 @@ class Orders extends AbstractObjectsController { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1037,55 +1037,55 @@ class Orders extends AbstractObjectsController { ), ), 'coupon_lines' => array( - 'description' => __( 'Coupons line data.', 'woocommerce' ), + 'description' => __( 'Coupons line data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce' ), + 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce' ), + 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'discount' => array( - 'description' => __( 'Discount total.', 'woocommerce' ), + 'description' => __( 'Discount total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_tax' => array( - 'description' => __( 'Discount total tax.', 'woocommerce' ), + 'description' => __( 'Discount total tax.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -1096,7 +1096,7 @@ class Orders extends AbstractObjectsController { ), ), 'refunds' => array( - 'description' => __( 'List of refunds.', 'woocommerce' ), + 'description' => __( 'List of refunds.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1104,19 +1104,19 @@ class Orders extends AbstractObjectsController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Refund ID.', 'woocommerce' ), + 'description' => __( 'Refund ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reason' => array( - 'description' => __( 'Refund reason.', 'woocommerce' ), + 'description' => __( 'Refund reason.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Refund total.', 'woocommerce' ), + 'description' => __( 'Refund total.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1125,7 +1125,7 @@ class Orders extends AbstractObjectsController { ), ), 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'edit' ), @@ -1146,7 +1146,7 @@ class Orders extends AbstractObjectsController { $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -1155,27 +1155,27 @@ class Orders extends AbstractObjectsController { 'validate_callback' => 'rest_validate_request_arg', ); $params['customer'] = array( - 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['product'] = array( - 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['dp'] = array( 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); // This needs to remain a string to support extensions that filter Order Number. $params['number'] = array( - 'description' => __( 'Limit result set to orders matching part of an order number.', 'woocommerce' ), + 'description' => __( 'Limit result set to orders matching part of an order number.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); diff --git a/src/Controllers/Version4/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php index 0304d8dfd1f..9cb4001e727 100644 --- a/src/Controllers/Version4/PaymentGateways.php +++ b/src/Controllers/Version4/PaymentGateways.php @@ -57,7 +57,7 @@ class PaymentGateways extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -109,7 +109,7 @@ class PaymentGateways extends AbstractController { $gateway = $this->get_gateway( $request ); if ( is_null( $gateway ) ) { - return new \WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $gateway = $this->prepare_item_for_response( $gateway, $request ); @@ -126,7 +126,7 @@ class PaymentGateways extends AbstractController { $gateway = $this->get_gateway( $request ); if ( is_null( $gateway ) ) { - return new \WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } // Get settings. @@ -152,7 +152,7 @@ class PaymentGateways extends AbstractController { } if ( $errors_found ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -302,23 +302,23 @@ class PaymentGateways extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'description' => __( 'Payment gateway ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'description' => __( 'Payment gateway sort order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -326,24 +326,24 @@ class PaymentGateways extends AbstractController { ), ), 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'description' => __( 'Payment gateway enabled status.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'description' => __( 'Payment gateway method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'description' => __( 'Payment gateway method description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_supports' => array( - 'description' => __( 'Supported features for this payment gateway.', 'woocommerce' ), + 'description' => __( 'Supported features for this payment gateway.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -352,54 +352,54 @@ class PaymentGateways extends AbstractController { ), ), 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'description' => __( 'Payment gateway settings.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), + 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), + 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version4/ProductAttributeTerms.php b/src/Controllers/Version4/ProductAttributeTerms.php index 1ba1d73bd63..119f2b290c9 100644 --- a/src/Controllers/Version4/ProductAttributeTerms.php +++ b/src/Controllers/Version4/ProductAttributeTerms.php @@ -33,7 +33,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { array( 'args' => array( 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -52,7 +52,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { array( 'name' => array( 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), 'required' => true, ), ) @@ -69,11 +69,11 @@ class ProductAttributeTerms extends AbstractTermsContoller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -99,7 +99,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -114,7 +114,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { array( 'args' => array( 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -177,13 +177,13 @@ class ProductAttributeTerms extends AbstractTermsContoller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Term name.', 'woocommerce' ), + 'description' => __( 'Term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -191,7 +191,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -199,7 +199,7 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -207,12 +207,12 @@ class ProductAttributeTerms extends AbstractTermsContoller { ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version4/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php index b2176689ac7..115dc709d14 100644 --- a/src/Controllers/Version4/ProductAttributes.php +++ b/src/Controllers/Version4/ProductAttributes.php @@ -59,7 +59,7 @@ class ProductAttributes extends AbstractController { $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), array( 'name' => array( - 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'required' => true, ), @@ -77,7 +77,7 @@ class ProductAttributes extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -103,7 +103,7 @@ class ProductAttributes extends AbstractController { 'force' => array( 'default' => true, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -261,7 +261,7 @@ class ProductAttributes extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $attribute = $this->get_attribute( (int) $request['id'] ); @@ -275,7 +275,7 @@ class ProductAttributes extends AbstractController { $deleted = wc_delete_attribute( $attribute->attribute_id ); if ( false === $deleted ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $response = new \WP_REST_Response(); @@ -349,13 +349,13 @@ class ProductAttributes extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -363,7 +363,7 @@ class ProductAttributes extends AbstractController { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -371,21 +371,21 @@ class ProductAttributes extends AbstractController { ), ), 'type' => array( - 'description' => __( 'Type of attribute.', 'woocommerce' ), + 'description' => __( 'Type of attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'select', 'enum' => array_keys( wc_get_attribute_types() ), 'context' => array( 'view', 'edit' ), ), 'order_by' => array( - 'description' => __( 'Default sort order.', 'woocommerce' ), + 'description' => __( 'Default sort order.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'menu_order', 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ), 'context' => array( 'view', 'edit' ), ), 'has_archives' => array( - 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce' ), + 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), @@ -449,7 +449,7 @@ class ProductAttributes extends AbstractController { ); if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { - return new \WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $attribute; @@ -466,13 +466,13 @@ class ProductAttributes extends AbstractController { protected function validate_attribute_slug( $slug, $new_data = true ) { if ( strlen( $slug ) >= 28 ) { /* Translators: %s slug. */ - return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { /* Translators: %s slug. */ - return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { /* Translators: %s slug. */ - return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); } return true; diff --git a/src/Controllers/Version4/ProductCategories.php b/src/Controllers/Version4/ProductCategories.php index 5ad40a1eb28..cf863a2342d 100644 --- a/src/Controllers/Version4/ProductCategories.php +++ b/src/Controllers/Version4/ProductCategories.php @@ -141,13 +141,13 @@ class ProductCategories extends AbstractTermsContoller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), + 'description' => __( 'Category name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -155,7 +155,7 @@ class ProductCategories extends AbstractTermsContoller { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -163,12 +163,12 @@ class ProductCategories extends AbstractTermsContoller { ), ), 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -176,71 +176,71 @@ class ProductCategories extends AbstractTermsContoller { ), ), 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'default', 'enum' => array( 'default', 'products', 'subcategories', 'both' ), 'context' => array( 'view', 'edit' ), ), 'image' => array( - 'description' => __( 'Image data.', 'woocommerce' ), + 'description' => __( 'Image data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php index 7c307aa80e3..9941ae93b67 100644 --- a/src/Controllers/Version4/ProductReviews.php +++ b/src/Controllers/Version4/ProductReviews.php @@ -57,23 +57,23 @@ class ProductReviews extends AbstractController { array( 'product_id' => array( 'required' => true, - 'description' => __( 'Unique identifier for the product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'review' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce' ), + 'description' => __( 'Review content.', 'woocommerce-rest-api' ), ), 'reviewer' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + 'description' => __( 'Name of the reviewer.', 'woocommerce-rest-api' ), ), 'reviewer_email' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + 'description' => __( 'Email of the reviewer.', 'woocommerce-rest-api' ), ), ) ), @@ -89,7 +89,7 @@ class ProductReviews extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -115,7 +115,7 @@ class ProductReviews extends AbstractController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -256,13 +256,13 @@ class ProductReviews extends AbstractController { */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new \WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $prepared_review = $this->prepare_item_for_database( $request ); @@ -276,7 +276,7 @@ class ProductReviews extends AbstractController { * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). */ if ( empty( $prepared_review['comment_content'] ) ) { - return new \WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). @@ -301,7 +301,7 @@ class ProductReviews extends AbstractController { $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new \WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $prepared_review['comment_parent'] = 0; @@ -342,7 +342,7 @@ class ProductReviews extends AbstractController { $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); if ( ! $review_id ) { - return new \WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { @@ -408,7 +408,7 @@ class ProductReviews extends AbstractController { $id = (int) $review->comment_ID; if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { - return new \WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $prepared_args = $this->prepare_item_for_database( $request ); @@ -418,7 +418,7 @@ class ProductReviews extends AbstractController { if ( ! empty( $prepared_args['comment_post_ID'] ) ) { if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { - return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } } @@ -427,7 +427,7 @@ class ProductReviews extends AbstractController { $change = $this->handle_status_param( $request['status'], $id ); if ( ! $change ) { - return new \WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } } elseif ( ! empty( $prepared_args ) ) { if ( is_wp_error( $prepared_args ) ) { @@ -435,7 +435,7 @@ class ProductReviews extends AbstractController { } if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { - return new \WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $prepared_args['comment_ID'] = $id; @@ -443,13 +443,13 @@ class ProductReviews extends AbstractController { $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new \WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); if ( false === $updated ) { - return new \WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { @@ -518,11 +518,11 @@ class ProductReviews extends AbstractController { // If this type doesn't support trashing, error out. if ( ! $supports_trash ) { /* translators: %s: force=true */ - return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce' ), 'force=true' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce-rest-api' ), 'force=true' ), array( 'status' => 501 ) ); } if ( 'trash' === $review->comment_approved ) { - return new \WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + return new \WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce-rest-api' ), array( 'status' => 410 ) ); } $result = wp_trash_comment( $review->comment_ID ); @@ -531,7 +531,7 @@ class ProductReviews extends AbstractController { } if ( ! $result ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -655,48 +655,48 @@ class ProductReviews extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Status of the review.', 'woocommerce' ), + 'description' => __( 'Status of the review.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'approved', 'enum' => array( 'approved', 'hold', 'spam', 'unspam', 'trash', 'untrash' ), 'context' => array( 'view', 'edit' ), ), 'reviewer' => array( - 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'reviewer_email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce' ), + 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -704,12 +704,12 @@ class ProductReviews extends AbstractController { ), ), 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -724,14 +724,14 @@ class ProductReviews extends AbstractController { foreach ( $avatar_sizes as $size ) { $avatar_properties[ $size ] = array( /* translators: %d: avatar image size in pixels */ - 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce' ), $size ), + 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce-rest-api' ), $size ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ); } $schema['properties']['reviewer_avatar_urls'] = array( - 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce' ), + 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -753,17 +753,17 @@ class ProductReviews extends AbstractController { $params['context']['default'] = 'view'; $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', ); $params['before'] = array( - 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -771,7 +771,7 @@ class ProductReviews extends AbstractController { 'default' => array(), ); $params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -779,11 +779,11 @@ class ProductReviews extends AbstractController { 'default' => array(), ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( @@ -792,7 +792,7 @@ class ProductReviews extends AbstractController { ), ); $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'date_gmt', 'enum' => array( @@ -804,14 +804,14 @@ class ProductReviews extends AbstractController { ), ); $params['reviewer'] = array( - 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $params['reviewer_exclude'] = array( - 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -819,13 +819,13 @@ class ProductReviews extends AbstractController { ); $params['reviewer_email'] = array( 'default' => null, - 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce' ), + 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce-rest-api' ), 'format' => 'email', 'type' => 'string', ); $params['product'] = array( 'default' => array(), - 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce' ), + 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -833,7 +833,7 @@ class ProductReviews extends AbstractController { ); $params['status'] = array( 'default' => 'approved', - 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce-rest-api' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', 'enum' => array( @@ -867,7 +867,7 @@ class ProductReviews extends AbstractController { */ protected function get_review( $id ) { $id = (int) $id; - $error = new \WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + $error = new \WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); if ( 0 >= $id ) { return $error; @@ -882,7 +882,7 @@ class ProductReviews extends AbstractController { $post = get_post( (int) $review->comment_post_ID ); if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { - return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } } diff --git a/src/Controllers/Version4/ProductShippingClasses.php b/src/Controllers/Version4/ProductShippingClasses.php index 3353034f847..230cb312eb7 100644 --- a/src/Controllers/Version4/ProductShippingClasses.php +++ b/src/Controllers/Version4/ProductShippingClasses.php @@ -59,13 +59,13 @@ class ProductShippingClasses extends AbstractTermsContoller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Shipping class name.', 'woocommerce' ), + 'description' => __( 'Shipping class name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -73,7 +73,7 @@ class ProductShippingClasses extends AbstractTermsContoller { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -81,7 +81,7 @@ class ProductShippingClasses extends AbstractTermsContoller { ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -89,7 +89,7 @@ class ProductShippingClasses extends AbstractTermsContoller { ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version4/ProductTags.php b/src/Controllers/Version4/ProductTags.php index edc0c7610a6..752d270afd3 100644 --- a/src/Controllers/Version4/ProductTags.php +++ b/src/Controllers/Version4/ProductTags.php @@ -59,13 +59,13 @@ class ProductTags extends AbstractTermsContoller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce' ), + 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -73,7 +73,7 @@ class ProductTags extends AbstractTermsContoller { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -81,7 +81,7 @@ class ProductTags extends AbstractTermsContoller { ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -89,7 +89,7 @@ class ProductTags extends AbstractTermsContoller { ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php index bdcb73b4573..e0a6bbad5a1 100644 --- a/src/Controllers/Version4/ProductVariations.php +++ b/src/Controllers/Version4/ProductVariations.php @@ -44,7 +44,7 @@ class ProductVariations extends Products { array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -70,11 +70,11 @@ class ProductVariations extends Products { array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variation.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -104,7 +104,7 @@ class ProductVariations extends Products { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -118,7 +118,7 @@ class ProductVariations extends Products { array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -148,42 +148,42 @@ class ProductVariations extends Products { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product parent name.', 'woocommerce' ), + 'description' => __( 'Product parent name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), + 'description' => __( 'Product type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'variation', 'enum' => array( 'variation' ), 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce' ), + 'description' => __( 'Variation description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -191,14 +191,14 @@ class ProductVariations extends Products { ), ), 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce' ), + 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -206,91 +206,91 @@ class ProductVariations extends Products { ), ), 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce' ), + 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Variation status.', 'woocommerce' ), + 'description' => __( 'Variation status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_keys( get_post_statuses() ), 'context' => array( 'view', 'edit' ), ), 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), + 'description' => __( 'File ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -298,179 +298,179 @@ class ProductVariations extends Products { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), + 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'instock', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce' ), + 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), + 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -478,30 +478,30 @@ class ProductVariations extends Products { ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -533,7 +533,7 @@ class ProductVariations extends Products { ); $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'sanitize_callback' => 'sanitize_text_field', @@ -541,7 +541,7 @@ class ProductVariations extends Products { ); $params['search'] = array( - 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), + 'description' => __( 'Search by similar product name or sku.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); @@ -571,12 +571,12 @@ class ProductVariations extends Products { $object = $this->get_object( $id ); if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } // Check if variation belongs to the correct parent product. if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -751,7 +751,7 @@ class ProductVariations extends Products { if ( ! $object || 0 === $object->get_id() ) { return new \WP_Error( - "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( + "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404, ) ); @@ -772,7 +772,7 @@ class ProductVariations extends Products { if ( ! Permissions::user_can_delete( $this->post_type, $object->get_id() ) ) { return new \WP_Error( /* translators: %s: post type */ - "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( + "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code(), ) ); @@ -799,7 +799,7 @@ class ProductVariations extends Products { if ( ! $supports_trash ) { return new \WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( + 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501, ) ); @@ -810,7 +810,7 @@ class ProductVariations extends Products { if ( 'trash' === $object->get_status() ) { return new \WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( + 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410, ) ); @@ -826,7 +826,7 @@ class ProductVariations extends Products { if ( ! $result ) { return new \WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( + 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500, ) ); diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php index 888250eb535..592d54b4a20 100644 --- a/src/Controllers/Version4/Products.php +++ b/src/Controllers/Version4/Products.php @@ -55,13 +55,13 @@ class Products extends AbstractObjectsController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce' ), + 'description' => __( 'Product name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( @@ -69,68 +69,68 @@ class Products extends AbstractObjectsController { ), ), 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce' ), + 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce' ), + 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Product type.', 'woocommerce' ), + 'description' => __( 'Product type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'simple', 'enum' => array_keys( wc_get_product_types() ), 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), 'context' => array( 'view', 'edit' ), ), 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce' ), + 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'visible', 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Product description.', 'woocommerce' ), + 'description' => __( 'Product description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( @@ -138,7 +138,7 @@ class Products extends AbstractObjectsController { ), ), 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce' ), + 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( @@ -146,7 +146,7 @@ class Products extends AbstractObjectsController { ), ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -154,96 +154,96 @@ class Products extends AbstractObjectsController { ), ), 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce' ), + 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce' ), + 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce' ), + 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce' ), + 'description' => __( 'File ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce' ), + 'description' => __( 'File name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce' ), + 'description' => __( 'File URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -251,157 +251,157 @@ class Products extends AbstractObjectsController { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce' ), + 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'instock', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -410,7 +410,7 @@ class Products extends AbstractObjectsController { 'readonly' => true, ), 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'description' => __( 'List of up-sell products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -418,7 +418,7 @@ class Products extends AbstractObjectsController { 'context' => array( 'view', 'edit' ), ), 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -426,12 +426,12 @@ class Products extends AbstractObjectsController { 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -439,25 +439,25 @@ class Products extends AbstractObjectsController { ), ), 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce' ), + 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce' ), + 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce' ), + 'description' => __( 'Category name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce' ), + 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -466,25 +466,25 @@ class Products extends AbstractObjectsController { ), ), 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce' ), + 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce' ), + 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce' ), + 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce' ), + 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -493,54 +493,54 @@ class Products extends AbstractObjectsController { ), ), 'images' => array( - 'description' => __( 'List of images.', 'woocommerce' ), + 'description' => __( 'List of images.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce' ), + 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce' ), + 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce' ), + 'description' => __( 'Image name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -548,41 +548,41 @@ class Products extends AbstractObjectsController { ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce' ), + 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce' ), + 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -593,24 +593,24 @@ class Products extends AbstractObjectsController { ), ), 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce' ), + 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -618,7 +618,7 @@ class Products extends AbstractObjectsController { ), ), 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'description' => __( 'List of variations IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -627,7 +627,7 @@ class Products extends AbstractObjectsController { 'readonly' => true, ), 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -636,30 +636,30 @@ class Products extends AbstractObjectsController { 'readonly' => true, ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce' ), + 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce' ), + 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce' ), + 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce' ), + 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), @@ -681,14 +681,14 @@ class Products extends AbstractObjectsController { $params = parent::get_collection_params(); $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), 'sanitize_callback' => 'sanitize_key', @@ -696,7 +696,7 @@ class Products extends AbstractObjectsController { ); $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_types() ), 'sanitize_callback' => 'sanitize_key', @@ -704,49 +704,49 @@ class Products extends AbstractObjectsController { ); $params['sku'] = array( - 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['featured'] = array( - 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), + 'description' => __( 'Limit result set to featured products.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -754,7 +754,7 @@ class Products extends AbstractObjectsController { if ( wc_tax_enabled() ) { $params['tax_class'] = array( - 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), 'sanitize_callback' => 'sanitize_text_field', @@ -763,28 +763,28 @@ class Products extends AbstractObjectsController { } $params['on_sale'] = array( - 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), + 'description' => __( 'Limit result set to products on sale.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); $params['min_price'] = array( - 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), + 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['max_price'] = array( - 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), + 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce-rest-api' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'sanitize_callback' => 'sanitize_text_field', @@ -792,14 +792,14 @@ class Products extends AbstractObjectsController { ); $params['low_in_stock'] = array( - 'description' => __( 'Limit result set to products that are low or out of stock.', 'woocommerce' ), + 'description' => __( 'Limit result set to products that are low or out of stock.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'wc_string_to_bool', ); $params['search'] = array( - 'description' => __( 'Search by similar product name or sku.', 'woocommerce' ), + 'description' => __( 'Search by similar product name or sku.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); @@ -1113,7 +1113,7 @@ class Products extends AbstractObjectsController { if ( ! $object || 0 === $object->get_id() ) { return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", - __( 'Invalid ID.', 'woocommerce' ), + __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404, ) @@ -1123,7 +1123,7 @@ class Products extends AbstractObjectsController { if ( 'variation' === $object->get_type() ) { return new \WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404, ) @@ -1146,7 +1146,7 @@ class Products extends AbstractObjectsController { return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", /* translators: %s: post type */ - sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), + sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code(), ) @@ -1175,7 +1175,7 @@ class Products extends AbstractObjectsController { return new \WP_Error( 'woocommerce_rest_trash_not_supported', /* translators: %s: post type */ - sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), + sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501, ) @@ -1188,7 +1188,7 @@ class Products extends AbstractObjectsController { return new \WP_Error( 'woocommerce_rest_already_trashed', /* translators: %s: post type */ - sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), + sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410, ) @@ -1206,7 +1206,7 @@ class Products extends AbstractObjectsController { return new \WP_Error( 'woocommerce_rest_cannot_delete', /* translators: %s: post type */ - sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), + sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500, ) diff --git a/src/Controllers/Version4/Requests/CustomerRequest.php b/src/Controllers/Version4/Requests/CustomerRequest.php index f852f39669e..eee26f94961 100644 --- a/src/Controllers/Version4/Requests/CustomerRequest.php +++ b/src/Controllers/Version4/Requests/CustomerRequest.php @@ -25,7 +25,7 @@ class CustomerRequest extends AbstractObjectRequest { $object = new \WC_Customer( $id ); if ( $id !== $object->get_id() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), 400 ); } $this->set_props( $object ); @@ -60,13 +60,13 @@ class CustomerRequest extends AbstractObjectRequest { switch ( $prop ) { case 'email': if ( email_exists( $value ) && $value !== $object->get_email() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce-rest-api' ), 400 ); } $prop_values[ $prop ] = $value; break; case 'username': if ( $object->get_id() && $value !== $object->get_username() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce-rest-api' ), 400 ); } $prop_values[ $prop ] = $value; break; diff --git a/src/Controllers/Version4/Requests/OrderRequest.php b/src/Controllers/Version4/Requests/OrderRequest.php index 6a8af0b97ca..2e8109702f7 100644 --- a/src/Controllers/Version4/Requests/OrderRequest.php +++ b/src/Controllers/Version4/Requests/OrderRequest.php @@ -181,7 +181,7 @@ class OrderRequest extends AbstractObjectRequest { } elseif ( ! empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['variation_id']; } else { - throw new \WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); } return $product_id; } @@ -230,7 +230,7 @@ class OrderRequest extends AbstractObjectRequest { if ( 'create' === $action ) { if ( empty( $posted['method_id'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce-rest-api' ), 400 ); } } @@ -254,7 +254,7 @@ class OrderRequest extends AbstractObjectRequest { if ( 'create' === $action ) { if ( empty( $posted['name'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce-rest-api' ), 400 ); } } @@ -289,7 +289,7 @@ class OrderRequest extends AbstractObjectRequest { $item = $order->get_item( absint( $posted['id'] ), false ); if ( ! $item ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce-rest-api' ), 400 ); } } @@ -335,7 +335,7 @@ class OrderRequest extends AbstractObjectRequest { if ( 0 !== $customer_id ) { // Make sure customer exists. if ( false === get_user_by( 'id', $customer_id ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); } // Make sure customer is part of blog. @@ -370,7 +370,7 @@ class OrderRequest extends AbstractObjectRequest { if ( is_array( $item ) ) { if ( empty( $item['id'] ) ) { if ( empty( $item['code'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); } $results = $order->apply_coupon( wc_clean( $item['code'] ) ); diff --git a/src/Controllers/Version4/Requests/ProductRequest.php b/src/Controllers/Version4/Requests/ProductRequest.php index 2593e4c4253..4187677a22c 100644 --- a/src/Controllers/Version4/Requests/ProductRequest.php +++ b/src/Controllers/Version4/Requests/ProductRequest.php @@ -71,11 +71,11 @@ class ProductRequest extends AbstractObjectRequest { } if ( ! $object ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_product_id', __( 'Invalid product.', 'woocommerce' ), 404 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_product_id', __( 'Invalid product.', 'woocommerce-rest-api' ), 404 ); } if ( $object->is_type( 'variation' ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_product_id', __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), 404 ); + throw new \WC_REST_Exception( 'woocommerce_rest_invalid_product_id', __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), 404 ); } return $object; diff --git a/src/Controllers/Version4/Requests/ProductVariationRequest.php b/src/Controllers/Version4/Requests/ProductVariationRequest.php index 76608c5d412..69059c66a6b 100644 --- a/src/Controllers/Version4/Requests/ProductVariationRequest.php +++ b/src/Controllers/Version4/Requests/ProductVariationRequest.php @@ -29,7 +29,7 @@ class ProductVariationRequest extends ProductRequest { $parent = wc_get_product( $object->get_parent_id() ); if ( ! $parent ) { - throw new \WC_REST_Exception( 'woocommerce_rest_product_variation_invalid_parent', __( 'Invalid parent product.', 'woocommerce' ), 404 ); + throw new \WC_REST_Exception( 'woocommerce_rest_product_variation_invalid_parent', __( 'Invalid parent product.', 'woocommerce-rest-api' ), 404 ); } $this->set_common_props( $object ); diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php index de2cd12bc69..6d76f20bb9c 100644 --- a/src/Controllers/Version4/Settings.php +++ b/src/Controllers/Version4/Settings.php @@ -75,7 +75,7 @@ class Settings extends AbstractController { public function get_items( $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); if ( empty( $groups ) ) { - return new \WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $defaults = $this->group_defaults(); @@ -176,27 +176,27 @@ class Settings extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'description' => __( 'ID of parent grouping.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'description' => __( 'IDs for settings sub groups.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php index 7529ccb6580..992159bc4ea 100644 --- a/src/Controllers/Version4/SettingsOptions.php +++ b/src/Controllers/Version4/SettingsOptions.php @@ -45,7 +45,7 @@ class SettingsOptions extends AbstractController { array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -65,7 +65,7 @@ class SettingsOptions extends AbstractController { array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -86,11 +86,11 @@ class SettingsOptions extends AbstractController { array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), 'type' => 'string', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -165,13 +165,13 @@ class SettingsOptions extends AbstractController { */ public function get_group_settings( $group_id ) { if ( empty( $group_id ) ) { - return new \WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores if ( empty( $settings ) ) { - return new \WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $filtered_settings = array(); @@ -252,7 +252,7 @@ class SettingsOptions extends AbstractController { */ public function get_setting( $group_id, $setting_id ) { if ( empty( $setting_id ) ) { - return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $settings = $this->get_group_settings( $group_id ); @@ -264,13 +264,13 @@ class SettingsOptions extends AbstractController { $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); if ( empty( $array_key ) ) { - return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $setting = $settings[ $array_key[0] ]; if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { - return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } if ( is_wp_error( $setting ) ) { @@ -493,7 +493,7 @@ class SettingsOptions extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', @@ -502,7 +502,7 @@ class SettingsOptions extends AbstractController { 'readonly' => true, ), 'group_id' => array( - 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ), + 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', @@ -511,7 +511,7 @@ class SettingsOptions extends AbstractController { 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -520,7 +520,7 @@ class SettingsOptions extends AbstractController { 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -529,18 +529,18 @@ class SettingsOptions extends AbstractController { 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), + 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -549,7 +549,7 @@ class SettingsOptions extends AbstractController { 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -558,7 +558,7 @@ class SettingsOptions extends AbstractController { 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), + 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -568,7 +568,7 @@ class SettingsOptions extends AbstractController { 'readonly' => true, ), 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php index 229e9db0f8d..8aa7d3def17 100644 --- a/src/Controllers/Version4/ShippingMethods.php +++ b/src/Controllers/Version4/ShippingMethods.php @@ -54,7 +54,7 @@ class ShippingMethods extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -99,7 +99,7 @@ class ShippingMethods extends AbstractController { $wc_shipping = \WC_Shipping::instance(); $methods = $wc_shipping->get_shipping_methods(); if ( empty( $methods[ $request['id'] ] ) ) { - return new \WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $method = $methods[ $request['id'] ]; @@ -155,19 +155,19 @@ class ShippingMethods extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Method ID.', 'woocommerce' ), + 'description' => __( 'Method ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version4/ShippingZoneLocations.php b/src/Controllers/Version4/ShippingZoneLocations.php index 1171b90e559..503b6ff3845 100644 --- a/src/Controllers/Version4/ShippingZoneLocations.php +++ b/src/Controllers/Version4/ShippingZoneLocations.php @@ -26,7 +26,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), + 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -86,7 +86,7 @@ class ShippingZoneLocations extends AbstractShippingZonesController { } if ( 0 === $zone->get_id() ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); } $raw_locations = $request->get_json_params(); @@ -148,12 +148,12 @@ class ShippingZoneLocations extends AbstractShippingZonesController { 'type' => 'object', 'properties' => array( 'code' => array( - 'description' => __( 'Shipping zone location code.', 'woocommerce' ), + 'description' => __( 'Shipping zone location code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'type' => array( - 'description' => __( 'Shipping zone location type.', 'woocommerce' ), + 'description' => __( 'Shipping zone location type.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'country', 'enum' => array( diff --git a/src/Controllers/Version4/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php index d252ab17ef3..ca547399671 100644 --- a/src/Controllers/Version4/ShippingZoneMethods.php +++ b/src/Controllers/Version4/ShippingZoneMethods.php @@ -29,7 +29,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { array( 'args' => array( 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -48,7 +48,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { 'method_id' => array( 'required' => true, 'readonly' => false, - 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), ), ) ), @@ -64,11 +64,11 @@ class ShippingZoneMethods extends AbstractShippingZonesController { array( 'args' => array( 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), 'type' => 'integer', ), 'instance_id' => array( - 'description' => __( 'Unique ID for the instance.', 'woocommerce' ), + 'description' => __( 'Unique ID for the instance.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -91,7 +91,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -126,7 +126,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( false === $method ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $method, $request ); @@ -182,7 +182,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( false === $method ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -211,7 +211,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $methods = $zone->get_shipping_methods(); @@ -225,7 +225,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( false === $method ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -282,7 +282,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( false === $method ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -327,7 +327,7 @@ class ShippingZoneMethods extends AbstractShippingZonesController { } if ( $errors_found ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); @@ -449,100 +449,100 @@ class ShippingZoneMethods extends AbstractShippingZonesController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'instance_id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Shipping method customer facing title.', 'woocommerce' ), + 'description' => __( 'Shipping method customer facing title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'order' => array( - 'description' => __( 'Shipping method sort order.', 'woocommerce' ), + 'description' => __( 'Shipping method sort order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'enabled' => array( - 'description' => __( 'Shipping method enabled status.', 'woocommerce' ), + 'description' => __( 'Shipping method enabled status.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'settings' => array( - 'description' => __( 'Shipping method settings.', 'woocommerce' ), + 'description' => __( 'Shipping method settings.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce' ), + 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce' ), + 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version4/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php index af9da032b05..a80af9c47f5 100644 --- a/src/Controllers/Version4/ShippingZones.php +++ b/src/Controllers/Version4/ShippingZones.php @@ -39,7 +39,7 @@ class ShippingZones extends AbstractShippingZonesController { 'name' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Shipping zone name.', 'woocommerce' ), + 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), ), ) ), @@ -55,7 +55,7 @@ class ShippingZones extends AbstractShippingZonesController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), + 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -78,7 +78,7 @@ class ShippingZones extends AbstractShippingZonesController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), ), ), ), @@ -156,7 +156,7 @@ class ShippingZones extends AbstractShippingZonesController { $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); return $response; } else { - return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } } @@ -174,7 +174,7 @@ class ShippingZones extends AbstractShippingZonesController { } if ( 0 === $zone->get_id() ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + return new \WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); } $zone_changed = false; @@ -213,7 +213,7 @@ class ShippingZones extends AbstractShippingZonesController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $previous = $this->get_item( $request ); @@ -280,13 +280,13 @@ class ShippingZones extends AbstractShippingZonesController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Shipping zone name.', 'woocommerce' ), + 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -294,7 +294,7 @@ class ShippingZones extends AbstractShippingZonesController { ), ), 'order' => array( - 'description' => __( 'Shipping zone order.', 'woocommerce' ), + 'description' => __( 'Shipping zone order.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php index 36239c6b7f6..f2f458c4090 100644 --- a/src/Controllers/Version4/SystemStatus.php +++ b/src/Controllers/Version4/SystemStatus.php @@ -82,195 +82,195 @@ class SystemStatus extends AbstractController { 'type' => 'object', 'properties' => array( 'environment' => array( - 'description' => __( 'Environment.', 'woocommerce' ), + 'description' => __( 'Environment.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'home_url' => array( - 'description' => __( 'Home URL.', 'woocommerce' ), + 'description' => __( 'Home URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'site_url' => array( - 'description' => __( 'Site URL.', 'woocommerce' ), + 'description' => __( 'Site URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'wc_version' => array( - 'description' => __( 'WooCommerce version.', 'woocommerce' ), + 'description' => __( 'WooCommerce version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'log_directory' => array( - 'description' => __( 'Log directory.', 'woocommerce' ), + 'description' => __( 'Log directory.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'log_directory_writable' => array( - 'description' => __( 'Is log directory writable?', 'woocommerce' ), + 'description' => __( 'Is log directory writable?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_version' => array( - 'description' => __( 'WordPress version.', 'woocommerce' ), + 'description' => __( 'WordPress version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_multisite' => array( - 'description' => __( 'Is WordPress multisite?', 'woocommerce' ), + 'description' => __( 'Is WordPress multisite?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_memory_limit' => array( - 'description' => __( 'WordPress memory limit.', 'woocommerce' ), + 'description' => __( 'WordPress memory limit.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_debug_mode' => array( - 'description' => __( 'Is WordPress debug mode active?', 'woocommerce' ), + 'description' => __( 'Is WordPress debug mode active?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_cron' => array( - 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce' ), + 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'language' => array( - 'description' => __( 'WordPress language.', 'woocommerce' ), + 'description' => __( 'WordPress language.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'server_info' => array( - 'description' => __( 'Server info.', 'woocommerce' ), + 'description' => __( 'Server info.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'php_version' => array( - 'description' => __( 'PHP version.', 'woocommerce' ), + 'description' => __( 'PHP version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'php_post_max_size' => array( - 'description' => __( 'PHP post max size.', 'woocommerce' ), + 'description' => __( 'PHP post max size.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'php_max_execution_time' => array( - 'description' => __( 'PHP max execution time.', 'woocommerce' ), + 'description' => __( 'PHP max execution time.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'php_max_input_vars' => array( - 'description' => __( 'PHP max input vars.', 'woocommerce' ), + 'description' => __( 'PHP max input vars.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'curl_version' => array( - 'description' => __( 'cURL version.', 'woocommerce' ), + 'description' => __( 'cURL version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'suhosin_installed' => array( - 'description' => __( 'Is SUHOSIN installed?', 'woocommerce' ), + 'description' => __( 'Is SUHOSIN installed?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'max_upload_size' => array( - 'description' => __( 'Max upload size.', 'woocommerce' ), + 'description' => __( 'Max upload size.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'mysql_version' => array( - 'description' => __( 'MySQL version.', 'woocommerce' ), + 'description' => __( 'MySQL version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'mysql_version_string' => array( - 'description' => __( 'MySQL version string.', 'woocommerce' ), + 'description' => __( 'MySQL version string.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'default_timezone' => array( - 'description' => __( 'Default timezone.', 'woocommerce' ), + 'description' => __( 'Default timezone.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'fsockopen_or_curl_enabled' => array( - 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce' ), + 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'soapclient_enabled' => array( - 'description' => __( 'Is SoapClient class enabled?', 'woocommerce' ), + 'description' => __( 'Is SoapClient class enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'domdocument_enabled' => array( - 'description' => __( 'Is DomDocument class enabled?', 'woocommerce' ), + 'description' => __( 'Is DomDocument class enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'gzip_enabled' => array( - 'description' => __( 'Is GZip enabled?', 'woocommerce' ), + 'description' => __( 'Is GZip enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'mbstring_enabled' => array( - 'description' => __( 'Is mbstring enabled?', 'woocommerce' ), + 'description' => __( 'Is mbstring enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_post_successful' => array( - 'description' => __( 'Remote POST successful?', 'woocommerce' ), + 'description' => __( 'Remote POST successful?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_post_response' => array( - 'description' => __( 'Remote POST response.', 'woocommerce' ), + 'description' => __( 'Remote POST response.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_get_successful' => array( - 'description' => __( 'Remote GET successful?', 'woocommerce' ), + 'description' => __( 'Remote GET successful?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_get_response' => array( - 'description' => __( 'Remote GET response.', 'woocommerce' ), + 'description' => __( 'Remote GET response.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, @@ -278,31 +278,31 @@ class SystemStatus extends AbstractController { ), ), 'database' => array( - 'description' => __( 'Database.', 'woocommerce' ), + 'description' => __( 'Database.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'wc_database_version' => array( - 'description' => __( 'WC database version.', 'woocommerce' ), + 'description' => __( 'WC database version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'database_prefix' => array( - 'description' => __( 'Database prefix.', 'woocommerce' ), + 'description' => __( 'Database prefix.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'maxmind_geoip_database' => array( - 'description' => __( 'MaxMind GeoIP database.', 'woocommerce' ), + 'description' => __( 'MaxMind GeoIP database.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'database_tables' => array( - 'description' => __( 'Database tables.', 'woocommerce' ), + 'description' => __( 'Database tables.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -313,7 +313,7 @@ class SystemStatus extends AbstractController { ), ), 'active_plugins' => array( - 'description' => __( 'Active plugins.', 'woocommerce' ), + 'description' => __( 'Active plugins.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -322,7 +322,7 @@ class SystemStatus extends AbstractController { ), ), 'inactive_plugins' => array( - 'description' => __( 'Inactive plugins.', 'woocommerce' ), + 'description' => __( 'Inactive plugins.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -331,7 +331,7 @@ class SystemStatus extends AbstractController { ), ), 'dropins_mu_plugins' => array( - 'description' => __( 'Dropins & MU plugins.', 'woocommerce' ), + 'description' => __( 'Dropins & MU plugins.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -340,62 +340,62 @@ class SystemStatus extends AbstractController { ), ), 'theme' => array( - 'description' => __( 'Theme.', 'woocommerce' ), + 'description' => __( 'Theme.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'name' => array( - 'description' => __( 'Theme name.', 'woocommerce' ), + 'description' => __( 'Theme name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'version' => array( - 'description' => __( 'Theme version.', 'woocommerce' ), + 'description' => __( 'Theme version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'version_latest' => array( - 'description' => __( 'Latest version of theme.', 'woocommerce' ), + 'description' => __( 'Latest version of theme.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'author_url' => array( - 'description' => __( 'Theme author URL.', 'woocommerce' ), + 'description' => __( 'Theme author URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'is_child_theme' => array( - 'description' => __( 'Is this theme a child theme?', 'woocommerce' ), + 'description' => __( 'Is this theme a child theme?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_woocommerce_support' => array( - 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ), + 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_woocommerce_file' => array( - 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ), + 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_outdated_templates' => array( - 'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ), + 'description' => __( 'Does this theme have outdated templates?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'overrides' => array( - 'description' => __( 'Template overrides.', 'woocommerce' ), + 'description' => __( 'Template overrides.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -404,19 +404,19 @@ class SystemStatus extends AbstractController { ), ), 'parent_name' => array( - 'description' => __( 'Parent theme name.', 'woocommerce' ), + 'description' => __( 'Parent theme name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'parent_version' => array( - 'description' => __( 'Parent theme version.', 'woocommerce' ), + 'description' => __( 'Parent theme version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'parent_author_url' => array( - 'description' => __( 'Parent theme author URL.', 'woocommerce' ), + 'description' => __( 'Parent theme author URL.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), @@ -425,67 +425,67 @@ class SystemStatus extends AbstractController { ), ), 'settings' => array( - 'description' => __( 'Settings.', 'woocommerce' ), + 'description' => __( 'Settings.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'api_enabled' => array( - 'description' => __( 'REST API enabled?', 'woocommerce' ), + 'description' => __( 'REST API enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'force_ssl' => array( - 'description' => __( 'SSL forced?', 'woocommerce' ), + 'description' => __( 'SSL forced?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'currency' => array( - 'description' => __( 'Currency.', 'woocommerce' ), + 'description' => __( 'Currency.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'currency_symbol' => array( - 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'currency_position' => array( - 'description' => __( 'Currency position.', 'woocommerce' ), + 'description' => __( 'Currency position.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'thousand_separator' => array( - 'description' => __( 'Thousand separator.', 'woocommerce' ), + 'description' => __( 'Thousand separator.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'decimal_separator' => array( - 'description' => __( 'Decimal separator.', 'woocommerce' ), + 'description' => __( 'Decimal separator.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'number_of_decimals' => array( - 'description' => __( 'Number of decimals.', 'woocommerce' ), + 'description' => __( 'Number of decimals.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'geolocation_enabled' => array( - 'description' => __( 'Geolocation enabled?', 'woocommerce' ), + 'description' => __( 'Geolocation enabled?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'taxonomies' => array( - 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce' ), + 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -494,7 +494,7 @@ class SystemStatus extends AbstractController { ), ), 'product_visibility_terms' => array( - 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce' ), + 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -505,19 +505,19 @@ class SystemStatus extends AbstractController { ), ), 'security' => array( - 'description' => __( 'Security.', 'woocommerce' ), + 'description' => __( 'Security.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'secure_connection' => array( - 'description' => __( 'Is the connection to your store secure?', 'woocommerce' ), + 'description' => __( 'Is the connection to your store secure?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'hide_errors' => array( - 'description' => __( 'Hide errors from visitors?', 'woocommerce' ), + 'description' => __( 'Hide errors from visitors?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, @@ -525,7 +525,7 @@ class SystemStatus extends AbstractController { ), ), 'pages' => array( - 'description' => __( 'WooCommerce pages.', 'woocommerce' ), + 'description' => __( 'WooCommerce pages.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -534,7 +534,7 @@ class SystemStatus extends AbstractController { ), ), 'post_type_counts' => array( - 'description' => __( 'Post type counts.', 'woocommerce' ), + 'description' => __( 'Post type counts.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php index e6aaa94d0d9..72fc9b8e513 100644 --- a/src/Controllers/Version4/SystemStatusTools.php +++ b/src/Controllers/Version4/SystemStatusTools.php @@ -55,7 +55,7 @@ class SystemStatusTools extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -85,79 +85,79 @@ class SystemStatusTools extends AbstractController { public function get_tools() { $tools = array( 'clear_transients' => array( - 'name' => __( 'WooCommerce transients', 'woocommerce' ), - 'button' => __( 'Clear transients', 'woocommerce' ), - 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ), + 'name' => __( 'WooCommerce transients', 'woocommerce-rest-api' ), + 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce-rest-api' ), ), 'clear_expired_transients' => array( - 'name' => __( 'Expired transients', 'woocommerce' ), - 'button' => __( 'Clear transients', 'woocommerce' ), - 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce' ), + 'name' => __( 'Expired transients', 'woocommerce-rest-api' ), + 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce-rest-api' ), ), 'delete_orphaned_variations' => array( - 'name' => __( 'Orphaned variations', 'woocommerce' ), - 'button' => __( 'Delete orphaned variations', 'woocommerce' ), - 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce' ), + 'name' => __( 'Orphaned variations', 'woocommerce-rest-api' ), + 'button' => __( 'Delete orphaned variations', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce-rest-api' ), ), 'clear_expired_download_permissions' => array( - 'name' => __( 'Used-up download permissions', 'woocommerce' ), - 'button' => __( 'Clean up download permissions', 'woocommerce' ), - 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ), + 'name' => __( 'Used-up download permissions', 'woocommerce-rest-api' ), + 'button' => __( 'Clean up download permissions', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce-rest-api' ), ), 'regenerate_product_lookup_tables' => array( - 'name' => __( 'Product lookup tables', 'woocommerce' ), - 'button' => __( 'Regenerate', 'woocommerce' ), - 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce' ), + 'name' => __( 'Product lookup tables', 'woocommerce-rest-api' ), + 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce-rest-api' ), ), 'recount_terms' => array( - 'name' => __( 'Term counts', 'woocommerce' ), - 'button' => __( 'Recount terms', 'woocommerce' ), - 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ), + 'name' => __( 'Term counts', 'woocommerce-rest-api' ), + 'button' => __( 'Recount terms', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce-rest-api' ), ), 'reset_roles' => array( - 'name' => __( 'Capabilities', 'woocommerce' ), - 'button' => __( 'Reset capabilities', 'woocommerce' ), - 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ), + 'name' => __( 'Capabilities', 'woocommerce-rest-api' ), + 'button' => __( 'Reset capabilities', 'woocommerce-rest-api' ), + 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce-rest-api' ), ), 'clear_sessions' => array( - 'name' => __( 'Clear customer sessions', 'woocommerce' ), - 'button' => __( 'Clear', 'woocommerce' ), + 'name' => __( 'Clear customer sessions', 'woocommerce-rest-api' ), + 'button' => __( 'Clear', 'woocommerce-rest-api' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce' ) + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce-rest-api' ) ), ), 'install_pages' => array( - 'name' => __( 'Create default WooCommerce pages', 'woocommerce' ), - 'button' => __( 'Create pages', 'woocommerce' ), + 'name' => __( 'Create default WooCommerce pages', 'woocommerce-rest-api' ), + 'button' => __( 'Create pages', 'woocommerce-rest-api' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce' ) + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce-rest-api' ) ), ), 'delete_taxes' => array( - 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce' ), - 'button' => __( 'Delete tax rates', 'woocommerce' ), + 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce-rest-api' ), + 'button' => __( 'Delete tax rates', 'woocommerce-rest-api' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce' ) + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce-rest-api' ) ), ), 'regenerate_thumbnails' => array( - 'name' => __( 'Regenerate shop thumbnails', 'woocommerce' ), - 'button' => __( 'Regenerate', 'woocommerce' ), - 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce' ), + 'name' => __( 'Regenerate shop thumbnails', 'woocommerce-rest-api' ), + 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), + 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce-rest-api' ), ), 'db_update_routine' => array( - 'name' => __( 'Update database', 'woocommerce' ), - 'button' => __( 'Update database', 'woocommerce' ), + 'name' => __( 'Update database', 'woocommerce-rest-api' ), + 'button' => __( 'Update database', 'woocommerce-rest-api' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce' ) + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce-rest-api' ) ), ), ); @@ -205,7 +205,7 @@ class SystemStatusTools extends AbstractController { public function get_item( $request ) { $tools = $this->get_tools(); if ( empty( $tools[ $request['id'] ] ) ) { - return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $tool = $tools[ $request['id'] ]; return rest_ensure_response( @@ -230,7 +230,7 @@ class SystemStatusTools extends AbstractController { public function update_item( $request ) { $tools = $this->get_tools(); if ( empty( $tools[ $request['id'] ] ) ) { - return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $tool = $tools[ $request['id'] ]; @@ -269,7 +269,7 @@ class SystemStatusTools extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the tool.', 'woocommerce' ), + 'description' => __( 'A unique identifier for the tool.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -277,7 +277,7 @@ class SystemStatusTools extends AbstractController { ), ), 'name' => array( - 'description' => __( 'Tool name.', 'woocommerce' ), + 'description' => __( 'Tool name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -285,7 +285,7 @@ class SystemStatusTools extends AbstractController { ), ), 'action' => array( - 'description' => __( 'What running the tool will do.', 'woocommerce' ), + 'description' => __( 'What running the tool will do.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -293,7 +293,7 @@ class SystemStatusTools extends AbstractController { ), ), 'description' => array( - 'description' => __( 'Tool description.', 'woocommerce' ), + 'description' => __( 'Tool description.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -301,12 +301,12 @@ class SystemStatusTools extends AbstractController { ), ), 'success' => array( - 'description' => __( 'Did the tool run successfully?', 'woocommerce' ), + 'description' => __( 'Did the tool run successfully?', 'woocommerce-rest-api' ), 'type' => 'boolean', 'context' => array( 'edit' ), ), 'message' => array( - 'description' => __( 'Tool return message.', 'woocommerce' ), + 'description' => __( 'Tool return message.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( @@ -362,23 +362,23 @@ class SystemStatusTools extends AbstractController { try { if ( ! isset( $tools[ $tool ] ) ) { - throw new Exception( __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ) ); + throw new Exception( __( 'There was an error calling this tool. There is no callback present.', 'woocommerce-rest-api' ) ); } $callback = isset( $tools[ $tool ]['callback'] ) ? $tools[ $tool ]['callback'] : array( $this, $tool ); if ( ! is_callable( $callback ) ) { - throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce' ) ); + throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce-rest-api' ) ); } $message = call_user_func( $callback ); if ( false === $message ) { - throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce' ) ); + throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce-rest-api' ) ); } if ( empty( $message ) || ! is_string( $message ) ) { - $message = __( 'Tool ran.', 'woocommerce' ); + $message = __( 'Tool ran.', 'woocommerce-rest-api' ); } $ran = true; @@ -412,7 +412,7 @@ class SystemStatusTools extends AbstractController { } \WC_Cache_Helper::get_transient_version( 'shipping', true ); - return __( 'Product transients cleared', 'woocommerce' ); + return __( 'Product transients cleared', 'woocommerce-rest-api' ); } /** @@ -422,7 +422,7 @@ class SystemStatusTools extends AbstractController { */ protected function clear_expired_transients() { /* translators: %d: amount of expired transients */ - return sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() ); + return sprintf( __( '%d transients rows cleared', 'woocommerce-rest-api' ), wc_delete_expired_transients() ); } /** @@ -442,7 +442,7 @@ class SystemStatusTools extends AbstractController { ) ); /* translators: %d: amount of orphaned variations */ - return sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result ); + return sprintf( __( '%d orphaned variations deleted', 'woocommerce-rest-api' ), $result ); } /** @@ -463,7 +463,7 @@ class SystemStatusTools extends AbstractController { ) ); /* translators: %d: amount of permissions */ - return sprintf( __( '%d permissions deleted', 'woocommerce' ), $result ); + return sprintf( __( '%d permissions deleted', 'woocommerce-rest-api' ), $result ); } /** @@ -475,7 +475,7 @@ class SystemStatusTools extends AbstractController { if ( ! wc_update_product_lookup_tables_is_running() ) { wc_update_product_lookup_tables(); } - return __( 'Lookup tables are regenerating', 'woocommerce' ); + return __( 'Lookup tables are regenerating', 'woocommerce-rest-api' ); } /** @@ -486,7 +486,7 @@ class SystemStatusTools extends AbstractController { protected function reset_roles() { \WC_Install::remove_roles(); \WC_Install::create_roles(); - return __( 'Roles successfully reset', 'woocommerce' ); + return __( 'Roles successfully reset', 'woocommerce-rest-api' ); } /** @@ -511,7 +511,7 @@ class SystemStatusTools extends AbstractController { ) ); _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); - return __( 'Terms successfully recounted', 'woocommerce' ); + return __( 'Terms successfully recounted', 'woocommerce-rest-api' ); } /** @@ -526,7 +526,7 @@ class SystemStatusTools extends AbstractController { $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. wp_cache_flush(); /* translators: %d: amount of sessions */ - return sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) ); + return sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce-rest-api' ), absint( $result ) ); } /** @@ -536,7 +536,7 @@ class SystemStatusTools extends AbstractController { */ protected function install_pages() { \WC_Install::create_pages(); - return __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); + return __( 'All missing WooCommerce pages successfully installed', 'woocommerce-rest-api' ); } /** @@ -549,7 +549,7 @@ class SystemStatusTools extends AbstractController { $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); \WC_Cache_Helper::incr_cache_prefix( 'taxes' ); - return __( 'Tax rates successfully deleted', 'woocommerce' ); + return __( 'Tax rates successfully deleted', 'woocommerce-rest-api' ); } /** @@ -559,7 +559,7 @@ class SystemStatusTools extends AbstractController { */ protected function regenerate_thumbnails() { \WC_Regenerate_Images::queue_image_regeneration(); - return __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); + return __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce-rest-api' ); } /** @@ -572,6 +572,6 @@ class SystemStatusTools extends AbstractController { // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); - return __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' ); + return __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce-rest-api' ); } } diff --git a/src/Controllers/Version4/TaxClasses.php b/src/Controllers/Version4/TaxClasses.php index 2c60d447aa1..3f3a527f2de 100644 --- a/src/Controllers/Version4/TaxClasses.php +++ b/src/Controllers/Version4/TaxClasses.php @@ -61,7 +61,7 @@ class TaxClasses extends AbstractController { array( 'args' => array( 'slug' => array( - 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), + 'description' => __( 'Unique slug for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', ), ), @@ -73,7 +73,7 @@ class TaxClasses extends AbstractController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -95,7 +95,7 @@ class TaxClasses extends AbstractController { // Add standard class. $tax_classes[] = array( 'slug' => 'standard', - 'name' => __( 'Standard rate', 'woocommerce' ), + 'name' => __( 'Standard rate', 'woocommerce-rest-api' ), ); $classes = \WC_Tax::get_tax_classes(); @@ -141,7 +141,7 @@ class TaxClasses extends AbstractController { // Return error if tax class already exists. if ( $exists ) { - return new \WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } // Add the new class. @@ -182,7 +182,7 @@ class TaxClasses extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $tax_class = array( @@ -202,7 +202,7 @@ class TaxClasses extends AbstractController { } if ( ! $deleted ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $request->set_param( 'context', 'edit' ); @@ -277,13 +277,13 @@ class TaxClasses extends AbstractController { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Tax class name.', 'woocommerce' ), + 'description' => __( 'Tax class name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'required' => true, diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php index e7ee48b7a7d..b1adf12669f 100644 --- a/src/Controllers/Version4/Taxes.php +++ b/src/Controllers/Version4/Taxes.php @@ -63,7 +63,7 @@ class Taxes extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -89,7 +89,7 @@ class Taxes extends AbstractController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -272,7 +272,7 @@ class Taxes extends AbstractController { */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new \WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $tax = $this->create_or_update_tax( $request ); @@ -308,7 +308,7 @@ class Taxes extends AbstractController { $tax_obj = \WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $tax = $this->prepare_item_for_response( $tax_obj, $request ); @@ -328,7 +328,7 @@ class Taxes extends AbstractController { $tax_obj = \WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $tax = $this->create_or_update_tax( $request, $tax_obj ); @@ -365,13 +365,13 @@ class Taxes extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $tax = \WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $request->set_param( 'context', 'edit' ); @@ -380,7 +380,7 @@ class Taxes extends AbstractController { \WC_Tax::_delete_tax_rate( $id ); if ( 0 === $wpdb->rows_affected ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); } /** @@ -473,66 +473,66 @@ class Taxes extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'country' => array( - 'description' => __( 'Country ISO 3166 code.', 'woocommerce' ), + 'description' => __( 'Country ISO 3166 code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'State code.', 'woocommerce' ), + 'description' => __( 'State code.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postcode / ZIP.', 'woocommerce' ), + 'description' => __( 'Postcode / ZIP.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce' ), + 'description' => __( 'City name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'rate' => array( - 'description' => __( 'Tax rate.', 'woocommerce' ), + 'description' => __( 'Tax rate.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tax rate name.', 'woocommerce' ), + 'description' => __( 'Tax rate name.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'priority' => array( - 'description' => __( 'Tax priority.', 'woocommerce' ), + 'description' => __( 'Tax priority.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 1, 'context' => array( 'view', 'edit' ), ), 'compound' => array( - 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce' ), + 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'shipping' => array( - 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce' ), + 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce-rest-api' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'order' => array( - 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce' ), + 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'class' => array( - 'description' => __( 'Tax class.', 'woocommerce' ), + 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'standard', 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), @@ -555,7 +555,7 @@ class Taxes extends AbstractController { $params['context']['default'] = 'view'; $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -563,7 +563,7 @@ class Taxes extends AbstractController { 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-rest-api' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -572,14 +572,14 @@ class Taxes extends AbstractController { 'validate_callback' => 'rest_validate_request_arg', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'enum' => array( 'asc', 'desc' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', @@ -587,7 +587,7 @@ class Taxes extends AbstractController { ); $params['orderby'] = array( 'default' => 'order', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'enum' => array( 'id', 'order', @@ -597,19 +597,19 @@ class Taxes extends AbstractController { 'validate_callback' => 'rest_validate_request_arg', ); $params['class'] = array( - 'description' => __( 'Sort by tax class.', 'woocommerce' ), + 'description' => __( 'Sort by tax class.', 'woocommerce-rest-api' ), 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), 'sanitize_callback' => 'sanitize_title', 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $params['code'] = array( - 'description' => __( 'Search by similar tax code.', 'woocommerce' ), + 'description' => __( 'Search by similar tax code.', 'woocommerce-rest-api' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $params['include'] = array( - 'description' => __( 'Limit result set to items that have the specified rate ID(s) assigned.', 'woocommerce' ), + 'description' => __( 'Limit result set to items that have the specified rate ID(s) assigned.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', diff --git a/src/Controllers/Version4/Utilities/BatchTrait.php b/src/Controllers/Version4/Utilities/BatchTrait.php index f35f7eba96e..74870676955 100644 --- a/src/Controllers/Version4/Utilities/BatchTrait.php +++ b/src/Controllers/Version4/Utilities/BatchTrait.php @@ -94,7 +94,7 @@ trait BatchTrait { 'type' => 'object', 'properties' => array( 'create' => array( - 'description' => __( 'List of created resources.', 'woocommerce' ), + 'description' => __( 'List of created resources.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -102,7 +102,7 @@ trait BatchTrait { ), ), 'update' => array( - 'description' => __( 'List of updated resources.', 'woocommerce' ), + 'description' => __( 'List of updated resources.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -110,7 +110,7 @@ trait BatchTrait { ), ), 'delete' => array( - 'description' => __( 'List of delete resources.', 'woocommerce' ), + 'description' => __( 'List of delete resources.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -152,7 +152,7 @@ trait BatchTrait { if ( $total > $limit ) { /* translators: %s: items limit */ - return new \WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); + return new \WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce-rest-api' ), $limit ), array( 'status' => 413 ) ); } return true; diff --git a/src/Controllers/Version4/Utilities/DatabaseInformation.php b/src/Controllers/Version4/Utilities/DatabaseInformation.php index be946dc9e9e..b5d9f0a37d7 100644 --- a/src/Controllers/Version4/Utilities/DatabaseInformation.php +++ b/src/Controllers/Version4/Utilities/DatabaseInformation.php @@ -78,7 +78,7 @@ class DatabaseInformation { * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. */ $tables = array( - 'woocommerce' => array_fill_keys( $core_tables, false ), + 'woocommerce-rest-api' => array_fill_keys( $core_tables, false ), 'other' => array(), ); @@ -94,7 +94,7 @@ class DatabaseInformation { if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { continue; } - $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; + $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce-rest-api' : 'other'; $tables[ $table_type ][ $table->name ] = array( 'data' => $table->data, diff --git a/src/Controllers/Version4/Utilities/ServerEnvironment.php b/src/Controllers/Version4/Utilities/ServerEnvironment.php index 1c7612a3bac..9d89040e51e 100644 --- a/src/Controllers/Version4/Utilities/ServerEnvironment.php +++ b/src/Controllers/Version4/Utilities/ServerEnvironment.php @@ -157,7 +157,7 @@ class ServerEnvironment { $curl_version = curl_version(); $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; } elseif ( extension_loaded( 'curl' ) ) { - $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); + $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce-rest-api' ); } return $curl_version; } diff --git a/src/Controllers/Version4/Utilities/SettingsTrait.php b/src/Controllers/Version4/Utilities/SettingsTrait.php index 68c04657177..f5ac8f64590 100644 --- a/src/Controllers/Version4/Utilities/SettingsTrait.php +++ b/src/Controllers/Version4/Utilities/SettingsTrait.php @@ -36,7 +36,7 @@ trait SettingsTrait { if ( array_key_exists( $value, $setting['options'] ) ) { return $value; } else { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -54,7 +54,7 @@ trait SettingsTrait { } if ( ! is_array( $values ) ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $final_values = array(); @@ -77,7 +77,7 @@ trait SettingsTrait { */ public function validate_setting_image_width_field( $values, $setting ) { if ( ! is_array( $values ) ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $current = $setting['value']; @@ -120,7 +120,7 @@ trait SettingsTrait { $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; return $value; } else { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } diff --git a/src/Controllers/Version4/Utilities/ThemeInformation.php b/src/Controllers/Version4/Utilities/ThemeInformation.php index fb99a3a48aa..489832351cb 100644 --- a/src/Controllers/Version4/Utilities/ThemeInformation.php +++ b/src/Controllers/Version4/Utilities/ThemeInformation.php @@ -85,7 +85,7 @@ class ThemeInformation { 'version_latest' => \WC_Admin_Status::get_latest_theme_version( $active_theme ), 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), 'is_child_theme' => is_child_theme(), - 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), + 'has_woocommerce_support' => current_theme_supports( 'woocommerce-rest-api' ), 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), 'has_outdated_templates' => $outdated_templates, 'overrides' => $override_files, diff --git a/src/Controllers/Version4/Utilities/WPEnvironment.php b/src/Controllers/Version4/Utilities/WPEnvironment.php index 5ebc5acb6d6..1e0b2edf449 100644 --- a/src/Controllers/Version4/Utilities/WPEnvironment.php +++ b/src/Controllers/Version4/Utilities/WPEnvironment.php @@ -46,23 +46,23 @@ class WPEnvironment { public function get_pages() { // WC pages to check against. $check_pages = array( - _x( 'Shop base', 'Page setting', 'woocommerce' ) => array( + _x( 'Shop base', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_shop_page_id', 'shortcode' => '', ), - _x( 'Cart', 'Page setting', 'woocommerce' ) => array( + _x( 'Cart', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_cart_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', ), - _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( + _x( 'Checkout', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_checkout_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', ), - _x( 'My account', 'Page setting', 'woocommerce' ) => array( + _x( 'My account', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_myaccount_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', ), - _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( + _x( 'Terms and conditions', 'Page setting', 'woocommerce-rest-api' ) => array( 'option' => 'woocommerce_terms_page_id', 'shortcode' => '', ), diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php index 17c1e911059..360661844a9 100644 --- a/src/Controllers/Version4/Webhooks.php +++ b/src/Controllers/Version4/Webhooks.php @@ -63,12 +63,12 @@ class Webhooks extends AbstractController { 'topic' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), ), 'delivery_url' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), + 'description' => __( 'Webhook delivery URL.', 'woocommerce-rest-api' ), ), ) ), @@ -84,7 +84,7 @@ class Webhooks extends AbstractController { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', ), ), @@ -110,7 +110,7 @@ class Webhooks extends AbstractController { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), ), ), ), @@ -216,7 +216,7 @@ class Webhooks extends AbstractController { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $object, $request ); @@ -231,17 +231,17 @@ class Webhooks extends AbstractController { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); } // Validate topic. if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } // Validate delivery URL. if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -293,7 +293,7 @@ class Webhooks extends AbstractController { $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } // Update topic. @@ -301,7 +301,7 @@ class Webhooks extends AbstractController { if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { $webhook->set_topic( $request['topic'] ); } else { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -310,7 +310,7 @@ class Webhooks extends AbstractController { if ( wc_is_valid_url( $request['delivery_url'] ) ) { $webhook->set_delivery_url( $request['delivery_url'] ); } else { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -324,7 +324,7 @@ class Webhooks extends AbstractController { if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { $webhook->set_status( $request['status'] ); } else { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } } @@ -368,13 +368,13 @@ class Webhooks extends AbstractController { // We don't support trashing for this type, error out. if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); @@ -382,7 +382,7 @@ class Webhooks extends AbstractController { $result = $webhook->delete( true ); if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); } $response = new \WP_REST_Response(); $response->set_data( @@ -420,7 +420,7 @@ class Webhooks extends AbstractController { // Validate required POST fields. if ( 'POST' === $request->get_method() && empty( $data->ID ) ) { - $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ); // @codingStandardsIgnoreLine + $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce-rest-api' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce-rest-api' ) ) ); // @codingStandardsIgnoreLine // Post author. $data->post_author = get_current_user_id(); @@ -513,42 +513,42 @@ class Webhooks extends AbstractController { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), + 'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Webhook status.', 'woocommerce' ), + 'description' => __( 'Webhook status.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'active', 'enum' => array_keys( wc_get_webhook_statuses() ), 'context' => array( 'view', 'edit' ), ), 'topic' => array( - 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'resource' => array( - 'description' => __( 'Webhook resource.', 'woocommerce' ), + 'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'event' => array( - 'description' => __( 'Webhook event.', 'woocommerce' ), + 'description' => __( 'Webhook event.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hooks' => array( - 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -557,37 +557,37 @@ class Webhooks extends AbstractController { ), ), 'delivery_url' => array( - 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'secret' => array( - 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce' ), + 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -609,19 +609,19 @@ class Webhooks extends AbstractController { $params['context']['default'] = 'view'; $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), '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' ), + 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -630,7 +630,7 @@ class Webhooks extends AbstractController { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), 'type' => 'array', 'items' => array( 'type' > 'integer', @@ -639,20 +639,20 @@ class Webhooks extends AbstractController { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), 'validate_callback' => 'rest_validate_request_arg', ); $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -664,7 +664,7 @@ class Webhooks extends AbstractController { ); $params['status'] = array( 'default' => 'all', - 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce' ), + 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce-rest-api' ), 'type' => 'string', 'enum' => array( 'all', 'active', 'paused', 'disabled' ), 'sanitize_callback' => 'sanitize_key', diff --git a/src/Utilities/ImageAttachment.php b/src/Utilities/ImageAttachment.php index a9fab68b8c7..115aa7d0279 100644 --- a/src/Utilities/ImageAttachment.php +++ b/src/Utilities/ImageAttachment.php @@ -58,7 +58,7 @@ class ImageAttachment { if ( ! wp_attachment_is_image( $this->id ) ) { /* translators: %s: image ID */ - throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $this->id ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $this->id ), 400 ); } } diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 1be24fe5ee4..ec068e1e999 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -36,7 +36,7 @@ if ( is_readable( $autoloader ) ) { error_log( // phpcs:ignore sprintf( /* translators: 1: composer command. 2: plugin directory */ - esc_html__( 'Your installation of the WooCommerce REST API feature plugin is incomplete. Please run %1$s within the %2$s directory.', 'woocommerce' ), + esc_html__( 'Your installation of the WooCommerce REST API feature plugin is incomplete. Please run %1$s within the %2$s directory.', 'woocommerce-rest-api' ), '`composer install`', '`' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '`' ) @@ -54,7 +54,7 @@ if ( is_readable( $autoloader ) ) { composer install', '' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '' ); From 1c82fd60f8a3ca044ef06e0b0e9a129abe5ac863 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jun 2019 15:47:00 +0100 Subject: [PATCH 175/440] Fix some strings which should not be replaced --- composer.lock | 50 +------------------ phpcs.xml | 2 +- ...ss-wc-rest-system-status-v2-controller.php | 6 +-- .../class-wc-rest-order-notes-controller.php | 2 +- src/Controllers/Version4/OrderNotes.php | 2 +- .../Utilities/DatabaseInformation.php | 4 +- .../Version4/Utilities/ThemeInformation.php | 2 +- 7 files changed, 10 insertions(+), 58 deletions(-) diff --git a/composer.lock b/composer.lock index aeca76fa924..32e9fe5d083 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0654700fc5735080c502c67e64be6c00", + "content-hash": "751413f93c1471f67dbcdbc9dd05c134", "packages": [ { "name": "automattic/jetpack-autoloader", @@ -1641,54 +1641,6 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, - { - "name": "slowprog/composer-copy-file", - "version": "0.3.1", - "source": { - "type": "git", - "url": "https://github.com/slowprog/CopyFile.git", - "reference": "5a82ba4613948f70b2d4b041c13c1c9259fc6477" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slowprog/CopyFile/zipball/5a82ba4613948f70b2d4b041c13c1c9259fc6477", - "reference": "5a82ba4613948f70b2d4b041c13c1c9259fc6477", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "composer/composer": "1.0.*@dev", - "mikey179/vfsstream": "~1", - "php-mock/php-mock-phpunit": "~1", - "phpunit/phpunit": "5.7.27", - "symfony/filesystem": "~2.7", - "symfony/finder": "~2.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "SlowProg\\CopyFile\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andrey Tyshev", - "email": "slowprog@gmail.com" - } - ], - "description": "Composer script copying your files after install", - "homepage": "https://github.com/SlowProg/composer-copy-file", - "keywords": [ - "copy file" - ], - "time": "2019-01-10T05:06:10+00:00" - }, { "name": "squizlabs/php_codesniffer", "version": "3.4.2", diff --git a/phpcs.xml b/phpcs.xml index 9df96537e9c..ceb59896bf8 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -17,7 +17,7 @@ - + diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 0f97047dcb0..64e7093fb12 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -744,7 +744,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. */ $tables = array( - 'woocommerce-rest-api' => array_fill_keys( $core_tables, false ), + 'woocommerce' => array_fill_keys( $core_tables, false ), 'other' => array(), ); @@ -760,7 +760,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { continue; } - $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce-rest-api' : 'other'; + $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce' : 'other'; $tables[ $table_type ][ $table->name ] = array( 'data' => $table->data, @@ -1001,7 +1001,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ), 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), 'is_child_theme' => is_child_theme(), - 'has_woocommerce_support' => current_theme_supports( 'woocommerce-rest-api' ), + 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), 'has_outdated_templates' => $outdated_templates, 'overrides' => $override_files, diff --git a/src/Controllers/Version3/class-wc-rest-order-notes-controller.php b/src/Controllers/Version3/class-wc-rest-order-notes-controller.php index 6015634664b..3e4d2e17f90 100644 --- a/src/Controllers/Version3/class-wc-rest-order-notes-controller.php +++ b/src/Controllers/Version3/class-wc-rest-order-notes-controller.php @@ -35,7 +35,7 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { public function prepare_item_for_response( $note, $request ) { $data = array( 'id' => (int) $note->comment_ID, - 'author' => __( 'woocommerce-rest-api', 'woocommerce-rest-api' ) === $note->comment_author ? 'system' : $note->comment_author, + 'author' => __( 'woocommerce', 'woocommerce-rest-api' ) === $note->comment_author ? 'system' : $note->comment_author, 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), 'note' => $note->comment_content, diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php index d95de72528f..3174a419420 100644 --- a/src/Controllers/Version4/OrderNotes.php +++ b/src/Controllers/Version4/OrderNotes.php @@ -336,7 +336,7 @@ class OrderNotes extends AbstractController { protected function get_data_for_response( $object, $request ) { return array( 'id' => (int) $object->comment_ID, - 'author' => __( 'woocommerce-rest-api', 'woocommerce-rest-api' ) === $object->comment_author ? 'system' : $object->comment_author, + 'author' => __( 'woocommerce', 'woocommerce-rest-api' ) === $object->comment_author ? 'system' : $object->comment_author, 'date_created' => wc_rest_prepare_date_response( $object->comment_date ), 'date_created_gmt' => wc_rest_prepare_date_response( $object->comment_date_gmt ), 'note' => $object->comment_content, diff --git a/src/Controllers/Version4/Utilities/DatabaseInformation.php b/src/Controllers/Version4/Utilities/DatabaseInformation.php index b5d9f0a37d7..be946dc9e9e 100644 --- a/src/Controllers/Version4/Utilities/DatabaseInformation.php +++ b/src/Controllers/Version4/Utilities/DatabaseInformation.php @@ -78,7 +78,7 @@ class DatabaseInformation { * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. */ $tables = array( - 'woocommerce-rest-api' => array_fill_keys( $core_tables, false ), + 'woocommerce' => array_fill_keys( $core_tables, false ), 'other' => array(), ); @@ -94,7 +94,7 @@ class DatabaseInformation { if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { continue; } - $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce-rest-api' : 'other'; + $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; $tables[ $table_type ][ $table->name ] = array( 'data' => $table->data, diff --git a/src/Controllers/Version4/Utilities/ThemeInformation.php b/src/Controllers/Version4/Utilities/ThemeInformation.php index 489832351cb..fb99a3a48aa 100644 --- a/src/Controllers/Version4/Utilities/ThemeInformation.php +++ b/src/Controllers/Version4/Utilities/ThemeInformation.php @@ -85,7 +85,7 @@ class ThemeInformation { 'version_latest' => \WC_Admin_Status::get_latest_theme_version( $active_theme ), 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), 'is_child_theme' => is_child_theme(), - 'has_woocommerce_support' => current_theme_supports( 'woocommerce-rest-api' ), + 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), 'has_outdated_templates' => $outdated_templates, 'overrides' => $override_files, From a703749a467f59531b0a3fee81aeb2715891b77f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jun 2019 16:06:26 +0100 Subject: [PATCH 176/440] Fixed tests --- unit-tests/Helpers/OrderHelper.php | 2 +- unit-tests/Tests/Version2/customers.php | 2 +- unit-tests/Tests/Version2/products.php | 6 +++--- unit-tests/Tests/Version2/settings.php | 4 ++-- unit-tests/Tests/Version3/customers.php | 2 +- unit-tests/Tests/Version3/functions.php | 4 ++-- unit-tests/Tests/Version3/products.php | 6 +++--- unit-tests/Tests/Version3/settings.php | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/unit-tests/Helpers/OrderHelper.php b/unit-tests/Helpers/OrderHelper.php index c52d7cf3ce4..59f72d1dcb2 100644 --- a/unit-tests/Helpers/OrderHelper.php +++ b/unit-tests/Helpers/OrderHelper.php @@ -30,7 +30,7 @@ class OrderHelper { // Delete all products in the order. foreach ( $order->get_items() as $item ) { - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::delete_product( $item['product_id'] ); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::delete_product( $item['product_id'] ); } ShippingHelper::delete_simple_flat_rate(); diff --git a/unit-tests/Tests/Version2/customers.php b/unit-tests/Tests/Version2/customers.php index 5135bf7c967..f9a4d5acca1 100644 --- a/unit-tests/Tests/Version2/customers.php +++ b/unit-tests/Tests/Version2/customers.php @@ -38,7 +38,7 @@ class Customers_V2 extends WC_REST_Unit_Test_Case { wp_set_current_user( 1 ); $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); - \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v2/customers' ); $request->set_query_params( diff --git a/unit-tests/Tests/Version2/products.php b/unit-tests/Tests/Version2/products.php index 4de979db12a..165110cad3b 100644 --- a/unit-tests/Tests/Version2/products.php +++ b/unit-tests/Tests/Version2/products.php @@ -43,9 +43,9 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_products() { wp_set_current_user( $this->user ); - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); sleep( 1 ); // So both products have different timestamps. - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); $products = $response->get_data(); @@ -65,7 +65,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { */ public function test_get_products_without_permission() { wp_set_current_user( 0 ); - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); $this->assertEquals( 401, $response->get_status() ); } diff --git a/unit-tests/Tests/Version2/settings.php b/unit-tests/Tests/Version2/settings.php index 777442dfff3..3debe1b5272 100644 --- a/unit-tests/Tests/Version2/settings.php +++ b/unit-tests/Tests/Version2/settings.php @@ -14,7 +14,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function setUp() { parent::setUp(); $this->endpoint = new WC_REST_Setting_Options_Controller(); - \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', @@ -110,7 +110,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings' ) ); $this->assertEquals( 500, $response->get_status() ); - \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); } /** diff --git a/unit-tests/Tests/Version3/customers.php b/unit-tests/Tests/Version3/customers.php index bd997f5881f..8d4508bade4 100644 --- a/unit-tests/Tests/Version3/customers.php +++ b/unit-tests/Tests/Version3/customers.php @@ -44,7 +44,7 @@ class Customers extends WC_REST_Unit_Test_Case { wp_set_current_user( 1 ); $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); - \WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); $request->set_query_params( diff --git a/unit-tests/Tests/Version3/functions.php b/unit-tests/Tests/Version3/functions.php index 19a523f5d5d..8707d3ec54f 100644 --- a/unit-tests/Tests/Version3/functions.php +++ b/unit-tests/Tests/Version3/functions.php @@ -232,14 +232,14 @@ class WC_Tests_API_Functions extends WC_Unit_Test_Case { } elseif ( 'http://somedomain.com/invalid-image-2.png' === $url ) { // image with an unsupported mime type. // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/file.txt', $request['filename'] ); + copy( Automattic\WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/file.txt', $request['filename'] ); $mocked_response = array( 'response' => array( 'code' => 200 ), ); } elseif ( 'http://somedomain.com/' . $this->file_name === $url ) { // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/Dr1Bczxq4q.png', $request['filename'] ); + copy( Automattic\WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/Dr1Bczxq4q.png', $request['filename'] ); $mocked_response = array( 'response' => array( 'code' => 200 ), diff --git a/unit-tests/Tests/Version3/products.php b/unit-tests/Tests/Version3/products.php index aeb08700395..7da09a9c136 100644 --- a/unit-tests/Tests/Version3/products.php +++ b/unit-tests/Tests/Version3/products.php @@ -43,9 +43,9 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_get_products() { wp_set_current_user( $this->user ); - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); sleep( 1 ); // So both products have different timestamps. - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); $products = $response->get_data(); @@ -65,7 +65,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { */ public function test_get_products_without_permission() { wp_set_current_user( 0 ); - \WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); $this->assertEquals( 401, $response->get_status() ); } diff --git a/unit-tests/Tests/Version3/settings.php b/unit-tests/Tests/Version3/settings.php index 4fac9ba3509..d78e2faef9b 100644 --- a/unit-tests/Tests/Version3/settings.php +++ b/unit-tests/Tests/Version3/settings.php @@ -14,7 +14,7 @@ class Settings extends WC_REST_Unit_Test_Case { public function setUp() { parent::setUp(); $this->endpoint = new WC_REST_Setting_Options_Controller(); - \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', @@ -110,7 +110,7 @@ class Settings extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings' ) ); $this->assertEquals( 500, $response->get_status() ); - \WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); + \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); } /** From 09ef1e74cf727175297c3aa5cbe4a7b42d555778 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 24 Jun 2019 16:17:02 +0100 Subject: [PATCH 177/440] Rename tests dir --- .gitattributes | 2 +- .gitignore | 2 +- .scrutinizer.yml | 2 +- .travis.yml | 6 +++--- phpunit.xml | 6 +++--- unit-tests/Bootstrap.php | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.gitattributes b/.gitattributes index b5d3da03cbb..9dabeff5ad2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,7 +1,7 @@ /.* export-ignore /phpcs.xml export-ignore /phpunit.* export-ignore -/unit-tests export-ignore +/tests export-ignore /vendor export-ignore /README.md export-ignore /readme.txt export-ignore diff --git a/.gitignore b/.gitignore index dd37e6a9ec2..992c5e6328a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,7 @@ Thumbs.db # Unit tests /tmp -/unit-tests/bin/tmp +/tests/bin/tmp # Logs /logs diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 425a5847ebc..04bbd2b73b4 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -27,7 +27,7 @@ filter: - src/Controllers/Version1/ - src/Controllers/Version2/ - src/Controllers/Version3/ - - unit-tests/ + - tests/ - vendor/ - classmap.php coding_style: diff --git a/.travis.yml b/.travis.yml index ecc05440f0b..38f92b14e2c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,8 +20,8 @@ before_script: - composer install - composer global require "phpunit/phpunit=4.8.*|6.5.*" - composer require woocommerce/woocommerce-sniffs - - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION + - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION script: - - bash unit-tests/bin/phpunit.sh - - bash unit-tests/bin/phpcs.sh \ No newline at end of file + - bash tests/bin/phpunit.sh + - bash tests/bin/phpcs.sh diff --git a/phpunit.xml b/phpunit.xml index 8f9df0b9fb5..ddb43245333 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,6 +1,6 @@ - ./unit-tests/Tests + ./tests/Tests - ./unit-tests/Tests/Version4 + ./tests/Tests/Version4 diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index 4988801e59d..d4658968ce8 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -21,14 +21,14 @@ class Bootstrap { protected $wp_tests_dir; /** - * unit-tests directory. + * Tests directory. * * @var string */ protected $tests_dir; /** - * WC Core unit-tests directory. + * WC Core unit tests directory. * * @var string */ From a6db14ba38ee22d4af72eeac860413e5ba84f7c8 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 25 Jun 2019 16:12:47 +0100 Subject: [PATCH 178/440] Update test paths --- .gitattributes | 2 +- .gitignore | 1 - phpunit.xml | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.gitattributes b/.gitattributes index 9dabeff5ad2..b5d3da03cbb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,7 +1,7 @@ /.* export-ignore /phpcs.xml export-ignore /phpunit.* export-ignore -/tests export-ignore +/unit-tests export-ignore /vendor export-ignore /README.md export-ignore /readme.txt export-ignore diff --git a/.gitignore b/.gitignore index 992c5e6328a..77f4d76fe9c 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,3 @@ Thumbs.db # composer vendor/ -classmap.php.bak diff --git a/phpunit.xml b/phpunit.xml index ddb43245333..8f9df0b9fb5 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,6 +1,6 @@ - ./tests/Tests + ./unit-tests/Tests - ./tests/Tests/Version4 + ./unit-tests/Tests/Version4 From 48b9ff06953da8879721e1bef86a94f80f19cc38 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 25 Jun 2019 16:16:58 +0100 Subject: [PATCH 179/440] Versions --- src/Package.php | 2 +- woocommerce-rest-api.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Package.php b/src/Package.php index ec3cc6474d2..6660b41560f 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.0'; + const VERSION = '1.1.0-dev'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index ec068e1e999..474529f1cc1 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.0-dev + * Version: 1.1.0-dev * Requires PHP: 5.6 * License: GPLv3 * From 8b82b840139d6734a4accd29d03d8ad2c3715796 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 25 Jun 2019 16:17:22 +0100 Subject: [PATCH 180/440] Autoload version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index be084222a5c..4dad153c7dd 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "prefer-stable": true, "minimum-stability": "dev", "require": { - "automattic/jetpack-autoloader": "^1" + "automattic/jetpack-autoloader": "1.2.0" }, "require-dev": { "phpunit/phpunit": "6.5.14", From 370d6c1a047edbf47c56e2e0b0978e1c48d71231 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 25 Jun 2019 16:18:35 +0100 Subject: [PATCH 181/440] remove v4 for 1.0 release --- phpunit.xml | 3 - .../Version4/AbstractController.php | 348 ----- .../Version4/AbstractObjectsController.php | 767 ----------- .../AbstractShippingZonesController.php | 104 -- .../Version4/AbstractTermsContoller.php | 659 --------- src/Controllers/Version4/Coupons.php | 465 ------- .../Version4/CustomerDownloads.php | 235 ---- src/Controllers/Version4/Customers.php | 792 ----------- src/Controllers/Version4/Data.php | 153 -- src/Controllers/Version4/Data/Continents.php | 340 ----- src/Controllers/Version4/Data/Countries.php | 222 --- src/Controllers/Version4/Data/Currencies.php | 209 --- src/Controllers/Version4/Data/DownloadIPs.php | 149 -- src/Controllers/Version4/NetworkOrders.php | 166 --- src/Controllers/Version4/OrderNotes.php | 449 ------ src/Controllers/Version4/OrderRefunds.php | 665 --------- src/Controllers/Version4/Orders.php | 1185 ---------------- src/Controllers/Version4/PaymentGateways.php | 426 ------ .../Version4/ProductAttributeTerms.php | 225 --- .../Version4/ProductAttributes.php | 490 ------- .../Version4/ProductCategories.php | 253 ---- src/Controllers/Version4/ProductReviews.php | 1017 -------------- .../Version4/ProductShippingClasses.php | 102 -- src/Controllers/Version4/ProductTags.php | 102 -- .../Version4/ProductVariations.php | 902 ------------ src/Controllers/Version4/Products.php | 1227 ----------------- .../Requests/AbstractObjectRequest.php | 64 - .../Version4/Requests/CustomerRequest.php | 105 -- .../Version4/Requests/OrderRequest.php | 387 ------ .../Version4/Requests/ProductRequest.php | 440 ------ .../Requests/ProductVariationRequest.php | 188 --- .../Responses/AbstractObjectResponse.php | 25 - .../Version4/Responses/CustomerResponse.php | 54 - .../Version4/Responses/OrderResponse.php | 183 --- .../Version4/Responses/ProductResponse.php | 354 ----- .../Responses/ProductReviewResponse.php | 71 - .../Responses/ProductVariationResponse.php | 111 -- src/Controllers/Version4/Settings.php | 208 --- src/Controllers/Version4/SettingsOptions.php | 581 -------- src/Controllers/Version4/ShippingMethods.php | 191 --- .../Version4/ShippingZoneLocations.php | 172 --- .../Version4/ShippingZoneMethods.php | 557 -------- src/Controllers/Version4/ShippingZones.php | 306 ---- src/Controllers/Version4/SystemStatus.php | 588 -------- .../Version4/SystemStatusTools.php | 577 -------- src/Controllers/Version4/TaxClasses.php | 310 ----- src/Controllers/Version4/Taxes.php | 623 --------- .../Version4/Utilities/BatchTrait.php | 281 ---- .../Utilities/DatabaseInformation.php | 118 -- .../Version4/Utilities/Pagination.php | 81 -- .../Version4/Utilities/Permissions.php | 238 ---- .../Version4/Utilities/PluginInformation.php | 149 -- .../Version4/Utilities/ServerEnvironment.php | 187 --- .../Version4/Utilities/SettingsTrait.php | 152 -- .../Version4/Utilities/ThemeInformation.php | 96 -- .../Version4/Utilities/WPEnvironment.php | 115 -- .../Version4/Utilities/WooEnvironment.php | 59 - src/Controllers/Version4/Webhooks.php | 685 --------- src/Controllers/Version4/_changelog.md | 31 - src/Package.php | 2 +- src/Server.php | 46 - unit-tests/Tests/Version4/Coupons.php | 319 ----- unit-tests/Tests/Version4/Customers.php | 649 --------- unit-tests/Tests/Version4/Data.php | 133 -- unit-tests/Tests/Version4/Orders.php | 656 --------- unit-tests/Tests/Version4/PaymentGateways.php | 358 ----- unit-tests/Tests/Version4/ProductReviews.php | 400 ------ .../Tests/Version4/ProductVariations.php | 487 ------- unit-tests/Tests/Version4/Products.php | 838 ----------- unit-tests/Tests/Version4/Settings.php | 886 ------------ unit-tests/Tests/Version4/ShippingMethods.php | 159 --- unit-tests/Tests/Version4/ShippingZones.php | 811 ----------- unit-tests/Tests/Version4/SystemStatus.php | 459 ------ woocommerce-rest-api.php | 2 +- 74 files changed, 2 insertions(+), 26145 deletions(-) delete mode 100644 src/Controllers/Version4/AbstractController.php delete mode 100644 src/Controllers/Version4/AbstractObjectsController.php delete mode 100644 src/Controllers/Version4/AbstractShippingZonesController.php delete mode 100644 src/Controllers/Version4/AbstractTermsContoller.php delete mode 100644 src/Controllers/Version4/Coupons.php delete mode 100644 src/Controllers/Version4/CustomerDownloads.php delete mode 100644 src/Controllers/Version4/Customers.php delete mode 100644 src/Controllers/Version4/Data.php delete mode 100644 src/Controllers/Version4/Data/Continents.php delete mode 100644 src/Controllers/Version4/Data/Countries.php delete mode 100644 src/Controllers/Version4/Data/Currencies.php delete mode 100644 src/Controllers/Version4/Data/DownloadIPs.php delete mode 100644 src/Controllers/Version4/NetworkOrders.php delete mode 100644 src/Controllers/Version4/OrderNotes.php delete mode 100644 src/Controllers/Version4/OrderRefunds.php delete mode 100644 src/Controllers/Version4/Orders.php delete mode 100644 src/Controllers/Version4/PaymentGateways.php delete mode 100644 src/Controllers/Version4/ProductAttributeTerms.php delete mode 100644 src/Controllers/Version4/ProductAttributes.php delete mode 100644 src/Controllers/Version4/ProductCategories.php delete mode 100644 src/Controllers/Version4/ProductReviews.php delete mode 100644 src/Controllers/Version4/ProductShippingClasses.php delete mode 100644 src/Controllers/Version4/ProductTags.php delete mode 100644 src/Controllers/Version4/ProductVariations.php delete mode 100644 src/Controllers/Version4/Products.php delete mode 100644 src/Controllers/Version4/Requests/AbstractObjectRequest.php delete mode 100644 src/Controllers/Version4/Requests/CustomerRequest.php delete mode 100644 src/Controllers/Version4/Requests/OrderRequest.php delete mode 100644 src/Controllers/Version4/Requests/ProductRequest.php delete mode 100644 src/Controllers/Version4/Requests/ProductVariationRequest.php delete mode 100644 src/Controllers/Version4/Responses/AbstractObjectResponse.php delete mode 100644 src/Controllers/Version4/Responses/CustomerResponse.php delete mode 100644 src/Controllers/Version4/Responses/OrderResponse.php delete mode 100644 src/Controllers/Version4/Responses/ProductResponse.php delete mode 100644 src/Controllers/Version4/Responses/ProductReviewResponse.php delete mode 100644 src/Controllers/Version4/Responses/ProductVariationResponse.php delete mode 100644 src/Controllers/Version4/Settings.php delete mode 100644 src/Controllers/Version4/SettingsOptions.php delete mode 100644 src/Controllers/Version4/ShippingMethods.php delete mode 100644 src/Controllers/Version4/ShippingZoneLocations.php delete mode 100644 src/Controllers/Version4/ShippingZoneMethods.php delete mode 100644 src/Controllers/Version4/ShippingZones.php delete mode 100644 src/Controllers/Version4/SystemStatus.php delete mode 100644 src/Controllers/Version4/SystemStatusTools.php delete mode 100644 src/Controllers/Version4/TaxClasses.php delete mode 100644 src/Controllers/Version4/Taxes.php delete mode 100644 src/Controllers/Version4/Utilities/BatchTrait.php delete mode 100644 src/Controllers/Version4/Utilities/DatabaseInformation.php delete mode 100644 src/Controllers/Version4/Utilities/Pagination.php delete mode 100644 src/Controllers/Version4/Utilities/Permissions.php delete mode 100644 src/Controllers/Version4/Utilities/PluginInformation.php delete mode 100644 src/Controllers/Version4/Utilities/ServerEnvironment.php delete mode 100644 src/Controllers/Version4/Utilities/SettingsTrait.php delete mode 100644 src/Controllers/Version4/Utilities/ThemeInformation.php delete mode 100644 src/Controllers/Version4/Utilities/WPEnvironment.php delete mode 100644 src/Controllers/Version4/Utilities/WooEnvironment.php delete mode 100644 src/Controllers/Version4/Webhooks.php delete mode 100644 src/Controllers/Version4/_changelog.md delete mode 100644 unit-tests/Tests/Version4/Coupons.php delete mode 100644 unit-tests/Tests/Version4/Customers.php delete mode 100644 unit-tests/Tests/Version4/Data.php delete mode 100644 unit-tests/Tests/Version4/Orders.php delete mode 100644 unit-tests/Tests/Version4/PaymentGateways.php delete mode 100644 unit-tests/Tests/Version4/ProductReviews.php delete mode 100644 unit-tests/Tests/Version4/ProductVariations.php delete mode 100644 unit-tests/Tests/Version4/Products.php delete mode 100644 unit-tests/Tests/Version4/Settings.php delete mode 100644 unit-tests/Tests/Version4/ShippingMethods.php delete mode 100644 unit-tests/Tests/Version4/ShippingZones.php delete mode 100644 unit-tests/Tests/Version4/SystemStatus.php diff --git a/phpunit.xml b/phpunit.xml index 8f9df0b9fb5..9119520176d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -13,8 +13,5 @@ ./unit-tests/Tests - - ./unit-tests/Tests/Version4 - diff --git a/src/Controllers/Version4/AbstractController.php b/src/Controllers/Version4/AbstractController.php deleted file mode 100644 index 9916af122ed..00000000000 --- a/src/Controllers/Version4/AbstractController.php +++ /dev/null @@ -1,348 +0,0 @@ - - * - * @class \WC_REST_Controller - * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -use \WP_REST_Controller; -use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; -use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\BatchTrait; - -/** - * Abstract Rest Controller Class - * - * @package Automattic/WooCommerce/RestApi - * @extends WP_REST_Controller - * @version 2.6.0 - */ -abstract class AbstractController extends WP_REST_Controller { - use BatchTrait; - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v4'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = ''; - - /** - * Permission to check. - * - * @var string - */ - protected $resource_type = ''; - - /** - * Register route for items requests. - * - * @param array $methods Supported methods. read, create. - */ - protected function register_items_route( $methods = [ 'read', 'create' ] ) { - $routes = []; - $routes['schema'] = [ $this, 'get_public_item_schema' ]; - - if ( in_array( 'read', $methods, true ) ) { - $routes[] = array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ); - } - - if ( in_array( 'create', $methods, true ) ) { - $routes[] = array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - ); - } - - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - $routes, - true - ); - } - - /** - * Register route for item create/get/delete/update requests. - * - * @param array $methods Supported methods. read, create. - */ - protected function register_item_route( $methods = [ 'read', 'edit', 'delete' ] ) { - $routes = []; - $routes['schema'] = [ $this, 'get_public_item_schema' ]; - $routes['args'] = [ - 'id' => [ - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ], - ]; - - if ( in_array( 'read', $methods, true ) ) { - $routes[] = array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ); - } - - if ( in_array( 'edit', $methods, true ) ) { - $routes[] = array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ); - } - - if ( in_array( 'delete', $methods, true ) ) { - $routes[] = array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - ), - ), - ); - } - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - $routes, - true - ); - } - - /** - * Add the schema from additional fields to an schema array. - * - * @param array $schema Schema array. - * @return array - */ - protected function add_additional_fields_schema( $schema ) { - $schema = parent::add_additional_fields_schema( $schema ); - $object_type = $schema['title']; - $schema['properties'] = apply_filters( 'woocommerce_rest_' . $object_type . '_schema', $schema['properties'] ); - return $schema; - } - - - - /** - * Check whether a given request has permission to read webhooks. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - $permission = Permissions::user_can_list( $this->get_item_title() ); - - if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return $permission; - } - - /** - * Check if a given request has access create webhooks. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function create_item_permissions_check( $request ) { - $permission = Permissions::user_can_create( $this->get_item_title() ); - - if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return $permission; - } - - /** - * Check if a given request has access to read a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $permission = Permissions::user_can_read( $this->get_item_title(), $id ); - - if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return $permission; - } - - /** - * Check if a given request has access update a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function update_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $permission = Permissions::user_can_edit( $this->get_item_title(), $id ); - - if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return $permission; - } - - /** - * Check if a given request has access delete a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $permission = Permissions::user_can_delete( $this->get_item_title(), $id ); - - if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return $permission; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - $permission = Permissions::user_can_batch( $this->get_item_title() ); - - if ( false === $permission ) { - return new \WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return $permission; - } - - /** - * Get context for the request. - * - * @param \WP_REST_Request $request Full details about the request. - * @return string - */ - protected function get_request_context( $request ) { - return ! empty( $request['context'] ) ? $request['context'] : 'view'; - } - - /** - * Prepare a single item for response. - * - * @param mixed $item Object used to create response. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - try { - $context = $this->get_request_context( $request ); - $fields = $this->get_fields_for_response( $request ); - $data = $this->get_data_for_response( $item, $request ); - $data = array_intersect_key( $data, array_flip( $fields ) ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $item, $request ) ); - } catch ( \WC_REST_Exception $e ) { - $response = rest_ensure_response( new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ) ); - } - - /** - * Filter object returned from the REST API. - * - * @param \WP_REST_Response $response The response object. - * @param mixed $item Object used to create response. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_' . $this->get_hook_suffix(), $response, $item, $request ); - } - - /** - * Return suffix for item action hooks. - * - * @return string - */ - protected function get_item_title() { - $schema = $this->get_item_schema(); - return $schema['title']; - } - - /** - * Return suffix for item action hooks. - * - * @return string - */ - protected function get_hook_suffix() { - return $this->get_item_title(); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param mixed $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return mixed Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return $object; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - return array(); - } -} diff --git a/src/Controllers/Version4/AbstractObjectsController.php b/src/Controllers/Version4/AbstractObjectsController.php deleted file mode 100644 index 332ae8828b7..00000000000 --- a/src/Controllers/Version4/AbstractObjectsController.php +++ /dev/null @@ -1,767 +0,0 @@ -register_items_route(); - $this->register_item_route(); - $this->register_batch_route(); - } - - /** - * Get a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $data = $this->prepare_item_for_response( $object, $request ); - $response = rest_ensure_response( $data ); - - return $response; - } - - /** - * Save an object data. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. - * @return \WC_Data|\WP_Error - */ - protected function save_object( $request, $creating = false ) { - try { - $object = $this->prepare_object_for_database( $request, $creating ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - $object->save(); - - return $this->get_object( $object->get_id() ); - } catch ( \WC_Data_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( \WC_REST_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Create a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $object = $this->save_object( $request, true ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - try { - $this->update_additional_fields_for_object( $object, $request ); - } catch ( \WC_Data_Exception $e ) { - $object->delete(); - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( \WC_REST_Exception $e ) { - $object->delete(); - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - /** - * Fires after a single object is created or updated via the REST API. - * - * @param \WC_Data $object Inserted object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating object, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $object, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ) ); - - return $response; - } - - /** - * Update a single post. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function update_item( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $object = $this->save_object( $request, false ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - try { - $this->update_additional_fields_for_object( $object, $request ); - } catch ( \WC_Data_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( \WC_REST_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - /** - * Fires after a single object is created or updated via the REST API. - * - * @param \WC_Data $object Inserted object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating object, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $object, $request ); - return rest_ensure_response( $response ); - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = array(); - $args['offset'] = $request['offset']; - $args['order'] = $request['order']; - $args['orderby'] = $request['orderby']; - $args['paged'] = $request['page']; - $args['post__in'] = $request['include']; - $args['post__not_in'] = $request['exclude']; - $args['posts_per_page'] = $request['per_page']; - $args['name'] = $request['slug']; - $args['post_parent__in'] = $request['parent']; - $args['post_parent__not_in'] = $request['parent_exclude']; - $args['s'] = $request['search']; - $args['fields'] = 'ids'; - - if ( 'date' === $args['orderby'] ) { - $args['orderby'] = 'date ID'; - } - - $args['date_query'] = array(); - - // Set before into date query. Date query must be specified as an array of an array. - if ( isset( $request['before'] ) ) { - $args['date_query'][0]['before'] = $request['before']; - } - - // Set after into date query. Date query must be specified as an array of an array. - if ( isset( $request['after'] ) ) { - $args['date_query'][0]['after'] = $request['after']; - } - - // Set date query colummn. Defaults to post_date. - if ( isset( $request['date_column'] ) && ! empty( $args['date_query'][0] ) ) { - $args['date_query'][0]['column'] = 'post_' . $request['date_column']; - } - - // Force the post_type argument, since it's not a user input variable. - $args['post_type'] = $this->post_type; - - /** - * 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_{$this->post_type}_object_query", $args, $request ); - - return $this->prepare_items_query( $args, $request ); - } - - /** - * Get objects. - * - * @since 3.0.0 - * @param array $query_args Query args. - * @return array - */ - protected function get_objects( $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( array( $this, 'get_object' ), $result ), - 'total' => (int) $total_posts, - 'pages' => (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ), - ); - } - - /** - * Get a collection of posts. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Response - */ - public function get_items( $request ) { - $query_args = $this->prepare_objects_query( $request ); - $query_results = $this->get_objects( $query_args ); - - $objects = array(); - foreach ( $query_results['objects'] as $object ) { - if ( ! Permissions::user_can_read( $this->post_type, $object->get_id() ) ) { - continue; - } - - $data = $this->prepare_item_for_response( $object, $request ); - $objects[] = $this->prepare_response_for_collection( $data ); - } - - $total = $query_results['total']; - $max_pages = $query_results['pages']; - - $response = rest_ensure_response( $objects ); - $response = Pagination::add_pagination_headers( $response, $request, $total, $max_pages ); - - return $response; - } - - /** - * Delete a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Response|\WP_Error - */ - public function delete_item( $request ) { - $force = (bool) $request['force']; - $object = $this->get_object( (int) $request['id'] ); - $result = false; - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $supports_trash = $this->supports_trash( $object ); - - if ( ! Permissions::user_can_delete( $this->post_type, $object->get_id() ) ) { - /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); - } - - $request->set_param( 'context', 'edit' ); - $previous = $this->prepare_item_for_response( $object, $request ); - - // If we're forcing, then delete permanently. - if ( $force ) { - $object->delete( true ); - $result = 0 === $object->get_id(); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); - } - - // Otherwise, only trash if we haven't already. - if ( is_callable( array( $object, 'get_status' ) ) && 'trash' === $object->get_status() ) { - /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); - } else { - $object->delete(); - $result = is_callable( array( $object, 'get_status' ) ) ? 'trash' === $object->get_status() : true; - } - } - - if ( ! $result ) { - /* translators: %s: post type */ - return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); - } - - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - - /** - * Fires after a single object is deleted or trashed via the REST API. - * - * @param \WC_Data $object The deleted or trashed object. - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); - - return $response; - } - - /** - * Can this object be trashed? - * - * @param object $object Object to check. - * @return boolean - */ - protected function supports_trash( $object ) { - $supports_trash = EMPTY_TRASH_DAYS > 0; - - /** - * Filter whether an object is trashable. - * - * Return false to disable trash support for the object. - * - * @param boolean $supports_trash Whether the object type support trashing. - * @param \WC_Data $object The object being considered for trashing support. - */ - return apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param(); - $params['context']['default'] = 'view'; - - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['search'] = array( - 'description' => __( 'Limit results to those matching a string.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['after'] = array( - 'description' => __( 'Limit response to resources created after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['before'] = array( - 'description' => __( 'Limit response to resources created before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['date_column'] = array( - 'description' => __( 'When limiting response using after/before, which date column to compare against.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'date_gmt', - 'modified', - 'modified_gmt', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['modified_before'] = array( - 'description' => __( 'Limit response to resources modified before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'modified', - 'id', - 'include', - 'title', - 'slug', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - if ( $this->hierarchical ) { - $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'sanitize_callback' => 'wp_parse_id_list', - 'default' => array(), - ); - } - - /** - * Filter collection parameters for the posts controller. - * - * The dynamic part of the filter `$this->post_type` refers to the post - * type slug for the controller. - * - * This filter registers the collection parameter, but does not map the - * collection parameter to an internal \WP_Query parameter. Use the - * `rest_{$this->post_type}_query` filter to set \WP_Query parameters. - * - * @param array $query_params JSON Schema-formatted collection parameters. - * @param \WP_Post_Type $post_type Post type object. - */ - return apply_filters( "rest_{$this->post_type}_collection_params", $params, $this->post_type ); - } - - /** - * Determine the allowed query_vars for a get_items() response and - * prepare for \WP_Query. - * - * @param array $prepared_args Prepared arguments. - * @param \WP_REST_Request $request Request object. - * @return array $query_args - */ - protected function prepare_items_query( $prepared_args = array(), $request = null ) { - $valid_vars = array_flip( $this->get_allowed_query_vars() ); - $query_args = array(); - foreach ( $valid_vars as $var => $index ) { - if ( isset( $prepared_args[ $var ] ) ) { - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $var, refers to the query_var key. - * - * @param mixed $prepared_args[ $var ] The query_var value. - */ - $query_args[ $var ] = apply_filters( "woocommerce_rest_query_var_{$var}", $prepared_args[ $var ] ); - } - } - - $query_args['ignore_sticky_posts'] = true; - - if ( 'include' === $query_args['orderby'] ) { - $query_args['orderby'] = 'post__in'; - } elseif ( 'id' === $query_args['orderby'] ) { - $query_args['orderby'] = 'ID'; // ID must be capitalized. - } elseif ( 'slug' === $query_args['orderby'] ) { - $query_args['orderby'] = 'name'; - } - - return $query_args; - } - - /** - * Get all the WP Query vars that are allowed for the API request. - * - * @return array - */ - protected function get_allowed_query_vars() { - global $wp; - - /** - * Filter the publicly allowed query vars. - * - * Allows adjusting of the default query vars that are made public. - * - * @param array Array of allowed \WP_Query query vars. - */ - $valid_vars = apply_filters( 'query_vars', $wp->public_query_vars ); - - $post_type_obj = get_post_type_object( $this->post_type ); - if ( current_user_can( $post_type_obj->cap->edit_posts ) ) { - /** - * Filter the allowed 'private' query vars for authorized users. - * - * If the user has the `edit_posts` capability, we also allow use of - * private query parameters, which are only undesirable on the - * frontend, but are safe for use in query strings. - * - * To disable anyway, use - * `add_filter( 'woocommerce_rest_private_query_vars', '__return_empty_array' );` - * - * @param array $private_query_vars Array of allowed query vars for authorized users. - * } - */ - $private = apply_filters( 'woocommerce_rest_private_query_vars', $wp->private_query_vars ); - $valid_vars = array_merge( $valid_vars, $private ); - } - // Define our own in addition to WP's normal vars. - $rest_valid = array( - 'date_query', - 'ignore_sticky_posts', - 'offset', - 'post__in', - 'post__not_in', - 'post_parent', - 'post_parent__in', - 'post_parent__not_in', - 'posts_per_page', - 'meta_query', - 'tax_query', - 'meta_key', - 'meta_value', - 'meta_compare', - 'meta_value_num', - ); - $valid_vars = array_merge( $valid_vars, $rest_valid ); - - /** - * Filter allowed query vars for the REST API. - * - * This filter allows you to add or remove query vars from the final allowed - * list for all requests, including unauthenticated ones. To alter the - * vars for editors only. - * - * @param array { - * Array of allowed \WP_Query query vars. - * - * @param string $allowed_query_var The query var to allow. - * } - */ - $valid_vars = apply_filters( 'woocommerce_rest_query_vars', $valid_vars ); - - return $valid_vars; - } - - /** - * Add meta query. - * - * @since 3.0.0 - * @param array $args Query args. - * @param array $meta_query Meta query. - * @return array - */ - protected function add_meta_query( $args, $meta_query ) { - if ( empty( $args['meta_query'] ) ) { - $args['meta_query'] = []; // phpcs:ignore - } - - $args['meta_query'][] = $meta_query; - - return $args['meta_query']; - } - - /** - * Return suffix for item action hooks. - * - * @return string - */ - protected function get_hook_suffix() { - return $this->post_type . '_object'; - } - - /** - * Check if a given request has access to read a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $object = $this->get_object( $id ); - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - return parent::get_item_permissions_check( $request ); - } - - /** - * Check if a given request has access update a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function update_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $object = $this->get_object( $id ); - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - return parent::update_item_permissions_check( $request ); - } - - /** - * Check if a given request has access delete a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $object = $this->get_object( $id ); - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - return parent::delete_item_permissions_check( $request ); - } -} diff --git a/src/Controllers/Version4/AbstractShippingZonesController.php b/src/Controllers/Version4/AbstractShippingZonesController.php deleted file mode 100644 index 88f7e9d7f7e..00000000000 --- a/src/Controllers/Version4/AbstractShippingZonesController.php +++ /dev/null @@ -1,104 +0,0 @@ - 404 ) ); - } - - return $zone; - } - - /** - * Check whether a given request has permission to read Shipping Zones. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return parent::get_items_permissions_check( $request ); - } - - /** - * Check if a given request has access to create Shipping Zones. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return parent::create_item_permissions_check( $request ); - } - - /** - * Check whether a given request has permission to edit Shipping Zones. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return parent::update_item_permissions_check( $request ); - } - - /** - * Check whether a given request has permission to delete Shipping Zones. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new \WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return parent::delete_item_permissions_check( $request ); - } -} diff --git a/src/Controllers/Version4/AbstractTermsContoller.php b/src/Controllers/Version4/AbstractTermsContoller.php deleted file mode 100644 index 68a41e8418a..00000000000 --- a/src/Controllers/Version4/AbstractTermsContoller.php +++ /dev/null @@ -1,659 +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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'name' => array( - 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), - 'required' => true, - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - $this->register_batch_route(); - } - - /** - * Get terms associated with a taxonomy. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Response|\WP_Error - */ - public function get_items( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $prepared_args = array( - 'exclude' => $request['exclude'], - 'include' => $request['include'], - 'order' => $request['order'], - 'orderby' => $request['orderby'], - 'product' => $request['product'], - 'hide_empty' => $request['hide_empty'], - 'number' => $request['per_page'], - 'search' => $request['search'], - 'slug' => $request['slug'], - ); - - if ( ! empty( $request['offset'] ) ) { - $prepared_args['offset'] = $request['offset']; - } else { - $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; - } - - $taxonomy_obj = get_taxonomy( $taxonomy ); - - if ( $taxonomy_obj->hierarchical && isset( $request['parent'] ) ) { - if ( 0 === $request['parent'] ) { - // Only query top-level terms. - $prepared_args['parent'] = 0; - } else { - if ( $request['parent'] ) { - $prepared_args['parent'] = $request['parent']; - } - } - } - - /** - * Filter the query arguments, before passing them to `get_terms()`. - * - * Enables adding extra arguments or setting defaults for a terms - * collection request. - * - * @see https://developer.wordpress.org/reference/functions/get_terms/ - * - * @param array $prepared_args Array of arguments to be - * passed to get_terms. - * @param \WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( "woocommerce_rest_{$taxonomy}_query", $prepared_args, $request ); - - if ( ! empty( $prepared_args['product'] ) ) { - $query_result = $this->get_terms_for_product( $prepared_args, $request ); - $total_terms = $this->total_terms; - } else { - $query_result = get_terms( $taxonomy, $prepared_args ); - - $count_args = $prepared_args; - unset( $count_args['number'] ); - unset( $count_args['offset'] ); - $total_terms = wp_count_terms( $taxonomy, $count_args ); - - // Ensure we don't return results when offset is out of bounds. - // See https://core.trac.wordpress.org/ticket/35935. - if ( $prepared_args['offset'] && $prepared_args['offset'] >= $total_terms ) { - $query_result = array(); - } - - // wp_count_terms can return a falsy value when the term has no children. - if ( ! $total_terms ) { - $total_terms = 0; - } - } - $response = array(); - foreach ( $query_result as $term ) { - $data = $this->prepare_item_for_response( $term, $request ); - $response[] = $this->prepare_response_for_collection( $data ); - } - - // Store pagination values for headers then unset for count query. - $per_page = (int) $prepared_args['number']; - $max_pages = ceil( $total_terms / $per_page ); - - $response = rest_ensure_response( $response ); - $response = Pagination::add_pagination_headers( $response, $request, $total_terms, $max_pages ); - - return $response; - } - - /** - * Create a single term for a taxonomy. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function create_item( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $name = $request['name']; - $args = array(); - $schema = $this->get_item_schema(); - - if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { - $args['description'] = $request['description']; - } - if ( isset( $request['slug'] ) ) { - $args['slug'] = $request['slug']; - } - if ( isset( $request['parent'] ) ) { - if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new \WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - $args['parent'] = $request['parent']; - } - - $term = wp_insert_term( $name, $taxonomy, $args ); - if ( is_wp_error( $term ) ) { - $error_data = array( 'status' => 400 ); - - // If we're going to inform the client that the term exists, - // give them the identifier they can actually use. - $term_id = $term->get_error_data( 'term_exists' ); - if ( $term_id ) { - $error_data['resource_id'] = $term_id; - } - - return new \WP_Error( $term->get_error_code(), $term->get_error_message(), $error_data ); - } - - $term = get_term( $term['term_id'], $taxonomy ); - - $this->update_additional_fields_for_object( $term, $request ); - - // Add term data. - $meta_fields = $this->update_term_meta_fields( $term, $request ); - if ( is_wp_error( $meta_fields ) ) { - wp_delete_term( $term->term_id, $taxonomy ); - - return $meta_fields; - } - - /** - * Fires after a single term is created or updated via the REST API. - * - * @param WP_Term $term Inserted Term object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating term, false when updating. - */ - do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $term, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - - $base = '/' . $this->namespace . '/' . $this->rest_base; - if ( ! empty( $request['attribute_id'] ) ) { - $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); - } - - $response->header( 'Location', rest_url( $base . '/' . $term->term_id ) ); - - return $response; - } - - /** - * Get a single term from a taxonomy. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function get_item( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $term = get_term( (int) $request['id'], $taxonomy ); - - if ( is_wp_error( $term ) ) { - return $term; - } - - $response = $this->prepare_item_for_response( $term, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Update a single term from a taxonomy. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function update_item( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $term = get_term( (int) $request['id'], $taxonomy ); - $schema = $this->get_item_schema(); - $prepared_args = array(); - - if ( isset( $request['name'] ) ) { - $prepared_args['name'] = $request['name']; - } - if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { - $prepared_args['description'] = $request['description']; - } - if ( isset( $request['slug'] ) ) { - $prepared_args['slug'] = $request['slug']; - } - if ( isset( $request['parent'] ) ) { - if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new \WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - $prepared_args['parent'] = $request['parent']; - } - - // Only update the term if we haz something to update. - if ( ! empty( $prepared_args ) ) { - $update = wp_update_term( $term->term_id, $term->taxonomy, $prepared_args ); - if ( is_wp_error( $update ) ) { - return $update; - } - } - - $term = get_term( (int) $request['id'], $taxonomy ); - - $this->update_additional_fields_for_object( $term, $request ); - - // Update term data. - $meta_fields = $this->update_term_meta_fields( $term, $request ); - if ( is_wp_error( $meta_fields ) ) { - return $meta_fields; - } - - /** - * Fires after a single term is created or updated via the REST API. - * - * @param WP_Term $term Inserted Term object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating term, false when updating. - */ - do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $term, $request ); - return rest_ensure_response( $response ); - } - - /** - * Delete a single term from a taxonomy. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Response|\WP_Error - */ - public function delete_item( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $term = get_term( (int) $request['id'], $taxonomy ); - // Get default category id. - $default_category_id = absint( get_option( 'default_product_cat', 0 ) ); - - // Prevent deleting the default product category. - if ( $default_category_id === (int) $request['id'] ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $term, $request ); - - $retval = wp_delete_term( $term->term_id, $term->taxonomy ); - if ( ! $retval ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a single term is deleted via the REST API. - * - * @param WP_Term $term The deleted term. - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$taxonomy}", $term, $response, $request ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - - if ( ! empty( $request['attribute_id'] ) ) { - $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); - } - - $links = array( - 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $item->term_id ), - ), - 'collection' => array( - 'href' => rest_url( $base ), - ), - ); - - if ( $item->parent ) { - $parent_term = get_term( (int) $item->parent, $item->taxonomy ); - if ( $parent_term ) { - $links['up'] = array( - 'href' => rest_url( trailingslashit( $base ) . $parent_term->term_id ), - ); - } - } - - return $links; - } - - /** - * Update term meta fields. - * - * @param \WP_Term $term Term object. - * @param \WP_REST_Request $request Full details about the request. - * @return bool|\WP_Error - */ - protected function update_term_meta_fields( $term, $request ) { - return true; - } - - /** - * Get the terms attached to a product. - * - * This is an alternative to `get_terms()` that uses `get_the_terms()` - * instead, which hits the object cache. There are a few things not - * supported, notably `include`, `exclude`. In `self::get_items()` these - * are instead treated as a full query. - * - * @param array $prepared_args Arguments for `get_terms()`. - * @param \WP_REST_Request $request Full details about the request. - * @return array List of term objects. (Total count in `$this->total_terms`). - */ - protected function get_terms_for_product( $prepared_args, $request ) { - $taxonomy = $this->get_taxonomy( $request ); - - $query_result = get_the_terms( $prepared_args['product'], $taxonomy ); - if ( empty( $query_result ) ) { - $this->total_terms = 0; - return array(); - } - - // get_items() verifies that we don't have `include` set, and default. - // ordering is by `name`. - if ( ! in_array( $prepared_args['orderby'], array( 'name', 'none', 'include' ), true ) ) { - switch ( $prepared_args['orderby'] ) { - case 'id': - $this->sort_column = 'term_id'; - break; - case 'slug': - case 'term_group': - case 'description': - case 'count': - $this->sort_column = $prepared_args['orderby']; - break; - } - usort( $query_result, array( $this, 'compare_terms' ) ); - } - if ( strtolower( $prepared_args['order'] ) !== 'asc' ) { - $query_result = array_reverse( $query_result ); - } - - // Pagination. - $this->total_terms = count( $query_result ); - $query_result = array_slice( $query_result, $prepared_args['offset'], $prepared_args['number'] ); - - return $query_result; - } - - /** - * Comparison function for sorting terms by a column. - * - * Uses `$this->sort_column` to determine field to sort by. - * - * @param \stdClass $left Term object. - * @param \stdClass $right Term object. - * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left. - */ - protected function compare_terms( $left, $right ) { - $col = $this->sort_column; - $left_val = $left->$col; - $right_val = $right->$col; - - if ( is_int( $left_val ) && is_int( $right_val ) ) { - return $left_val - $right_val; - } - - return strcmp( $left_val, $right_val ); - } - - /** - * Get the query params for collections - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - if ( '' !== $this->taxonomy && taxonomy_exists( $this->taxonomy ) ) { - $taxonomy = get_taxonomy( $this->taxonomy ); - } else { - $taxonomy = new \stdClass(); - $taxonomy->hierarchical = true; - } - - $params['context']['default'] = 'view'; - - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - ); - if ( ! $taxonomy->hierarchical ) { - $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - } - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_key', - 'default' => 'asc', - 'enum' => array( - 'asc', - 'desc', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by resource attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_key', - 'default' => 'name', - 'enum' => array( - 'id', - 'include', - 'name', - 'slug', - 'term_group', - 'description', - 'count', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['hide_empty'] = array( - 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'validate_callback' => 'rest_validate_request_arg', - ); - if ( $taxonomy->hierarchical ) { - $params['parent'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - } - $params['product'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => null, - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['slug'] = array( - 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - - /** - * Get taxonomy. - * - * @param \WP_REST_Request $request Full details about the request. - * @return string - */ - protected function get_taxonomy( $request ) { - // Check if taxonomy is defined. - // Prevents check for attribute taxonomy more than one time for each query. - if ( '' !== $this->taxonomy ) { - return $this->taxonomy; - } - - if ( ! empty( $request['attribute_id'] ) ) { - $taxonomy = wc_attribute_taxonomy_name_by_id( (int) $request['attribute_id'] ); - - $this->taxonomy = $taxonomy; - } - - return $this->taxonomy; - } - - /** - * Return suffix for item action hooks. - * - * @return string - */ - protected function get_hook_suffix() { - return $this->taxonomy; - } -} diff --git a/src/Controllers/Version4/Coupons.php b/src/Controllers/Version4/Coupons.php deleted file mode 100644 index 10dff13fc62..00000000000 --- a/src/Controllers/Version4/Coupons.php +++ /dev/null @@ -1,465 +0,0 @@ -get_data(); - - $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); - $format_date = array( 'date_created', 'date_modified', 'date_expires' ); - $format_null = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], 2 ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $datetime = $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - // Format null values. - foreach ( $format_null as $key ) { - $data[ $key ] = $data[ $key ] ? $data[ $key ] : null; - } - - return array( - 'id' => $object->get_id(), - 'code' => $data['code'], - 'amount' => $data['amount'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'discount_type' => $data['discount_type'], - 'description' => $data['description'], - 'date_expires' => $data['date_expires'], - 'date_expires_gmt' => $data['date_expires_gmt'], - 'usage_count' => $data['usage_count'], - 'individual_use' => $data['individual_use'], - 'product_ids' => $data['product_ids'], - 'excluded_product_ids' => $data['excluded_product_ids'], - 'usage_limit' => $data['usage_limit'], - 'usage_limit_per_user' => $data['usage_limit_per_user'], - 'limit_usage_to_x_items' => $data['limit_usage_to_x_items'], - 'free_shipping' => $data['free_shipping'], - 'product_categories' => $data['product_categories'], - 'excluded_product_categories' => $data['excluded_product_categories'], - 'exclude_sale_items' => $data['exclude_sale_items'], - 'minimum_amount' => $data['minimum_amount'], - 'maximum_amount' => $data['maximum_amount'], - 'email_restrictions' => $data['email_restrictions'], - 'used_by' => $data['used_by'], - 'meta_data' => $data['meta_data'], - ); - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - if ( ! empty( $request['code'] ) ) { - $id = wc_get_coupon_id_by_code( $request['code'] ); - $args['post__in'] = array( $id ); - } - - if ( ! empty( $request['search'] ) ) { - $args['search'] = $request['search']; - $args['s'] = false; - } - - return $args; - } - - /** - * Prepare a single coupon for create or update. - * - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WP_Error|\WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $coupon = new \WC_Coupon( $id ); - $schema = $this->get_item_schema(); - $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - - // Validate required POST fields. - if ( $creating && empty( $request['code'] ) ) { - return new \WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce-rest-api' ), 'code' ), array( 'status' => 400 ) ); - } - - // Handle all writable props. - foreach ( $data_keys as $key ) { - $value = $request[ $key ]; - - if ( ! is_null( $value ) ) { - switch ( $key ) { - case 'code': - $coupon_code = wc_format_coupon_code( $value ); - $id = $coupon->get_id() ? $coupon->get_id() : 0; - $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); - - if ( $id_from_code ) { - return new \WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $coupon->set_code( $coupon_code ); - break; - case 'meta_data': - if ( is_array( $value ) ) { - foreach ( $value as $meta ) { - $coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : 0 ); - } - } - break; - case 'description': - $coupon->set_description( wp_filter_post_kses( $value ) ); - break; - default: - if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { - $coupon->{"set_{$key}"}( $value ); - } - break; - } - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param \WC_Data $coupon Object object. - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $coupon, $request, $creating ); - } - - /** - * Get the Coupon's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the object.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'required' => true, - ), - 'amount' => array( - 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'discount_type' => array( - 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'fixed_cart', - 'enum' => array_keys( wc_get_coupon_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Coupon description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_expires' => array( - 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_expires_gmt' => array( - 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'usage_count' => array( - 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'individual_use' => array( - 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'product_ids' => array( - 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'excluded_product_ids' => array( - 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'usage_limit' => array( - 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'usage_limit_per_user' => array( - 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'limit_usage_to_x_items' => array( - 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'free_shipping' => array( - 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'product_categories' => array( - 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'excluded_product_categories' => array( - 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'exclude_sale_items' => array( - 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'minimum_amount' => array( - 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'maximum_amount' => array( - 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email_restrictions' => array( - 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - 'context' => array( 'view', 'edit' ), - ), - 'used_by' => array( - 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['code'] = array( - 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['search'] = array( - 'description' => __( 'Limit results to coupons with codes matching a given string.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - - /** - * Only return writable props from schema. - * - * @param array $schema Schema array. - * @return bool - */ - protected function filter_writable_props( $schema ) { - return empty( $schema['readonly'] ); - } - - /** - * Get a collection of posts and add the code search option to \WP_Query. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - add_filter( 'posts_where', array( $this, 'add_wp_query_search_code_filter' ), 10, 2 ); - $response = parent::get_items( $request ); - remove_filter( 'posts_where', array( $this, 'add_wp_query_search_code_filter' ), 10 ); - return $response; - } - - /** - * Add code searching to the WP Query - * - * @param string $where Where clause used to search posts. - * @param object $wp_query \WP_Query object. - * @return string - */ - public function add_wp_query_search_code_filter( $where, $wp_query ) { - global $wpdb; - - $search = $wp_query->get( 'search' ); - if ( $search ) { - $search = $wpdb->esc_like( $search ); - $search = "'%" . $search . "%'"; - $where .= ' AND ' . $wpdb->posts . '.post_title LIKE ' . $search; - } - - return $where; - } -} diff --git a/src/Controllers/Version4/CustomerDownloads.php b/src/Controllers/Version4/CustomerDownloads.php deleted file mode 100644 index c63fe2b875b..00000000000 --- a/src/Controllers/Version4/CustomerDownloads.php +++ /dev/null @@ -1,235 +0,0 @@ -/downloads endpoint. - * - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; - -/** - * REST API Customer Downloads controller class. - */ -class CustomerDownloads extends AbstractController { - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'customers/(?P[\d]+)/downloads'; - - /** - * Permission to check. - * - * @var string - */ - protected $resource_type = 'customers'; - - /** - * Register the routes for customers. - */ - public function register_routes() { - $this->register_items_route( [ 'read' ] ); - } - - /** - * Check whether a given request has permission to read customers. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - $customer = get_user_by( 'id', (int) $request['customer_id'] ); - - if ( ! $customer ) { - return new \WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! Permissions::user_can_read( $this->resource_type, $customer->ID ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all customer downloads. - * - * @param \WP_REST_Request $request Request params. - * @return array - */ - public function get_items( $request ) { - $downloads = wc_get_customer_available_downloads( (int) $request['customer_id'] ); - - $data = array(); - foreach ( $downloads as $download_data ) { - $download = $this->prepare_item_for_response( (object) $download_data, $request ); - $download = $this->prepare_response_for_collection( $download ); - $data[] = $download; - } - - return rest_ensure_response( $data ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param object $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return array( - 'download_id' => $object->download_id, - 'download_url' => $object->download_url, - 'product_id' => $object->product_id, - 'product_name' => $object->product_name, - 'download_name' => $object->download_name, - 'order_id' => $object->order_id, - 'order_key' => $object->order_key, - 'downloads_remaining' => '' === $object->downloads_remaining ? 'unlimited' : $object->downloads_remaining, - 'access_expires' => $object->access_expires ? wc_rest_prepare_date_response( $object->access_expires ) : 'never', - 'access_expires_gmt' => $object->access_expires ? wc_rest_prepare_date_response( get_gmt_from_date( $object->access_expires ) ) : 'never', - 'file' => $object->file, - ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = str_replace( '(?P[\d]+)', $request['customer_id'], $this->rest_base ); - $links = array( - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'product' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $item->product_id ) ), - ), - 'order' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $item->order_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Customer Download's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'customer_download', - 'type' => 'object', - 'properties' => array( - 'download_id' => array( - 'description' => __( 'Download ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'download_url' => array( - 'description' => __( 'Download file URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Downloadable product ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'product_name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'download_name' => array( - 'description' => __( 'Downloadable file name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'downloads_remaining' => array( - 'description' => __( 'Number of downloads remaining.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'access_expires' => array( - 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'access_expires_gmt' => array( - 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'file' => array( - 'description' => __( 'File details.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version4/Customers.php b/src/Controllers/Version4/Customers.php deleted file mode 100644 index 38688b23f0e..00000000000 --- a/src/Controllers/Version4/Customers.php +++ /dev/null @@ -1,792 +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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'email' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'New user email address.', 'woocommerce-rest-api' ), - ), - 'username' => array( - 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), - 'description' => __( 'New user username.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - 'password' => array( - 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), - 'description' => __( 'New user password.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - 'reassign' => array( - 'default' => 0, - 'type' => 'integer', - 'description' => __( 'ID to reassign posts to.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - $this->register_batch_route(); - } - - /** - * Get all customers. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $prepared_args = array( - 'exclude' => $request['exclude'], - 'include' => $request['include'], - 'order' => $request['order'], - 'number' => $request['per_page'], - ); - - if ( ! empty( $request['offset'] ) ) { - $prepared_args['offset'] = $request['offset']; - } else { - $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; - } - - $orderby_possibles = array( - 'id' => 'ID', - 'include' => 'include', - 'name' => 'display_name', - 'registered_date' => 'registered', - ); - $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; - $prepared_args['search'] = $request['search']; - - if ( '' !== $prepared_args['search'] ) { - $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; - } - - // Filter by email. - if ( ! empty( $request['email'] ) ) { - $prepared_args['search'] = $request['email']; - $prepared_args['search_columns'] = array( 'user_email' ); - } - - // Filter by role. - if ( 'all' !== $request['role'] ) { - $prepared_args['role'] = $request['role']; - } - - /** - * Filter arguments, before passing to \ WP_User_Query, when querying users via the REST API. - * - * @see https://developer.wordpress.org/reference/classes/\ WP_User_Query/ - * - * @param array $prepared_args Array of arguments for \ WP_User_Query. - * @param \WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_customer_query', $prepared_args, $request ); - - $query = new \WP_User_Query( $prepared_args ); - - $users = array(); - foreach ( $query->results as $user ) { - $customer = new \WC_Customer( $user->ID ); - $data = $this->prepare_item_for_response( $customer, $request ); - $users[] = $this->prepare_response_for_collection( $data ); - } - - // Store pagination values for headers then unset for count query. - $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); - - $prepared_args['fields'] = 'ID'; - - $total_users = $query->get_total(); - - if ( $total_users < 1 ) { - // Out-of-bounds, run the query again without LIMIT for total count. - unset( $prepared_args['number'] ); - unset( $prepared_args['offset'] ); - $count_query = new \ WP_User_Query( $prepared_args ); - $total_users = $count_query->get_total(); - } - - $response = rest_ensure_response( $users ); - $response = Pagination::add_pagination_headers( $response, $request, $total_users, ceil( $total_users / $per_page ) ); - - return $response; - } - - /** - * Create a single customer. - * - * @throws \WC_REST_Exception On invalid params. - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - try { - if ( ! empty( $request['id'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), 400 ); - } - - $customer_request = new CustomerRequest( $request ); - $customer = $customer_request->prepare_object(); - $customer->save(); - - if ( ! $customer->get_id() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce-rest-api' ), 400 ); - } - - $this->update_additional_fields_for_object( $customer, $request ); - - /** - * Fires after a customer is created or updated via the REST API. - * - * @param \WC_Customer $customer Customer object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating customer, false when updating customer. - */ - do_action( 'woocommerce_rest_insert_customer_object', $customer, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $customer, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ) ); - - return $response; - } catch ( \Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Get a single customer. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $customer = new \WC_Customer( $id ); - - if ( empty( $id ) || ! $customer->get_id() ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $response = $this->prepare_item_for_response( $customer, $request ); - $response = rest_ensure_response( $response ); - - return $response; - } - - /** - * Update a single user. - * - * @throws \WC_REST_Exception On invalid params. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function update_item( $request ) { - try { - $customer_request = new CustomerRequest( $request ); - $customer = $customer_request->prepare_object(); - $customer->save(); - - $this->update_additional_fields_for_object( $customer, $request ); - - if ( is_multisite() && ! is_user_member_of_blog( $customer->get_id() ) ) { - add_user_to_blog( get_current_blog_id(), $customer->get_id(), 'customer' ); - } - - /** - * Fires after a customer is created or updated via the REST API. - * - * @param \WC_Customer $customer Data used to create the customer. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating customer, false when updating customer. - */ - do_action( 'woocommerce_rest_insert_customer_object', $customer, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $customer, $request ); - $response = rest_ensure_response( $response ); - return $response; - } catch ( Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Delete a single customer. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $reassign = isset( $request['reassign'] ) ? absint( $request['reassign'] ) : null; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - if ( ! get_userdata( $id ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - if ( ! empty( $reassign ) ) { - if ( $reassign === $id || ! get_userdata( $reassign ) ) { - return new \WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - /** Include admin customer functions to get access to wp_delete_user() */ - require_once ABSPATH . 'wp-admin/includes/user.php'; - - $customer = new \WC_Customer( $id ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $customer, $request ); - - if ( ! is_null( $reassign ) ) { - $result = $customer->delete_and_reassign( $reassign ); - } else { - $result = $customer->delete(); - } - - if ( ! $result ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a customer is deleted via the REST API. - * - * @param \WC_Customer $customer User data. - * @param \WP_REST_Response $response The response returned from the API. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_customer_object', $customer, $response, $request ); - - return $response; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WC_Customer $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - $formatter = new CustomerResponse(); - - return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - return $links; - } - - /** - * Get the Customer's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'customer', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'role' => array( - 'description' => __( 'Customer role.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_user', - ), - ), - 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - ), - 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'is_paying_customer' => array( - 'description' => __( 'Is the customer a paying customer?', 'woocommerce-rest-api' ), - 'type' => 'bool', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get role names. - * - * @return array - */ - protected function get_role_names() { - global $wp_roles; - - return array_keys( $wp_roles->role_names ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['context']['default'] = 'view'; - - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'enum' => array( 'asc', 'desc' ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'default' => 'name', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'enum' => array( - 'id', - 'include', - 'name', - 'registered_date', - ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['email'] = array( - 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['role'] = array( - 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'customer', - 'enum' => array_merge( array( 'all' ), $this->get_role_names() ), - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } - - /** - * Check if a given ID is valid. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - protected function check_valid_customer_id( $request ) { - $id = $request->get_param( 'id' ); - $user = get_userdata( $id ); - - if ( false === $user ) { - return new \WP_Error( 'woocommerce_rest_customer_invalid_id', __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return true; - } - - /** - * Check if a given request has access to read a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $check_valid = $this->check_valid_customer_id( $request ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::get_item_permissions_check( $request ); - } - - /** - * Check if a given request has access to delete an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $check_valid = $this->check_valid_customer_id( $request ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::delete_item_permissions_check( $request ); - } - - /** - * Check if a given request has access to update an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $check_valid = $this->check_valid_customer_id( $request ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::update_item_permissions_check( $request ); - } -} diff --git a/src/Controllers/Version4/Data.php b/src/Controllers/Version4/Data.php deleted file mode 100644 index f8a322a47de..00000000000 --- a/src/Controllers/Version4/Data.php +++ /dev/null @@ -1,153 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Return the list of data resources. - * - * @since 3.5.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $data = array(); - $resources = array( - array( - 'slug' => 'continents', - 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce-rest-api' ), - ), - array( - 'slug' => 'countries', - 'description' => __( 'List of supported states in a given country.', 'woocommerce-rest-api' ), - ), - array( - 'slug' => 'currencies', - 'description' => __( 'List of supported currencies.', 'woocommerce-rest-api' ), - ), - array( - 'slug' => 'download-ips', - 'description' => __( 'An endpoint used for searching download logs for a specific IP address.', 'woocommerce-rest-api' ), - ), - ); - - foreach ( $resources as $resource ) { - $item = $this->prepare_item_for_response( (object) $resource, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - return rest_ensure_response( $data ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \stdClass $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return array( - 'slug' => $object->slug, - 'description' => $object->description, - ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->slug ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the data index schema, conforming to JSON Schema. - * - * @since 3.5.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_index', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'Data resource ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Data resource description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/Data/Continents.php b/src/Controllers/Version4/Data/Continents.php deleted file mode 100644 index c95b0b782bd..00000000000 --- a/src/Controllers/Version4/Data/Continents.php +++ /dev/null @@ -1,340 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\w-]+)', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => array( - 'continent' => array( - 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Return the list of countries and states for a given continent. - * - * @since 3.5.0 - * @param string $continent_code Continent code. - * @param \WP_REST_Request $request Request data. - * @return array|mixed Response data, ready for insertion into collection data. - */ - public function get_continent( $continent_code = false, $request ) { - $continents = WC()->countries->get_continents(); - $countries = WC()->countries->get_countries(); - $states = WC()->countries->get_states(); - $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php'; - $data = array(); - - if ( ! array_key_exists( $continent_code, $continents ) ) { - return false; - } - - $continent_list = $continents[ $continent_code ]; - - $continent = array( - 'code' => $continent_code, - 'name' => $continent_list['name'], - ); - - $local_countries = array(); - foreach ( $continent_list['countries'] as $country_code ) { - if ( isset( $countries[ $country_code ] ) ) { - $country = array( - 'code' => $country_code, - 'name' => $countries[ $country_code ], - ); - - // If we have detailed locale information include that in the response. - if ( array_key_exists( $country_code, $locale_info ) ) { - // Defensive programming against unexpected changes in locale-info.php. - $country_data = wp_parse_args( - $locale_info[ $country_code ], - array( - 'currency_code' => 'USD', - 'currency_pos' => 'left', - 'decimal_sep' => '.', - 'dimension_unit' => 'in', - 'num_decimals' => 2, - 'thousand_sep' => ',', - 'weight_unit' => 'lbs', - ) - ); - - $country = array_merge( $country, $country_data ); - } - - $local_states = array(); - if ( isset( $states[ $country_code ] ) ) { - foreach ( $states[ $country_code ] as $state_code => $state_name ) { - $local_states[] = array( - 'code' => $state_code, - 'name' => $state_name, - ); - } - } - $country['states'] = $local_states; - - // Allow only desired keys (e.g. filter out tax rates). - $allowed = array( - 'code', - 'currency_code', - 'currency_pos', - 'decimal_sep', - 'dimension_unit', - 'name', - 'num_decimals', - 'states', - 'thousand_sep', - 'weight_unit', - ); - $country = array_intersect_key( $country, array_flip( $allowed ) ); - - $local_countries[] = $country; - } - } - - $continent['countries'] = $local_countries; - return $continent; - } - - /** - * Return the list of states for all continents. - * - * @since 3.5.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $continents = WC()->countries->get_continents(); - $data = array(); - - foreach ( array_keys( $continents ) as $continent_code ) { - $continent = $this->get_continent( $continent_code, $request ); - $response = $this->prepare_item_for_response( $continent, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - - return rest_ensure_response( $data ); - } - - /** - * Return the list of locations for a given continent. - * - * @since 3.5.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $data = $this->get_continent( strtoupper( $request['location'] ), $request ); - if ( empty( $data ) ) { - return new \WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return $this->prepare_item_for_response( $data, $request ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param mixed $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return mixed Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return $object; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $continent_code = strtolower( $item['code'] ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $continent_code ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - return $links; - } - - /** - * Get the location schema, conforming to JSON Schema. - * - * @since 3.5.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'continent', - 'type' => 'object', - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of continent.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'countries' => array( - 'type' => 'array', - 'description' => __( 'List of countries on this continent.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency_code' => array( - 'type' => 'string', - 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency_pos' => array( - 'type' => 'string', - 'description' => __( 'Currency symbol position for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'decimal_sep' => array( - 'type' => 'string', - 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'dimension_unit' => array( - 'type' => 'string', - 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'num_decimals' => array( - 'type' => 'integer', - 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'states' => array( - 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - 'thousand_sep' => array( - 'type' => 'string', - 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'weight_unit' => array( - 'type' => 'string', - 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/Data/Countries.php b/src/Controllers/Version4/Data/Countries.php deleted file mode 100644 index cca85709109..00000000000 --- a/src/Controllers/Version4/Data/Countries.php +++ /dev/null @@ -1,222 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\w-]+)', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => array( - 'location' => array( - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get a list of countries and states. - * - * @param string $country_code Country code. - * @param \WP_REST_Request $request Request data. - * @return array|mixed Response data, ready for insertion into collection data. - */ - public function get_country( $country_code = false, $request ) { - $countries = WC()->countries->get_countries(); - $states = WC()->countries->get_states(); - $data = array(); - - if ( ! array_key_exists( $country_code, $countries ) ) { - return false; - } - - $country = array( - 'code' => $country_code, - 'name' => $countries[ $country_code ], - ); - - $local_states = array(); - if ( isset( $states[ $country_code ] ) ) { - foreach ( $states[ $country_code ] as $state_code => $state_name ) { - $local_states[] = array( - 'code' => $state_code, - 'name' => $state_name, - ); - } - } - $country['states'] = $local_states; - return $country; - } - - /** - * Return the list of states for all countries. - * - * @since 3.5.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $countries = WC()->countries->get_countries(); - $data = array(); - - foreach ( array_keys( $countries ) as $country_code ) { - $country = $this->get_country( $country_code, $request ); - $response = $this->prepare_item_for_response( $country, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - - return rest_ensure_response( $data ); - } - - /** - * Return the list of states for a given country. - * - * @since 3.5.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $data = $this->get_country( strtoupper( $request['location'] ), $request ); - if ( empty( $data ) ) { - return new \WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return $this->prepare_item_for_response( $data, $request ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param mixed $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return mixed Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return $object; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $country_code = strtolower( $item['code'] ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $country_code ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - - /** - * Get the location schema, conforming to JSON Schema. - * - * @since 3.5.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'country', - 'type' => 'object', - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'states' => array( - 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/Data/Currencies.php b/src/Controllers/Version4/Data/Currencies.php deleted file mode 100644 index cb87d6d242c..00000000000 --- a/src/Controllers/Version4/Data/Currencies.php +++ /dev/null @@ -1,209 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/current', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_current_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\w-]{3})', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'location' => array( - 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get currency information. - * - * @param string $code Currency code. - * @param \WP_REST_Request $request Request data. - * @return array|mixed Response data, ready for insertion into collection data. - */ - public function get_currency( $code = false, $request ) { - $currencies = get_woocommerce_currencies(); - $data = array(); - - if ( ! array_key_exists( $code, $currencies ) ) { - return false; - } - - $currency = array( - 'code' => $code, - 'name' => $currencies[ $code ], - 'symbol' => get_woocommerce_currency_symbol( $code ), - ); - - return $currency; - } - - /** - * Return the list of currencies. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $currencies = get_woocommerce_currencies(); - foreach ( array_keys( $currencies ) as $code ) { - $currency = $this->get_currency( $code, $request ); - $response = $this->prepare_item_for_response( $currency, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - - return rest_ensure_response( $data ); - } - - /** - * Return information for a specific currency. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); - if ( empty( $data ) ) { - return new \WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return $this->prepare_item_for_response( $data, $request ); - } - - /** - * Return information for the current site currency. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_current_item( $request ) { - $currency = get_option( 'woocommerce_currency' ); - return $this->prepare_item_for_response( $this->get_currency( $currency, $request ), $request ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param mixed $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return mixed Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return $object; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $code = strtoupper( $item['code'] ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $code ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - - /** - * Get the currency schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'currency', - 'type' => 'object', - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of currency.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'symbol' => array( - 'type' => 'string', - 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/Data/DownloadIPs.php b/src/Controllers/Version4/Data/DownloadIPs.php deleted file mode 100644 index 14a47ff7f85..00000000000 --- a/src/Controllers/Version4/Data/DownloadIPs.php +++ /dev/null @@ -1,149 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Return the download IPs matching the passed parameters. - * - * @since 3.5.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - global $wpdb; - - if ( isset( $request['match'] ) ) { - $downloads = $wpdb->get_results( - $wpdb->prepare( - "SELECT DISTINCT( user_ip_address ) FROM {$wpdb->prefix}wc_download_log - WHERE user_ip_address LIKE %s - LIMIT 10", - $request['match'] . '%' - ) - ); - } else { - return new \WP_Error( 'woocommerce_rest_data_download_ips_invalid_request', __( 'Invalid request. Please pass the match parameter.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $data = array(); - - if ( ! empty( $downloads ) ) { - foreach ( $downloads as $download ) { - $response = $this->prepare_item_for_response( (array) $download, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - } - - return rest_ensure_response( $data ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param mixed $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return mixed Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return $object; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - return $links; - } - - /** - * 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['match'] = array( - 'description' => __( 'A partial IP address can be passed and matching results will be returned.', 'woocommerce-rest-api' ), - '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' => 'download_ip', - 'type' => 'object', - 'properties' => array( - 'user_ip_address' => array( - 'type' => 'string', - 'description' => __( 'IP address.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/NetworkOrders.php b/src/Controllers/Version4/NetworkOrders.php deleted file mode 100644 index a721b5cd5a0..00000000000 --- a/src/Controllers/Version4/NetworkOrders.php +++ /dev/null @@ -1,166 +0,0 @@ -namespace, - '/' . $this->rest_base . '/network', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'network_orders' ), - 'permission_callback' => array( $this, 'network_orders_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - } - - /** - * Retrieves the item's schema for display / public consumption purposes. - * - * @return array Public item schema data. - */ - public function get_public_item_schema() { - $schema = parent::get_public_item_schema(); - - $schema['properties']['blog'] = array( - 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ); - $schema['properties']['edit_url'] = array( - 'description' => __( 'URL to edit the order', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ); - $schema['properties']['customer'][] = array( - 'description' => __( 'Name of the customer for the order', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ); - $schema['properties']['status_name'][] = array( - 'description' => __( 'Order Status', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ); - $schema['properties']['formatted_total'][] = array( - 'description' => __( 'Order total formatted for locale', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ); - - return $schema; - } - - /** - * Does a permissions check for the proper requested blog - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool $permission - */ - public function network_orders_permissions_check( $request ) { - $blog_id = $request->get_param( 'blog_id' ); - $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); - - switch_to_blog( $blog_id ); - - $permission = $this->get_items_permissions_check( $request ); - - restore_current_blog(); - - return $permission; - } - - /** - * Get a collection of orders from the requested blog id - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return \WP_REST_Response - */ - public function network_orders( $request ) { - $blog_id = $request->get_param( 'blog_id' ); - $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); - $active_plugins = get_blog_option( $blog_id, 'active_plugins', array() ); - $network_active_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); - - $plugins = array_merge( $active_plugins, $network_active_plugins ); - $wc_active = false; - foreach ( $plugins as $plugin ) { - if ( substr_compare( $plugin, '/woocommerce.php', strlen( $plugin ) - strlen( '/woocommerce.php' ), strlen( '/woocommerce.php' ) ) === 0 ) { - $wc_active = true; - } - } - - // If WooCommerce not active for site, return an empty response. - if ( ! $wc_active ) { - $response = rest_ensure_response( array() ); - return $response; - } - - switch_to_blog( $blog_id ); - add_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); - $items = $this->get_items( $request ); - remove_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); - - foreach ( $items->data as &$current_order ) { - $order = wc_get_order( $current_order['id'] ); - - $current_order['blog'] = get_blog_details( get_current_blog_id() ); - $current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' ); - /* translators: 1: first name 2: last name */ - $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce-rest-api' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); - $current_order['status_name'] = wc_get_order_status_name( $order->get_status() ); - $current_order['formatted_total'] = $order->get_formatted_order_total(); - } - - restore_current_blog(); - - return $items; - } - - /** - * Filters the post statuses to on hold and processing for the network order query. - * - * @param array $args Query args. - * - * @return array - */ - public function network_orders_filter_args( $args ) { - $args['post_status'] = array( - 'wc-on-hold', - 'wc-processing', - ); - - return $args; - } -} diff --git a/src/Controllers/Version4/OrderNotes.php b/src/Controllers/Version4/OrderNotes.php deleted file mode 100644 index 3174a419420..00000000000 --- a/src/Controllers/Version4/OrderNotes.php +++ /dev/null @@ -1,449 +0,0 @@ -/notes endpoint. - * - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; - -/** - * REST API Order Notes controller class. - */ -class OrderNotes extends AbstractController { - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'orders/(?P[\d]+)/notes'; - - /** - * Post type. - * - * @var string - */ - protected $post_type = 'shop_order'; - - /** - * Register the routes for order notes. - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'note' => array( - 'type' => 'string', - 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), - 'required' => true, - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Check if a given request has access to read a order note. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( $order && ! Permissions::user_can_read( $this->post_type, $order->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a order note. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error - */ - public function delete_item_permissions_check( $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( $order && ! Permissions::user_can_delete( $this->post_type, $order->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get order notes from an order. - * - * @param \WP_REST_Request $request Request data. - * - * @return array|\WP_Error - */ - public function get_items( $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $args = array( - 'post_id' => $order->get_id(), - 'approve' => 'approve', - 'type' => 'order_note', - ); - - // Allow filter by order note type. - if ( 'customer' === $request['type'] ) { - $args['meta_query'] = array( // WPCS: slow query ok. - array( - 'key' => 'is_customer_note', - 'value' => 1, - 'compare' => '=', - ), - ); - } elseif ( 'internal' === $request['type'] ) { - $args['meta_query'] = array( // WPCS: slow query ok. - array( - 'key' => 'is_customer_note', - 'compare' => 'NOT EXISTS', - ), - ); - } - - remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10 ); - - $notes = get_comments( $args ); - - add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); - - $data = array(); - foreach ( $notes as $note ) { - $order_note = $this->prepare_item_for_response( $note, $request ); - $order_note = $this->prepare_response_for_collection( $order_note ); - $data[] = $order_note; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a single order note. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - // Create the note. - $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); - - if ( ! $note_id ) { - return new \WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $note = get_comment( $note_id ); - $this->update_additional_fields_for_object( $note, $request ); - - /** - * Fires after a order note is created or updated via the REST API. - * - * @param \WP_Comment $note New order note object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $note, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); - - return $response; - } - - /** - * Get a single order note. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $note = get_comment( $id ); - - if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $order_note = $this->prepare_item_for_response( $note, $request ); - $response = rest_ensure_response( $order_note ); - - return $response; - } - - /** - * Delete a single order note. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Response|\WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new \WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $note = get_comment( $id ); - - if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $request->set_param( 'context', 'edit' ); - $previous = $this->prepare_item_for_response( $note, $request ); - $result = wc_delete_order_note( $note->comment_ID ); - - if ( ! $result ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), 'order_note' ), array( 'status' => 500 ) ); - } - - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - - /** - * Fires after a order note is deleted or trashed via the REST API. - * - * @param \WP_Comment $note The deleted or trashed order note. - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_order_note', $note, $response, $request ); - - return $response; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WP_Comment $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return array( - 'id' => (int) $object->comment_ID, - 'author' => __( 'woocommerce', 'woocommerce-rest-api' ) === $object->comment_author ? 'system' : $object->comment_author, - 'date_created' => wc_rest_prepare_date_response( $object->comment_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->comment_date_gmt ), - 'note' => $object->comment_content, - 'customer_note' => (bool) get_comment_meta( $object->comment_ID, 'is_customer_note', true ), - ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $order_id = (int) $item->comment_post_ID; - $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $item->comment_ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Order Notes schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'order_note', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'author' => array( - 'description' => __( 'Order note author.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'note' => array( - 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'customer_note' => array( - 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'added_by_user' => array( - 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'edit' ), - ), - ), - ); - - 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['type'] = array( - 'default' => 'any', - 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array( 'any', 'customer', 'internal' ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/OrderRefunds.php b/src/Controllers/Version4/OrderRefunds.php deleted file mode 100644 index 1f27254ef2c..00000000000 --- a/src/Controllers/Version4/OrderRefunds.php +++ /dev/null @@ -1,665 +0,0 @@ -/refunds endpoint. - * - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Order Refunds controller class. - */ -class OrderRefunds extends Orders { - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'orders/(?P[\d]+)/refunds'; - - /** - * Post type. - * - * @var string - */ - protected $post_type = 'shop_order_refund'; - - /** - * Order refunds actions. - */ - public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_object_trashable", '__return_false' ); - } - - /** - * Register the routes for order refunds. - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => true, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Get object. - * - * @since 3.0.0 - * @param int $id Object ID. - * @return \WC_Data|bool - */ - protected function get_object( $id ) { - return wc_get_order( $id ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @throws \WC_REST_Exception Exception on invalid data. - * - * @param mixed $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); - } - - if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce-rest-api' ), 404 ); - } - - $data = $object->get_data(); - $format_decimal = array( 'amount' ); - $format_date = array( 'date_created' ); - $format_line_items = array( 'line_items' ); - $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $dp ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $datetime = $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - // Format line items. - foreach ( $format_line_items as $key ) { - $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ], $request ) ); - } - - return array( - 'id' => $object->get_id(), - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'amount' => $data['amount'], - 'reason' => $data['reason'], - 'refunded_by' => $data['refunded_by'], - 'refunded_payment' => $data['refunded_payment'], - 'meta_data' => $data['meta_data'], - 'line_items' => $data['line_items'], - ); - } - - /** - * Expands an order item to get its data. - * - * @param \WC_Order_item $item Order item data. - * @param \WP_REST_Response $response The response object. - * @return array - */ - protected function get_order_item_data( $item, $request ) { - $data = $item->get_data(); - $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); - $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - if ( isset( $data[ $key ] ) ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); - } - } - - // Add SKU and PRICE to products. - if ( is_callable( array( $item, 'get_product' ) ) ) { - $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; - $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; - } - - // Format taxes. - if ( ! empty( $data['taxes']['total'] ) ) { - $taxes = array(); - - foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { - $taxes[] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', - ); - } - $data['taxes'] = $taxes; - } elseif ( isset( $data['taxes'] ) ) { - $data['taxes'] = array(); - } - - // Remove names for coupons, taxes and shipping. - if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { - unset( $data['name'] ); - } - - // Remove props we don't want to expose. - unset( $data['order_id'] ); - unset( $data['type'] ); - - return $data; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = str_replace( '(?P[\d]+)', $item->get_parent_id(), $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $item->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $item->get_parent_id() ) ), - ), - ); - - return $links; - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - $args['post_status'] = array_keys( wc_get_order_statuses() ); - $args['post_parent__in'] = array( absint( $request['order_id'] ) ); - - return $args; - } - - /** - * Create a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $order_data = get_post( (int) $request['order_id'] ); - - if ( empty( $order_data ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce-rest-api' ), 400 ); - } - - if ( 0 > $request['amount'] ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); - } - - // Create the refund. - $refund = wc_create_refund( - array( - 'order_id' => $order_data->ID, - 'amount' => $request['amount'], - 'reason' => empty( $request['reason'] ) ? null : $request['reason'], - 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, - 'restock_items' => true, - ) - ); - - if ( is_wp_error( $refund ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); - } - - if ( ! $refund ) { - return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); - } - - $post = get_post( $refund->get_id() ); - $this->update_additional_fields_for_object( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param \WP_Post $post Post object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); - - return $response; - } - - /** - * Prepares one object for create or update operation. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WP_Error|\WC_Data The prepared item, or \WP_Error object on failure. - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); - } - - if ( 0 > $request['amount'] ) { - return new \WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); - } - - // Create the refund. - $refund = wc_create_refund( - array( - 'order_id' => $order->get_id(), - 'amount' => $request['amount'], - 'reason' => empty( $request['reason'] ) ? null : $request['reason'], - 'line_items' => empty( $request['line_items'] ) ? array() : $request['line_items'], - 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, - 'restock_items' => true, - ) - ); - - if ( is_wp_error( $refund ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); - } - - if ( ! $refund ) { - return new \WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); - } - - if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - $refund->save_meta_data(); - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param \WC_Data $coupon Object object. - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); - } - - /** - * Save an object data. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. - * @return \WC_Data|\WP_Error - */ - protected function save_object( $request, $creating = false ) { - try { - $object = $this->prepare_object_for_database( $request, $creating ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - return $this->get_object( $object->get_id() ); - } catch ( \WC_Data_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( \WC_REST_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Get the Order's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'amount' => array( - 'description' => __( 'Refund amount.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'reason' => array( - 'description' => __( 'Reason for refund.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'refunded_by' => array( - 'description' => __( 'User ID of user who created the refund.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'refunded_payment' => array( - 'description' => __( 'If the payment was refunded via the API.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'api_refund' => array( - 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'edit' ), - 'default' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['dp'] = array( - 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - - unset( $params['status'], $params['customer'], $params['product'] ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Orders.php b/src/Controllers/Version4/Orders.php deleted file mode 100644 index 25923a1c9b4..00000000000 --- a/src/Controllers/Version4/Orders.php +++ /dev/null @@ -1,1185 +0,0 @@ -get_type() ) { - return false; - } - - return $order; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WC_Order $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - $formatter = new OrderResponse(); - - if ( ! is_null( $request['dp'] ) ) { - $formatter->set_dp( $request['dp'] ); - } - - return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - if ( 0 !== (int) $item->get_customer_id() ) { - $links['customer'] = array( - 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $item->get_customer_id() ) ), - ); - } - - if ( 0 !== (int) $item->get_parent_id() ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $item->get_parent_id() ) ), - ); - } - - return $links; - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - global $wpdb; - - // This is needed to get around an array to string notice in \WC_REST_Orders_V2_Controller::prepare_objects_query. - $statuses = $request['status']; - unset( $request['status'] ); - $args = parent::prepare_objects_query( $request ); - - $args['post_status'] = array(); - foreach ( $statuses as $status ) { - if ( in_array( $status, $this->get_order_statuses(), true ) ) { - $args['post_status'][] = 'wc-' . $status; - } elseif ( 'any' === $status ) { - // Set status to "any" and short-circuit out. - $args['post_status'] = 'any'; - break; - } else { - $args['post_status'][] = $status; - } - } - - // Put the statuses back for further processing (next/prev links, etc). - $request['status'] = $statuses; - - // Customer. - if ( isset( $request['customer'] ) ) { - if ( ! empty( $args['meta_query'] ) ) { - $args['meta_query'] = array(); // WPCS: slow query ok. - } - - $args['meta_query'][] = array( - 'key' => '_customer_user', - 'value' => $request['customer'], - 'type' => 'NUMERIC', - ); - } - - // Search by product. - if ( ! empty( $request['product'] ) ) { - $order_ids = $wpdb->get_col( - $wpdb->prepare( - "SELECT order_id - FROM {$wpdb->prefix}woocommerce_order_items - WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) - AND order_item_type = 'line_item'", - $request['product'] - ) - ); - - // Force WP_Query return empty if don't found any order. - $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); - - $args['post__in'] = $order_ids; - } - - // Search. - if ( ! empty( $args['s'] ) ) { - $order_ids = wc_order_search( $args['s'] ); - - if ( ! empty( $order_ids ) ) { - unset( $args['s'] ); - $args['post__in'] = array_merge( $order_ids, array( 0 ) ); - } - } - - // Search by partial order number. - if ( ! empty( $request['number'] ) ) { - $partial_number = trim( $request['number'] ); - $limit = intval( $args['posts_per_page'] ); - $order_ids = $wpdb->get_col( - $wpdb->prepare( - "SELECT ID - FROM {$wpdb->prefix}posts - WHERE post_type = 'shop_order' - AND ID LIKE %s - LIMIT %d", - $wpdb->esc_like( absint( $partial_number ) ) . '%', - $limit - ) - ); - - // Force \WP_Query return empty if don't found any order. - $order_ids = empty( $order_ids ) ? array( 0 ) : $order_ids; - $args['post__in'] = $order_ids; - } - - return $args; - } - - /** - * Prepare a single order for create or update. - * - * @throws \WC_REST_Exception When fails to set any item. - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WP_Error|\WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - try { - $order_request = new OrderRequest( $request ); - $order = $order_request->prepare_object(); - } catch ( \WC_REST_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param \WC_Data $order Object object. - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); - } - - /** - * Save an object data. - * - * @param \WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. - * @return \WC_Data|\WP_Error - * @throws \WC_REST_Exception But all errors are validated before returning any data. - */ - protected function save_object( $request, $creating = false ) { - try { - $object = $this->prepare_object_for_database( $request, $creating ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - // Make sure gateways are loaded so hooks from gateways fire on save/create. - WC()->payment_gateways(); - - if ( $creating ) { - $object->set_created_via( 'rest-api' ); - $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); - $object->calculate_totals(); - } else { - // If items have changed, recalculate order totals. - if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { - $object->calculate_totals( true ); - } - } - - $object->save(); - - // Actions for after the order is saved. - if ( true === $request['set_paid'] && ( $creating || $object->needs_payment() ) ) { - $object->payment_complete(); - } - - return $this->get_object( $object->get_id() ); - } catch ( \WC_Data_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( \WC_REST_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Get order statuses without prefixes. - * - * @return array - */ - protected function get_order_statuses() { - $order_statuses = array(); - - foreach ( array_keys( wc_get_order_statuses() ) as $status ) { - $order_statuses[] = str_replace( 'wc-', '', $status ); - } - - return $order_statuses; - } - - /** - * Get the Order's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'parent_id' => array( - 'description' => __( 'Parent order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'number' => array( - 'description' => __( 'Order number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Order status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'pending', - 'enum' => $this->get_order_statuses(), - 'context' => array( 'view', 'edit' ), - ), - 'currency' => array( - 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => get_woocommerce_currency(), - 'enum' => array_keys( get_woocommerce_currencies() ), - 'context' => array( 'view', 'edit' ), - ), - 'currency_symbol' => array( - 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the order was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'discount_total' => array( - 'description' => __( 'Total discount amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'discount_tax' => array( - 'description' => __( 'Total discount tax amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_total' => array( - 'description' => __( 'Total shipping amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_tax' => array( - 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'cart_tax' => array( - 'description' => __( 'Sum of line item taxes only.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Grand total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Sum of all taxes.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => 0, - 'context' => array( 'view', 'edit' ), - ), - 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'billing' => array( - 'description' => __( 'Billing address.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping' => array( - 'description' => __( 'Shipping address.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'payment_method' => array( - 'description' => __( 'Payment method ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'payment_method_title' => array( - 'description' => __( 'Payment method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'transaction_id' => array( - 'description' => __( 'Unique transaction ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_paid' => array( - 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_paid_gmt' => array( - 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_completed_gmt' => array( - 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'cart_hash' => array( - 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'tax_lines' => array( - 'description' => __( 'Tax lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rate_code' => array( - 'description' => __( 'Tax rate code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'Tax rate label.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'compound' => array( - 'description' => __( 'Show if is a compound tax rate.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tax_total' => array( - 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_tax_total' => array( - 'description' => __( 'Shipping tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'shipping_lines' => array( - 'description' => __( 'Shipping lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_title' => array( - 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'instance_id' => array( - 'description' => __( 'Shipping instance ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'fee_lines' => array( - 'description' => __( 'Fee lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class of fee.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status of fee.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'taxable', 'none' ), - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'coupon_lines' => array( - 'description' => __( 'Coupons line data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'discount' => array( - 'description' => __( 'Discount total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'discount_tax' => array( - 'description' => __( 'Discount total tax.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'refunds' => array( - 'description' => __( 'List of refunds.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Refund ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reason' => array( - 'description' => __( 'Refund reason.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Refund total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['status'] = array( - 'default' => 'any', - 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['customer'] = array( - 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['product'] = array( - 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['dp'] = array( - 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - // This needs to remain a string to support extensions that filter Order Number. - $params['number'] = array( - 'description' => __( 'Limit result set to orders matching part of an order number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/PaymentGateways.php b/src/Controllers/Version4/PaymentGateways.php deleted file mode 100644 index 9cb4001e727..00000000000 --- a/src/Controllers/Version4/PaymentGateways.php +++ /dev/null @@ -1,426 +0,0 @@ - - */ - public function register_routes() { - register_rest_route( - $this->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 . '/(?P[\w-]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Get payment gateways. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $payment_gateways = WC()->payment_gateways->payment_gateways(); - $response = array(); - foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { - $payment_gateway->id = $payment_gateway_id; - $gateway = $this->prepare_item_for_response( $payment_gateway, $request ); - $gateway = $this->prepare_response_for_collection( $gateway ); - $response[] = $gateway; - } - return rest_ensure_response( $response ); - } - - /** - * Get a single payment gateway. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function get_item( $request ) { - $gateway = $this->get_gateway( $request ); - - if ( is_null( $gateway ) ) { - return new \WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $gateway = $this->prepare_item_for_response( $gateway, $request ); - return rest_ensure_response( $gateway ); - } - - /** - * Update A Single Payment Method. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function update_item( $request ) { - $gateway = $this->get_gateway( $request ); - - if ( is_null( $gateway ) ) { - return new \WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - // Get settings. - $gateway->init_form_fields(); - $settings = $gateway->settings; - - // Update settings. - if ( isset( $request['settings'] ) ) { - $errors_found = false; - foreach ( $gateway->form_fields as $key => $field ) { - if ( isset( $request['settings'][ $key ] ) ) { - if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { - $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); - } else { - $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); - } - if ( is_wp_error( $value ) ) { - $errors_found = true; - break; - } - $settings[ $key ] = $value; - } - } - - if ( $errors_found ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - // Update if this method is enabled or not. - if ( isset( $request['enabled'] ) ) { - $settings['enabled'] = wc_bool_to_string( $request['enabled'] ); - $gateway->enabled = $settings['enabled']; - } - - // Update title. - if ( isset( $request['title'] ) ) { - $settings['title'] = $request['title']; - $gateway->title = $settings['title']; - } - - // Update description. - if ( isset( $request['description'] ) ) { - $settings['description'] = $request['description']; - $gateway->description = $settings['description']; - } - - // Update options. - $gateway->settings = $settings; - update_option( $gateway->get_option_key(), apply_filters( 'woocommerce_gateway_' . $gateway->id . '_settings_values', $settings, $gateway ) ); - - // Update order. - if ( isset( $request['order'] ) ) { - $order = (array) get_option( 'woocommerce_gateway_order' ); - $order[ $gateway->id ] = $request['order']; - update_option( 'woocommerce_gateway_order', $order ); - $gateway->order = absint( $request['order'] ); - } - - $gateway = $this->prepare_item_for_response( $gateway, $request ); - return rest_ensure_response( $gateway ); - } - - /** - * Get a gateway based on the current request object. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|null - */ - public function get_gateway( $request ) { - $gateway = null; - $payment_gateways = WC()->payment_gateways->payment_gateways(); - foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { - if ( $request['id'] !== $payment_gateway_id ) { - continue; - } - $payment_gateway->id = $payment_gateway_id; - $gateway = $payment_gateway; - } - return $gateway; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WC_Payment_Gateway $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - $order = (array) get_option( 'woocommerce_gateway_order' ); - return array( - 'id' => $object->id, - 'title' => $object->title, - 'description' => $object->description, - 'order' => isset( $order[ $object->id ] ) ? $order[ $object->id ] : '', - 'enabled' => ( 'yes' === $object->enabled ), - 'method_title' => $object->get_method_title(), - 'method_description' => $object->get_method_description(), - 'method_supports' => $object->supports, - 'settings' => $this->get_settings( $object ), - ); - } - - /** - * Return settings associated with this payment gateway. - * - * @param WC_Payment_Gateway $gateway Gateway instance. - * - * @return array - */ - public function get_settings( $gateway ) { - $settings = array(); - $gateway->init_form_fields(); - foreach ( $gateway->form_fields as $id => $field ) { - // Make sure we at least have a title and type. - if ( empty( $field['title'] ) || empty( $field['type'] ) ) { - continue; - } - - // Ignore 'enabled' and 'description' which get included elsewhere. - if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { - continue; - } - - $data = array( - 'id' => $id, - 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the payment gateway schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'payment_gateway', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'absint', - ), - ), - 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - ), - 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_supports' => array( - 'description' => __( 'Supported features for this payment gateway.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get any query params needed. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } - -} diff --git a/src/Controllers/Version4/ProductAttributeTerms.php b/src/Controllers/Version4/ProductAttributeTerms.php deleted file mode 100644 index 119f2b290c9..00000000000 --- a/src/Controllers/Version4/ProductAttributeTerms.php +++ /dev/null @@ -1,225 +0,0 @@ -/terms endpoint. - * - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Product Attribute Terms controller class. - */ -class ProductAttributeTerms extends AbstractTermsContoller { - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'products/attributes/(?P[\d]+)/terms'; - - /** - * Register the routes for terms. - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - 'args' => array( - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'name' => array( - 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), - 'required' => true, - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - 'args' => array( - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WP_Term $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - $menu_order = get_term_meta( $object->term_id, 'order_' . $this->taxonomy, true ); - - return array( - 'id' => (int) $object->term_id, - 'name' => $object->name, - 'slug' => $object->slug, - 'description' => $object->description, - 'menu_order' => (int) $menu_order, - 'count' => (int) $object->count, - ); - } - - /** - * Update term meta fields. - * - * @param \WP_Term $term Term object. - * @param \WP_REST_Request $request Request params. - * @return bool|\WP_Error - */ - protected function update_term_meta_fields( $term, $request ) { - $id = (int) $term->term_id; - - update_term_meta( $id, 'order_' . $this->taxonomy, $request['menu_order'] ); - - return true; - } - - /** - * Get the Attribute Term's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_attribute_term', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/ProductAttributes.php b/src/Controllers/Version4/ProductAttributes.php deleted file mode 100644 index 115dc709d14..00000000000 --- a/src/Controllers/Version4/ProductAttributes.php +++ /dev/null @@ -1,490 +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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'name' => array( - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'required' => true, - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => true, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - $this->register_batch_route(); - } - - /** - * Get all attributes. - * - * @param \WP_REST_Request $request Request params. - * @return array - */ - public function get_items( $request ) { - $attributes = wc_get_attribute_taxonomies(); - $data = array(); - foreach ( $attributes as $attribute_obj ) { - $attribute = $this->prepare_item_for_response( $attribute_obj, $request ); - $attribute = $this->prepare_response_for_collection( $attribute ); - $data[] = $attribute; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a single attribute. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function create_item( $request ) { - global $wpdb; - - $id = wc_create_attribute( - array( - 'name' => $request['name'], - 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), - 'type' => ! empty( $request['type'] ) ? $request['type'] : 'select', - 'order_by' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', - 'has_archives' => true === $request['has_archives'], - ) - ); - - // Checks for errors. - if ( is_wp_error( $id ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_create', $id->get_error_message(), array( 'status' => 400 ) ); - } - - $attribute = $this->get_attribute( $id ); - - if ( is_wp_error( $attribute ) ) { - return $attribute; - } - - $this->update_additional_fields_for_object( $attribute, $request ); - - /** - * Fires after a single product attribute is created or updated via the REST API. - * - * @param stdObject $attribute Inserted attribute object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating attribute, false when updating. - */ - do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $attribute, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( '/' . $this->namespace . '/' . $this->rest_base . '/' . $attribute->attribute_id ) ); - - return $response; - } - - /** - * Get a single attribute. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function get_item( $request ) { - $attribute = $this->get_attribute( (int) $request['id'] ); - - if ( is_wp_error( $attribute ) ) { - return $attribute; - } - - $response = $this->prepare_item_for_response( $attribute, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Update a single term from a taxonomy. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function update_item( $request ) { - global $wpdb; - - $id = (int) $request['id']; - $edited = wc_update_attribute( - $id, - array( - 'name' => $request['name'], - 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), - 'type' => $request['type'], - 'order_by' => $request['order_by'], - 'has_archives' => $request['has_archives'], - ) - ); - - // Checks for errors. - if ( is_wp_error( $edited ) ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', $edited->get_error_message(), array( 'status' => 400 ) ); - } - - $attribute = $this->get_attribute( $id ); - - if ( is_wp_error( $attribute ) ) { - return $attribute; - } - - $this->update_additional_fields_for_object( $attribute, $request ); - - /** - * Fires after a single product attribute is created or updated via the REST API. - * - * @param stdObject $attribute Inserted attribute object. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating attribute, false when updating. - */ - do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $attribute, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Delete a single attribute. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Response|\WP_Error - */ - public function delete_item( $request ) { - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $attribute = $this->get_attribute( (int) $request['id'] ); - - if ( is_wp_error( $attribute ) ) { - return $attribute; - } - - $request->set_param( 'context', 'edit' ); - $previous = $this->prepare_item_for_response( $attribute, $request ); - $deleted = wc_delete_attribute( $attribute->attribute_id ); - - if ( false === $deleted ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - - /** - * Fires after a single attribute is deleted via the REST API. - * - * @param stdObject $attribute The deleted attribute. - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_product_attribute', $attribute, $response, $request ); - - return $response; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param object $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return array( - 'id' => (int) $object->attribute_id, - 'name' => $object->attribute_label, - 'slug' => wc_attribute_taxonomy_name( $object->attribute_name ), - 'type' => $object->attribute_type, - 'order_by' => $object->attribute_orderby, - 'has_archives' => (bool) $object->attribute_public, - ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - $links = array( - 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $item->attribute_id ), - ), - 'collection' => array( - 'href' => rest_url( $base ), - ), - ); - - return $links; - } - - /** - * Get the Attribute's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_attribute', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'type' => array( - 'description' => __( 'Type of attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'select', - 'enum' => array_keys( wc_get_attribute_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'order_by' => array( - 'description' => __( 'Default sort order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'menu_order', - 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ), - 'context' => array( 'view', 'edit' ), - ), - 'has_archives' => array( - 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - 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; - } - - /** - * Get attribute name. - * - * @param \WP_REST_Request $request Full details about the request. - * @return string - */ - protected function get_taxonomy( $request ) { - if ( '' !== $this->attribute ) { - return $this->attribute; - } - - if ( $request['id'] ) { - $name = wc_attribute_taxonomy_name_by_id( (int) $request['id'] ); - - $this->attribute = $name; - } - - return $this->attribute; - } - - /** - * Get attribute data. - * - * @param int $id Attribute ID. - * @return stdClass|\WP_Error - */ - protected function get_attribute( $id ) { - global $wpdb; - - $attribute = $wpdb->get_row( - $wpdb->prepare( - " - SELECT * - FROM {$wpdb->prefix}woocommerce_attribute_taxonomies - WHERE attribute_id = %d - ", - $id - ) - ); - - if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { - return new \WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - return $attribute; - } - - /** - * Validate attribute slug. - * - * @deprecated 3.2.0 - * @param string $slug Slug being set. - * @param bool $new_data Is the data new or old. - * @return bool|\WP_Error - */ - protected function validate_attribute_slug( $slug, $new_data = true ) { - if ( strlen( $slug ) >= 28 ) { - /* Translators: %s slug. */ - return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); - } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { - /* Translators: %s slug. */ - return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); - } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { - /* Translators: %s slug. */ - return new \WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); - } - - return true; - } - - /** - * Schedule to flush rewrite rules. - * - * @deprecated 3.2.0 - * @since 3.0.0 - */ - protected function flush_rewrite_rules() { - wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); - } -} diff --git a/src/Controllers/Version4/ProductCategories.php b/src/Controllers/Version4/ProductCategories.php deleted file mode 100644 index cf863a2342d..00000000000 --- a/src/Controllers/Version4/ProductCategories.php +++ /dev/null @@ -1,253 +0,0 @@ -term_id, 'display_type', true ); - $menu_order = get_term_meta( $object->term_id, 'order', true ); - $image_id = get_term_meta( $object->term_id, 'thumbnail_id', true ); - $data = array( - 'id' => (int) $object->term_id, - 'name' => $object->name, - 'slug' => $object->slug, - 'parent' => (int) $object->parent, - 'description' => $object->description, - 'display' => $display_type ? $display_type : 'default', - 'image' => null, - 'menu_order' => (int) $menu_order, - 'count' => (int) $object->count, - ); - - if ( $image_id ) { - $attachment = get_post( $image_id ); - - $data['image'] = array( - 'id' => (int) $image_id, - 'date_created' => wc_rest_prepare_date_response( $attachment->post_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), - 'src' => wp_get_attachment_url( $image_id ), - 'name' => get_the_title( $attachment ), - 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), - ); - } - return $data; - } - - /** - * Update term meta fields. - * - * @param \WP_Term $term Term object. - * @param \WP_REST_Request $request Request instance. - * @return bool|\WP_Error - * - * @since 3.5.5 - */ - protected function update_term_meta_fields( $term, $request ) { - $id = (int) $term->term_id; - - if ( isset( $request['display'] ) ) { - update_term_meta( $id, 'display_type', 'default' === $request['display'] ? '' : $request['display'] ); - } - - if ( isset( $request['menu_order'] ) ) { - update_term_meta( $id, 'order', $request['menu_order'] ); - } - - if ( isset( $request['image'] ) ) { - if ( empty( $request['image']['id'] ) && ! empty( $request['image']['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $request['image']['src'] ) ); - - if ( is_wp_error( $upload ) ) { - return $upload; - } - - $image_id = wc_rest_set_uploaded_image_as_attachment( $upload ); - } else { - $image_id = isset( $request['image']['id'] ) ? absint( $request['image']['id'] ) : 0; - } - - // Check if image_id is a valid image attachment before updating the term meta. - if ( $image_id && wp_attachment_is_image( $image_id ) ) { - update_term_meta( $id, 'thumbnail_id', $image_id ); - - // Set the image alt. - if ( ! empty( $request['image']['alt'] ) ) { - update_post_meta( $image_id, '_wp_attachment_image_alt', wc_clean( $request['image']['alt'] ) ); - } - - // Set the image title. - if ( ! empty( $request['image']['name'] ) ) { - wp_update_post( - array( - 'ID' => $image_id, - 'post_title' => wc_clean( $request['image']['name'] ), - ) - ); - } - } else { - delete_term_meta( $id, 'thumbnail_id' ); - } - } - - return true; - } - - /** - * Get the Category schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'default', - 'enum' => array( 'default', 'products', 'subcategories', 'both' ), - 'context' => array( 'view', 'edit' ), - ), - 'image' => array( - 'description' => __( 'Image data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/ProductReviews.php b/src/Controllers/Version4/ProductReviews.php deleted file mode 100644 index 9941ae93b67..00000000000 --- a/src/Controllers/Version4/ProductReviews.php +++ /dev/null @@ -1,1017 +0,0 @@ -/reviews. - * - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -use Automattic\WooCommerce\RestApi\Controllers\Version4\Responses\ProductReviewResponse; -use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; -use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination; - -/** - * REST API Product Reviews controller class. - */ -class ProductReviews extends AbstractController { - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'products/reviews'; - - /** - * Permission to check. - * - * @var string - */ - protected $resource_type = 'product_reviews'; - - /** - * Register the routes for product reviews. - */ - public function register_routes() { - register_rest_route( - $this->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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'product_id' => array( - 'required' => true, - 'description' => __( 'Unique identifier for the product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'review' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce-rest-api' ), - ), - 'reviewer' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce-rest-api' ), - ), - 'reviewer_email' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce-rest-api' ), - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - $this->register_batch_route(); - } - - /** - * Get all reviews. - * - * @param \WP_REST_Request $request Full details about the request. - * @return array|\WP_Error - */ - public function get_items( $request ) { - // Retrieve the list of registered collection query parameters. - $registered = $this->get_collection_params(); - - /* - * This array defines mappings between public API query parameters whose - * values are accepted as-passed, and their internal \WP_Query parameter - * name equivalents (some are the same). Only values which are also - * present in $registered will be set. - */ - $parameter_mappings = array( - 'reviewer' => 'author__in', - 'reviewer_email' => 'author_email', - 'reviewer_exclude' => 'author__not_in', - 'exclude' => 'comment__not_in', - 'include' => 'comment__in', - 'offset' => 'offset', - 'order' => 'order', - 'per_page' => 'number', - 'product' => 'post__in', - 'search' => 'search', - 'status' => 'status', - ); - - $prepared_args = array(); - - /* - * For each known parameter which is both registered and present in the request, - * set the parameter's value on the query $prepared_args. - */ - foreach ( $parameter_mappings as $api_param => $wp_param ) { - if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { - $prepared_args[ $wp_param ] = $request[ $api_param ]; - } - } - - // Ensure certain parameter values default to empty strings. - foreach ( array( 'author_email', 'search' ) as $param ) { - if ( ! isset( $prepared_args[ $param ] ) ) { - $prepared_args[ $param ] = ''; - } - } - - if ( isset( $registered['orderby'] ) ) { - $prepared_args['orderby'] = $this->normalize_query_param( $request['orderby'] ); - } - - if ( isset( $prepared_args['status'] ) ) { - $prepared_args['status'] = 'approved' === $prepared_args['status'] ? 'approve' : $prepared_args['status']; - } - - $prepared_args['no_found_rows'] = false; - $prepared_args['date_query'] = array(); - - // Set before into date query. Date query must be specified as an array of an array. - if ( isset( $registered['before'], $request['before'] ) ) { - $prepared_args['date_query'][0]['before'] = $request['before']; - } - - // Set after into date query. Date query must be specified as an array of an array. - if ( isset( $registered['after'], $request['after'] ) ) { - $prepared_args['date_query'][0]['after'] = $request['after']; - } - - if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { - $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); - } - - /** - * Filters arguments, before passing to \WP_Comment_Query, when querying reviews via the REST API. - * - * @since 3.5.0 - * @link https://developer.wordpress.org/reference/classes/\WP_Comment_Query/ - * @param array $prepared_args Array of arguments for \WP_Comment_Query. - * @param \WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_product_review_query', $prepared_args, $request ); - - // Make sure that returns only reviews. - $prepared_args['type'] = 'review'; - - // Query reviews. - $query = new \WP_Comment_Query(); - $query_result = $query->query( $prepared_args ); - $reviews = array(); - - foreach ( $query_result as $review ) { - if ( ! Permissions::user_can_read( 'product_review', $review->comment_ID ) ) { - continue; - } - - $data = $this->prepare_item_for_response( $review, $request ); - $reviews[] = $this->prepare_response_for_collection( $data ); - } - - $total_reviews = (int) $query->found_comments; - $max_pages = (int) $query->max_num_pages; - - if ( $total_reviews < 1 ) { - // Out-of-bounds, run the query again without LIMIT for total count. - unset( $prepared_args['number'], $prepared_args['offset'] ); - - $query = new \WP_Comment_Query(); - $prepared_args['count'] = true; - - $total_reviews = $query->query( $prepared_args ); - $max_pages = ceil( $total_reviews / $request['per_page'] ); - } - - $response = rest_ensure_response( $reviews ); - $response = Pagination::add_pagination_headers( $response, $request, $total_reviews, $max_pages ); - - return $response; - } - - /** - * Create a single review. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - return new \WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $prepared_review = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $prepared_review ) ) { - return $prepared_review; - } - - $prepared_review['comment_type'] = 'review'; - - /* - * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). - */ - if ( empty( $prepared_review['comment_content'] ) ) { - return new \WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). - if ( ! isset( $prepared_review['comment_date_gmt'] ) ) { - $prepared_review['comment_date_gmt'] = current_time( 'mysql', true ); - } - - if ( ! empty( $_SERVER['REMOTE_ADDR'] ) && rest_is_ip_address( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) ) { // WPCS: input var ok, sanitization ok. - $prepared_review['comment_author_IP'] = wc_clean( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // WPCS: input var ok. - } else { - $prepared_review['comment_author_IP'] = '127.0.0.1'; - } - - if ( ! empty( $request['author_user_agent'] ) ) { - $prepared_review['comment_agent'] = $request['author_user_agent']; - } elseif ( $request->get_header( 'user_agent' ) ) { - $prepared_review['comment_agent'] = $request->get_header( 'user_agent' ); - } else { - $prepared_review['comment_agent'] = ''; - } - - $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); - if ( is_wp_error( $check_comment_lengths ) ) { - $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new \WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $prepared_review['comment_parent'] = 0; - $prepared_review['comment_author_url'] = ''; - $prepared_review['comment_approved'] = wp_allow_comment( $prepared_review, true ); - - if ( is_wp_error( $prepared_review['comment_approved'] ) ) { - $error_code = $prepared_review['comment_approved']->get_error_code(); - $error_message = $prepared_review['comment_approved']->get_error_message(); - - if ( 'comment_duplicate' === $error_code ) { - return new \WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 409 ) ); - } - - if ( 'comment_flood' === $error_code ) { - return new \WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 400 ) ); - } - - return $prepared_review['comment_approved']; - } - - /** - * Filters a review before it is inserted via the REST API. - * - * Allows modification of the review right before it is inserted via wp_insert_comment(). - * Returning a \WP_Error value from the filter will shortcircuit insertion and allow - * skipping further processing. - * - * @since 3.5.0 - * @param array|\WP_Error $prepared_review The prepared review data for wp_insert_comment(). - * @param \WP_REST_Request $request Request used to insert the review. - */ - $prepared_review = apply_filters( 'woocommerce_rest_pre_insert_product_review', $prepared_review, $request ); - if ( is_wp_error( $prepared_review ) ) { - return $prepared_review; - } - - $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); - - if ( ! $review_id ) { - return new \WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - if ( isset( $request['status'] ) ) { - $this->handle_status_param( $request['status'], $review_id ); - } - - update_comment_meta( $review_id, 'rating', ! empty( $request['rating'] ) ? $request['rating'] : '0' ); - - $review = get_comment( $review_id ); - - /** - * Fires after a comment is created or updated via the REST API. - * - * @param WP_Comment $review Inserted or updated comment object. - * @param \WP_REST_Request $request Request object. - * @param bool $creating True when creating a comment, false when updating. - */ - do_action( 'woocommerce_rest_insert_product_review', $review, $request, true ); - - $fields_update = $this->update_additional_fields_for_object( $review, $request ); - if ( is_wp_error( $fields_update ) ) { - return $fields_update; - } - - $context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view'; - $request->set_param( 'context', $context ); - - $response = $this->prepare_item_for_response( $review, $request ); - - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $review_id ) ) ); - - return $response; - } - - /** - * Get a single product review. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $review = $this->get_review( $request['id'] ); - if ( is_wp_error( $review ) ) { - return $review; - } - - return $this->prepare_item_for_response( $review, $request ); - } - - /** - * Updates a review. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response Response object on success, or error object on failure. - */ - public function update_item( $request ) { - $review = $this->get_review( $request['id'] ); - if ( is_wp_error( $review ) ) { - return $review; - } - - $id = (int) $review->comment_ID; - - if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { - return new \WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $prepared_args = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $prepared_args ) ) { - return $prepared_args; - } - - if ( ! empty( $prepared_args['comment_post_ID'] ) ) { - if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { - return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - } - - if ( empty( $prepared_args ) && isset( $request['status'] ) ) { - // Only the comment status is being changed. - $change = $this->handle_status_param( $request['status'], $id ); - - if ( ! $change ) { - return new \WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - } elseif ( ! empty( $prepared_args ) ) { - if ( is_wp_error( $prepared_args ) ) { - return $prepared_args; - } - - if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { - return new \WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $prepared_args['comment_ID'] = $id; - - $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); - if ( is_wp_error( $check_comment_lengths ) ) { - $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new \WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); - - if ( false === $updated ) { - return new \WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - if ( isset( $request['status'] ) ) { - $this->handle_status_param( $request['status'], $id ); - } - } - - if ( ! empty( $request['rating'] ) ) { - update_comment_meta( $id, 'rating', $request['rating'] ); - } - - $review = get_comment( $id ); - - /** This action is documented in includes/api/class-wc-rest-product-reviews-controller.php */ - do_action( 'woocommerce_rest_insert_product_review', $review, $request, false ); - - $fields_update = $this->update_additional_fields_for_object( $review, $request ); - - if ( is_wp_error( $fields_update ) ) { - return $fields_update; - } - - $request->set_param( 'context', 'edit' ); - - return $this->prepare_item_for_response( $review, $request ); - } - - /** - * Deletes a review. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response Response object on success, or error object on failure. - */ - public function delete_item( $request ) { - $review = $this->get_review( $request['id'] ); - if ( is_wp_error( $review ) ) { - return $review; - } - - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - /** - * Filters whether a review can be trashed. - * - * Return false to disable trash support for the post. - * - * @since 3.5.0 - * @param bool $supports_trash Whether the post type support trashing. - * @param WP_Comment $review The review object being considered for trashing support. - */ - $supports_trash = apply_filters( 'woocommerce_rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $review ); - - $request->set_param( 'context', 'edit' ); - - if ( $force ) { - $previous = $this->prepare_item_for_response( $review, $request ); - $result = wp_delete_comment( $review->comment_ID, true ); - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - } else { - // If this type doesn't support trashing, error out. - if ( ! $supports_trash ) { - /* translators: %s: force=true */ - return new \WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce-rest-api' ), 'force=true' ), array( 'status' => 501 ) ); - } - - if ( 'trash' === $review->comment_approved ) { - return new \WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce-rest-api' ), array( 'status' => 410 ) ); - } - - $result = wp_trash_comment( $review->comment_ID ); - $review = get_comment( $review->comment_ID ); - $response = $this->prepare_item_for_response( $review, $request ); - } - - if ( ! $result ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a review is deleted via the REST API. - * - * @param WP_Comment $review The deleted review data. - * @param \WP_REST_Response $response The response returned from the API. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_review', $review, $response, $request ); - - return $response; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WP_Comment $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - $formatter = new ProductReviewResponse(); - - return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); - } - - /** - * Prepare a single product review to be inserted into the database. - * - * @param \WP_REST_Request $request Request object. - * @return array|\WP_Error $prepared_review - */ - protected function prepare_item_for_database( $request ) { - if ( isset( $request['id'] ) ) { - $prepared_review['comment_ID'] = (int) $request['id']; - } - - if ( isset( $request['review'] ) ) { - $prepared_review['comment_content'] = $request['review']; - } - - if ( isset( $request['product_id'] ) ) { - $prepared_review['comment_post_ID'] = (int) $request['product_id']; - } - - if ( isset( $request['reviewer'] ) ) { - $prepared_review['comment_author'] = $request['reviewer']; - } - - if ( isset( $request['reviewer_email'] ) ) { - $prepared_review['comment_author_email'] = $request['reviewer_email']; - } - - if ( ! empty( $request['date_created'] ) ) { - $date_data = rest_get_date_with_gmt( $request['date_created'] ); - - if ( ! empty( $date_data ) ) { - list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; - } - } elseif ( ! empty( $request['date_created_gmt'] ) ) { - $date_data = rest_get_date_with_gmt( $request['date_created_gmt'], true ); - - if ( ! empty( $date_data ) ) { - list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; - } - } - - /** - * Filters a review after it is prepared for the database. - * - * Allows modification of the review right after it is prepared for the database. - * - * @since 3.5.0 - * @param array $prepared_review The prepared review data for `wp_insert_comment`. - * @param \WP_REST_Request $request The current request. - */ - return apply_filters( 'woocommerce_rest_preprocess_product_review', $prepared_review, $request ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->comment_ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - if ( 0 !== (int) $item->comment_post_ID ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $item->comment_post_ID ) ), - 'embeddable' => true, - ); - } - if ( 0 !== (int) $item->user_id ) { - $links['reviewer'] = array( - 'href' => rest_url( 'wp/v2/users/' . $item->user_id ), - 'embeddable' => true, - ); - } - return $links; - } - - /** - * Get the Product Review's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_review', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the review was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Status of the review.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'approved', - 'enum' => array( 'approved', 'hold', 'spam', 'unspam', 'trash', 'untrash' ), - 'context' => array( 'view', 'edit' ), - ), - 'reviewer' => array( - 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'reviewer_email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - if ( get_option( 'show_avatars' ) ) { - $avatar_properties = array(); - $avatar_sizes = rest_get_avatar_sizes(); - - foreach ( $avatar_sizes as $size ) { - $avatar_properties[ $size ] = array( - /* translators: %d: avatar image size in pixels */ - 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce-rest-api' ), $size ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'embed', 'view', 'edit' ), - ); - } - $schema['properties']['reviewer_avatar_urls'] = array( - 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $avatar_properties, - ); - } - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['context']['default'] = 'view'; - - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - ); - $params['before'] = array( - 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - ); - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - ); - $params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - ); - $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( - 'asc', - 'desc', - ), - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'date_gmt', - 'enum' => array( - 'date', - 'date_gmt', - 'id', - 'include', - 'product', - ), - ); - $params['reviewer'] = array( - 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['reviewer_exclude'] = array( - 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['reviewer_email'] = array( - 'default' => null, - 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce-rest-api' ), - 'format' => 'email', - 'type' => 'string', - ); - $params['product'] = array( - 'default' => array(), - 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['status'] = array( - 'default' => 'approved', - 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce-rest-api' ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'enum' => array( - 'all', - 'hold', - 'approved', - 'spam', - 'trash', - ), - ); - - /** - * Filter collection parameters for the reviews controller. - * - * This filter registers the collection parameter, but does not map the - * collection parameter to an internal \WP_Comment_Query parameter. Use the - * `wc_rest_review_query` filter to set \WP_Comment_Query parameters. - * - * @since 3.5.0 - * @param array $params JSON Schema-formatted collection parameters. - */ - return apply_filters( 'woocommerce_rest_product_review_collection_params', $params ); - } - - /** - * Get the reivew, if the ID is valid. - * - * @since 3.5.0 - * @param int $id Supplied ID. - * @return WP_Comment|\WP_Error Comment object if ID is valid, \WP_Error otherwise. - */ - protected function get_review( $id ) { - $id = (int) $id; - $error = new \WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - - if ( 0 >= $id ) { - return $error; - } - - $review = get_comment( $id ); - if ( empty( $review ) ) { - return $error; - } - - if ( ! empty( $review->comment_post_ID ) ) { - $post = get_post( (int) $review->comment_post_ID ); - - if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { - return new \WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - } - - return $review; - } - - /** - * Prepends internal property prefix to query parameters to match our response fields. - * - * @since 3.5.0 - * @param string $query_param Query parameter. - * @return string - */ - protected function normalize_query_param( $query_param ) { - $prefix = 'comment_'; - - switch ( $query_param ) { - case 'id': - $normalized = $prefix . 'ID'; - break; - case 'product': - $normalized = $prefix . 'post_ID'; - break; - case 'include': - $normalized = 'comment__in'; - break; - default: - $normalized = $prefix . $query_param; - break; - } - - return $normalized; - } - - - - /** - * Sets the comment_status of a given review object when creating or updating a review. - * - * @since 3.5.0 - * @param string|int $new_status New review status. - * @param int $id Review ID. - * @return bool Whether the status was changed. - */ - protected function handle_status_param( $new_status, $id ) { - $old_status = wp_get_comment_status( $id ); - - if ( $new_status === $old_status ) { - return false; - } - - switch ( $new_status ) { - case 'approved': - case 'approve': - case '1': - $changed = wp_set_comment_status( $id, 'approve' ); - break; - case 'hold': - case '0': - $changed = wp_set_comment_status( $id, 'hold' ); - break; - case 'spam': - $changed = wp_spam_comment( $id ); - break; - case 'unspam': - $changed = wp_unspam_comment( $id ); - break; - case 'trash': - $changed = wp_trash_comment( $id ); - break; - case 'untrash': - $changed = wp_untrash_comment( $id ); - break; - default: - $changed = false; - break; - } - - return $changed; - } - - /** - * Check if a given request has access to read a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $check_valid = $this->get_review( $id ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::get_item_permissions_check( $request ); - } - - /** - * Check if a given request has access to delete an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $check_valid = $this->get_review( $id ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::delete_item_permissions_check( $request ); - } - - /** - * Check if a given request has access to update an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $id = $request->get_param( 'id' ); - $check_valid = $this->get_review( $id ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::update_item_permissions_check( $request ); - } -} diff --git a/src/Controllers/Version4/ProductShippingClasses.php b/src/Controllers/Version4/ProductShippingClasses.php deleted file mode 100644 index 230cb312eb7..00000000000 --- a/src/Controllers/Version4/ProductShippingClasses.php +++ /dev/null @@ -1,102 +0,0 @@ - (int) $object->term_id, - 'name' => $object->name, - 'slug' => $object->slug, - 'description' => $object->description, - 'count' => (int) $object->count, - ); - } - - /** - * Get the Shipping Class schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Shipping class name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/ProductTags.php b/src/Controllers/Version4/ProductTags.php deleted file mode 100644 index 752d270afd3..00000000000 --- a/src/Controllers/Version4/ProductTags.php +++ /dev/null @@ -1,102 +0,0 @@ - (int) $object->term_id, - 'name' => $object->name, - 'slug' => $object->slug, - 'description' => $object->description, - 'count' => (int) $object->count, - ); - } - - /** - * Get the Tag's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/ProductVariations.php b/src/Controllers/Version4/ProductVariations.php deleted file mode 100644 index e0a6bbad5a1..00000000000 --- a/src/Controllers/Version4/ProductVariations.php +++ /dev/null @@ -1,902 +0,0 @@ -/variations endpoints. - * - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -use Automattic\WooCommerce\RestApi\Controllers\Version4\Requests\ProductVariationRequest; -use Automattic\WooCommerce\RestApi\Controllers\Version4\Responses\ProductVariationResponse; -use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions; - -/** - * REST API variations controller class. - */ -class ProductVariations extends Products { - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'products/(?P[\d]+)/variations'; - - /** - * Post type. - * - * @var string - */ - protected $post_type = 'product_variation'; - - /** - * Register the routes for products. - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); - } - - /** - * Get the Variation's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_variation', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product parent name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'variation', - 'enum' => array( 'variation' ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wc_clean', - ), - ), - 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Variation status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_keys( get_post_statuses() ), - 'context' => array( 'view', 'edit' ), - ), - 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - unset( - $params['in_stock'], - $params['type'], - $params['featured'], - $params['category'], - $params['tag'], - $params['shipping_class'], - $params['attribute'], - $params['attribute_term'] - ); - - $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['search'] = array( - 'description' => __( 'Search by similar product name or sku.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - - /** - * Get object. - * - * @since 3.0.0 - * @param int $id Object ID. - * @return \WC_Data|bool - */ - protected function get_object( $id ) { - return wc_get_product( $id ); - } - - /** - * Check if a given ID is valid. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - protected function check_valid_variation_id( $request ) { - $id = $request->get_param( 'id' ); - $object = $this->get_object( $id ); - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - // Check if variation belongs to the correct parent product. - if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { - return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to read a webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $check_valid = $this->check_valid_variation_id( $request ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::get_item_permissions_check( $request ); - } - - /** - * Check if a given request has access to delete an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $check_valid = $this->check_valid_variation_id( $request ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::delete_item_permissions_check( $request ); - } - - /** - * Check if a given request has access to update an item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $check_valid = $this->check_valid_variation_id( $request ); - - if ( is_wp_error( $check_valid ) ) { - return $check_valid; - } - - return parent::update_item_permissions_check( $request ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WC_Variation $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - $formatter = new ProductVariationResponse(); - - return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - // Set post_status. - $args['post_status'] = $request['status']; - - // Set custom args to handle later during clauses. - $custom_keys = array( - 'sku', - 'min_price', - 'max_price', - 'stock_status', - 'low_in_stock', - ); - foreach ( $custom_keys as $key ) { - if ( ! empty( $request[ $key ] ) ) { - $args[ $key ] = $request[ $key ]; - } - } - - // Filter by tax class. - if ( ! empty( $request['tax_class'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_tax_class', - 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', - ) - ); - } - - // Filter by on sale products. - if ( is_bool( $request['on_sale'] ) ) { - $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; - $on_sale_ids = wc_get_product_ids_on_sale(); - - // Use 0 when there's no on sale products to avoid return all products. - $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; - - $args[ $on_sale_key ] += $on_sale_ids; - } - - // Force the post_type argument, since it's not a user input variable. - if ( ! empty( $request['sku'] ) ) { - $args['post_type'] = array( 'product', 'product_variation' ); - } else { - $args['post_type'] = $this->post_type; - } - - $args['post_parent'] = $request['product_id']; - - if ( ! empty( $request['search'] ) ) { - $args['search'] = $request['search']; - unset( $args['s'] ); - } - - return $args; - } - - /** - * Prepare a single variation for create or update. - * - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WP_Error|\WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - try { - $variation_request = new ProductVariationRequest( $request ); - $variation = $variation_request->prepare_object(); - } catch ( \WC_REST_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param \WC_Data $variation Object object. - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); - } - - - /** - * Delete a variation. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return bool|\WP_Error|\WP_REST_Response - */ - public function delete_item( $request ) { - $force = (bool) $request['force']; - $object = $this->get_object( (int) $request['id'] ); - $result = false; - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( - "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( - 'status' => 404, - ) - ); - } - - $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); - - /** - * Filter whether an object is trashable. - * - * Return false to disable trash support for the object. - * - * @param boolean $supports_trash Whether the object type support trashing. - * @param \WC_Data $object The object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - - if ( ! Permissions::user_can_delete( $this->post_type, $object->get_id() ) ) { - return new \WP_Error( - /* translators: %s: post type */ - "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - $request->set_param( 'context', 'edit' ); - - // If we're forcing, then delete permanently. - if ( $force ) { - $previous = $this->prepare_item_for_response( $object, $request ); - - $object->delete( true ); - - $result = 0 === $object->get_id(); - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - return new \WP_Error( - /* translators: %s: post type */ - 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( - 'status' => 501, - ) - ); - } - - // Otherwise, only trash if we haven't already. - if ( is_callable( array( $object, 'get_status' ) ) ) { - if ( 'trash' === $object->get_status() ) { - return new \WP_Error( - /* translators: %s: post type */ - 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( - 'status' => 410, - ) - ); - } - - $object->delete(); - $result = 'trash' === $object->get_status(); - } - - $response = $this->prepare_item_for_response( $object, $request ); - } - - if ( ! $result ) { - return new \WP_Error( - /* translators: %s: post type */ - 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( - 'status' => 500, - ) - ); - } - - /** - * Fires after a single object is deleted or trashed via the REST API. - * - * @param \WC_Data $object The deleted or trashed object. - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); - - return $response; - } - - /** - * Get batch of items from requst. - * - * @param \WP_REST_Request $request Full details about the request. - * @param string $batch_type Batch type; one of create, update, delete. - * @return array - */ - protected function get_batch_of_items_from_request( $request, $batch_type ) { - $params = $request->get_params(); - $url_params = $request->get_url_params(); - $product_id = $url_params['product_id']; - - if ( ! isset( $params[ $batch_type ] ) ) { - return array(); - } - - $items = array_filter( $params[ $batch_type ] ); - - if ( 'update' === $batch_type || 'create' === $batch_type ) { - foreach ( $items as $key => $item ) { - $items[ $key ] = array_merge( - array( - 'product_id' => $product_id, - ), - $item - ); - } - } - - return array_filter( $items ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $product_id = (int) $request['product_id']; - $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $item->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), - ), - ); - return $links; - } -} diff --git a/src/Controllers/Version4/Products.php b/src/Controllers/Version4/Products.php deleted file mode 100644 index 592d54b4a20..00000000000 --- a/src/Controllers/Version4/Products.php +++ /dev/null @@ -1,1227 +0,0 @@ - 'http://json-schema.org/draft-04/schema#', - 'title' => 'product', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit', 'embed' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit', 'embed' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'simple', - 'enum' => array_keys( wc_get_product_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), - 'context' => array( 'view', 'edit' ), - ), - 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'visible', - 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Product description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit', 'embed' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wc_clean', - ), - ), - 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_kses_post', - ), - ), - 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'images' => array( - 'description' => __( 'List of images.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit', 'embed' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'integer', - ), - 'readonly' => true, - ), - 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['status'] = array( - 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_types() ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['sku'] = array( - 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['featured'] = array( - 'description' => __( 'Limit result set to featured products.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - if ( wc_tax_enabled() ) { - $params['tax_class'] = array( - 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - } - - $params['on_sale'] = array( - 'description' => __( 'Limit result set to products on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['min_price'] = array( - 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['max_price'] = array( - 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['low_in_stock'] = array( - 'description' => __( 'Limit result set to products that are low or out of stock.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'sanitize_callback' => 'wc_string_to_bool', - ); - - $params['search'] = array( - 'description' => __( 'Search by similar product name or sku.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); - - return $params; - } - - /** - * Get object. - * - * @param int $id Object ID. - * - * @since 3.0.0 - * @return \WC_Data|bool - */ - protected function get_object( $id ) { - return wc_get_product( $id ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WC_Product $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - $formatter = new ProductResponse(); - - return $formatter->prepare_response( $object, $this->get_request_context( $request ) ); - } - - /** - * Prepare a single product for create or update. - * - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return \WP_Error|\WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - try { - $product_request = new ProductRequest( $request ); - $product = $product_request->prepare_object(); - } catch ( \WC_REST_Exception $e ) { - return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param \WC_Data $product Object object. - * @param \WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); - } - - /** - * Get a collection of posts and add the post title filter option to \WP_Query. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - add_filter( 'posts_clauses', array( $this, 'get_items_query_clauses' ), 10, 2 ); - $response = parent::get_items( $request ); - remove_filter( 'posts_clauses', array( $this, 'get_items_query_clauses' ), 10 ); - return $response; - } - - /** - * Add in conditional search filters for products. - * - * @param array $args Query args. - * @param \WC_Query $wp_query WC_Query object. - * @return array - */ - public function get_items_query_clauses( $args, $wp_query ) { - global $wpdb; - - if ( $wp_query->get( 'search' ) ) { - $search = "'%" . $wpdb->esc_like( $wp_query->get( 'search' ) ) . "%'"; - $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); - $args['where'] .= " AND ({$wpdb->posts}.post_title LIKE {$search}"; - $args['where'] .= wc_product_sku_enabled() ? ' OR wc_product_meta_lookup.sku LIKE ' . $search . ')' : ')'; - } - - if ( $wp_query->get( 'sku' ) ) { - $skus = explode( ',', $wp_query->get( 'sku' ) ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $wp_query->get( 'sku' ); - } - $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); - $args['where'] .= ' AND wc_product_meta_lookup.sku IN ("' . implode( '","', array_map( 'esc_sql', $skus ) ) . '")'; - } - - if ( $wp_query->get( 'min_price' ) ) { - $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); - $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.min_price >= %f ', floatval( $wp_query->get( 'min_price' ) ) ); - } - - if ( $wp_query->get( 'max_price' ) ) { - $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); - $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.max_price <= %f ', floatval( $wp_query->get( 'max_price' ) ) ); - } - - if ( $wp_query->get( 'stock_status' ) ) { - $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); - $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.stock_status = %s ', $wp_query->get( 'stock_status' ) ); - } - - if ( $wp_query->get( 'low_in_stock' ) ) { - $low_stock = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) ); - $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); - $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.stock_quantity <= %d', $low_stock ); - } - - return $args; - } - - /** - * Join wc_product_meta_lookup to posts if not already joined. - * - * @param string $sql SQL join. - * @return string - */ - protected function append_product_sorting_table_join( $sql ) { - global $wpdb; - - if ( ! strstr( $sql, 'wc_product_meta_lookup' ) ) { - $sql .= " LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON $wpdb->posts.ID = wc_product_meta_lookup.product_id "; - } - return $sql; - } - - /** - * Make extra product orderby features supported by WooCommerce available to the WC API. - * This includes 'price', 'popularity', and 'rating'. - * - * @param \WP_REST_Request $request Request data. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - // Set post_status. - $args['post_status'] = $request['status']; - - // Set custom args to handle later during clauses. - $custom_keys = array( - 'sku', - 'min_price', - 'max_price', - 'stock_status', - 'low_in_stock', - ); - foreach ( $custom_keys as $key ) { - if ( ! empty( $request[ $key ] ) ) { - $args[ $key ] = $request[ $key ]; - } - } - - // Taxonomy query to filter products by type, category, - // tag, shipping class, and attribute. - $tax_query = array(); - - // Map between taxonomy name and arg's key. - $taxonomies = array( - 'product_cat' => 'category', - 'product_tag' => 'tag', - 'product_shipping_class' => 'shipping_class', - ); - - // Set tax_query for each passed arg. - foreach ( $taxonomies as $taxonomy => $key ) { - if ( ! empty( $request[ $key ] ) ) { - $tax_query[] = array( - 'taxonomy' => $taxonomy, - 'field' => 'term_id', - 'terms' => $request[ $key ], - ); - } - } - - // Filter product type by slug. - if ( ! empty( $request['type'] ) ) { - $tax_query[] = array( - 'taxonomy' => 'product_type', - 'field' => 'slug', - 'terms' => $request['type'], - ); - } - - // Filter by attribute and term. - if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { - if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { - $tax_query[] = array( - 'taxonomy' => $request['attribute'], - 'field' => 'term_id', - 'terms' => $request['attribute_term'], - ); - } - } - - // Build tax_query if taxonomies are set. - if ( ! empty( $tax_query ) ) { - if ( ! empty( $args['tax_query'] ) ) { - $args['tax_query'] = array_merge( $tax_query, $args['tax_query'] ); // WPCS: slow query ok. - } else { - $args['tax_query'] = $tax_query; // WPCS: slow query ok. - } - } - - // Filter featured. - if ( is_bool( $request['featured'] ) ) { - $args['tax_query'][] = array( - 'taxonomy' => 'product_visibility', - 'field' => 'name', - 'terms' => 'featured', - 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', - ); - } - - // Filter by tax class. - if ( ! empty( $request['tax_class'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_tax_class', - 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', - ) - ); - } - - // Filter by on sale products. - if ( is_bool( $request['on_sale'] ) ) { - $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; - $on_sale_ids = wc_get_product_ids_on_sale(); - - // Use 0 when there's no on sale products to avoid return all products. - $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; - - $args[ $on_sale_key ] += $on_sale_ids; - } - - // Force the post_type argument, since it's not a user input variable. - if ( ! empty( $request['sku'] ) ) { - $args['post_type'] = array( 'product', 'product_variation' ); - } else { - $args['post_type'] = $this->post_type; - } - - $orderby = $request->get_param( 'orderby' ); - $order = $request->get_param( 'order' ); - - $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); - $args['orderby'] = $ordering_args['orderby']; - $args['order'] = $ordering_args['order']; - if ( $ordering_args['meta_key'] ) { - $args['meta_key'] = $ordering_args['meta_key']; // WPCS: slow query ok. - } - - return $args; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), // @codingStandardsIgnoreLine. - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), // @codingStandardsIgnoreLine. - ), - ); - - if ( $item->get_parent_id() ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $item->get_parent_id() ) ), // @codingStandardsIgnoreLine. - ); - } - - return $links; - } - - /** - * Delete a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * - * @return \WP_REST_Response|\WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = (bool) $request['force']; - $object = $this->get_object( (int) $request['id'] ); - $result = false; - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( - "woocommerce_rest_{$this->post_type}_invalid_id", - __( 'Invalid ID.', 'woocommerce-rest-api' ), - array( - 'status' => 404, - ) - ); - } - - if ( 'variation' === $object->get_type() ) { - return new \WP_Error( - "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), - array( - 'status' => 404, - ) - ); - } - - $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); - - /** - * Filter whether an object is trashable. - * - * Return false to disable trash support for the object. - * - * @param boolean $supports_trash Whether the object type support trashing. - * @param \WC_Data $object The object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - - if ( ! Permissions::user_can_delete( $this->post_type, $object->get_id() ) ) { - return new \WP_Error( - "woocommerce_rest_user_cannot_delete_{$this->post_type}", - /* translators: %s: post type */ - sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), - array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - $request->set_param( 'context', 'edit' ); - - // If we're forcing, then delete permanently. - if ( $force ) { - $previous = $this->prepare_item_for_response( $object, $request ); - - $object->delete( true ); - $result = 0 === $object->get_id(); - - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - return new \WP_Error( - 'woocommerce_rest_trash_not_supported', - /* translators: %s: post type */ - sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), - array( - 'status' => 501, - ) - ); - } - - // Otherwise, only trash if we haven't already. - if ( is_callable( array( $object, 'get_status' ) ) ) { - if ( 'trash' === $object->get_status() ) { - return new \WP_Error( - 'woocommerce_rest_already_trashed', - /* translators: %s: post type */ - sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), - array( - 'status' => 410, - ) - ); - } - - $object->delete(); - $result = 'trash' === $object->get_status(); - } - - $response = $this->prepare_item_for_response( $object, $request ); - } - - if ( ! $result ) { - return new \WP_Error( - 'woocommerce_rest_cannot_delete', - /* translators: %s: post type */ - sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), - array( - 'status' => 500, - ) - ); - } - - /** - * Fires after a single object is deleted or trashed via the REST API. - * - * @param \WC_Data $object The deleted or trashed object. - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); - - return $response; - } -} diff --git a/src/Controllers/Version4/Requests/AbstractObjectRequest.php b/src/Controllers/Version4/Requests/AbstractObjectRequest.php deleted file mode 100644 index 660040e8a87..00000000000 --- a/src/Controllers/Version4/Requests/AbstractObjectRequest.php +++ /dev/null @@ -1,64 +0,0 @@ -request = (array) $request->get_params(); - } - - /** - * Get param from request. - * - * @param string $name Param name. - * @param mixed $default Default to return if not set. - */ - protected function get_param( $name, $default = null ) { - return isset( $this->request[ $name ] ) ? $this->request[ $name ] : $default; - } - - /** - * Convert request to object. - * - * @throws \WC_REST_Exception Will throw an exception if the resulting product object is invalid. - */ - abstract public function prepare_object(); - - /** - * Set meta data. - * - * @param mixed $object Product object reference. - */ - protected function set_meta_data( &$object ) { - $meta_data = $this->get_param( 'meta_data', null ); - - if ( ! is_null( $meta_data ) ) { - foreach ( $meta_data as $meta ) { - $object->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - } -} diff --git a/src/Controllers/Version4/Requests/CustomerRequest.php b/src/Controllers/Version4/Requests/CustomerRequest.php deleted file mode 100644 index eee26f94961..00000000000 --- a/src/Controllers/Version4/Requests/CustomerRequest.php +++ /dev/null @@ -1,105 +0,0 @@ -get_param( 'id', 0 ); - $object = new \WC_Customer( $id ); - - if ( $id !== $object->get_id() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), 400 ); - } - - $this->set_props( $object ); - $this->set_meta_data( $object ); - - return $object; - } - - /** - * Set order props. - * - * @throws \WC_REST_Exception Will throw an exception if the customer is invalid. - * @param \WC_Customer $object Order object reference. - */ - protected function set_props( &$object ) { - $props = [ - 'username', - 'password', - 'email', - 'first_name', - 'last_name', - 'billing', - 'shipping', - 'billing', - 'shipping', - ]; - - $request_props = array_intersect_key( $this->request, array_flip( $props ) ); - $prop_values = []; - - foreach ( $request_props as $prop => $value ) { - switch ( $prop ) { - case 'email': - if ( email_exists( $value ) && $value !== $object->get_email() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce-rest-api' ), 400 ); - } - $prop_values[ $prop ] = $value; - break; - case 'username': - if ( $object->get_id() && $value !== $object->get_username() ) { - throw new \WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce-rest-api' ), 400 ); - } - $prop_values[ $prop ] = $value; - break; - case 'billing': - case 'shipping': - $address = $this->parse_address_field( $value, $object, $prop ); - $prop_values = array_merge( $prop_values, $address ); - break; - default: - $prop_values[ $prop ] = $value; - } - } - - foreach ( $prop_values as $prop => $value ) { - $object->{"set_$prop"}( $value ); - } - } - - /** - * Parse address data. - * - * @param array $data Posted data. - * @param \WC_Customer $object Customer object. - * @param string $type Address type. - * @return array - */ - protected function parse_address_field( $data, $object, $type = 'billing' ) { - $address = []; - foreach ( $data as $key => $value ) { - if ( is_callable( array( $object, "set_{$type}_{$key}" ) ) ) { - $address[ "{$type}_{$key}" ] = $value; - } - } - return $address; - } -} diff --git a/src/Controllers/Version4/Requests/OrderRequest.php b/src/Controllers/Version4/Requests/OrderRequest.php deleted file mode 100644 index 2e8109702f7..00000000000 --- a/src/Controllers/Version4/Requests/OrderRequest.php +++ /dev/null @@ -1,387 +0,0 @@ -get_param( 'id', 0 ); - $object = new \WC_Order( $id ); - - $this->set_props( $object ); - $this->set_meta_data( $object ); - $this->set_line_items( $object ); - $this->calculate_coupons( $object ); - - return $object; - } - - /** - * Set order props. - * - * @param \WC_Order $object Order object reference. - */ - protected function set_props( &$object ) { - $props = [ - 'parent_id', - 'currency', - 'customer_id', - 'customer_note', - 'payment_method', - 'payment_method_title', - 'transaction_id', - 'billing', - 'shipping', - 'status', - ]; - - $request_props = array_intersect_key( $this->request, array_flip( $props ) ); - $prop_values = []; - - foreach ( $request_props as $prop => $value ) { - switch ( $prop ) { - case 'customer_id': - $prop_values[ $prop ] = $this->parse_customer_id_field( $value ); - break; - case 'billing': - case 'shipping': - $address = $this->parse_address_field( $value, $object, $prop ); - $prop_values = array_merge( $prop_values, $address ); - break; - default: - $prop_values[ $prop ] = $value; - } - } - - foreach ( $prop_values as $prop => $value ) { - $object->{"set_$prop"}( $value ); - } - } - - /** - * Set order line items. - * - * @param \WC_Order $object Order object reference. - */ - protected function set_line_items( &$object ) { - $types = [ - 'line_items', - 'shipping_lines', - 'fee_lines', - ]; - - foreach ( $types as $type ) { - if ( ! isset( $this->request[ $type ] ) || ! is_array( $this->request[ $type ] ) ) { - continue; - } - $items = $this->request[ $type ]; - - foreach ( $items as $item ) { - if ( ! is_array( $item ) ) { - continue; - } - if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { - $object->remove_item( $item['id'] ); - } else { - $this->set_item( $object, $type, $item ); - } - } - } - } - - /** - * Helper method to check if the resource ID associated with the provided item is null. - * Items can be deleted by setting the resource ID to null. - * - * @param array $item Item provided in the request body. - * @return bool True if the item resource ID is null, false otherwise. - */ - protected function item_is_null( $item ) { - $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); - - foreach ( $keys as $key ) { - if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { - return true; - } - } - - return false; - } - - /** - * Maybe set an item prop if the value was posted. - * - * @param \WC_Order_Item $item Order item. - * @param string $prop Order property. - * @param array $posted Request data. - */ - protected function maybe_set_item_prop( $item, $prop, $posted ) { - if ( isset( $posted[ $prop ] ) ) { - $item->{"set_$prop"}( $posted[ $prop ] ); - } - } - - /** - * Maybe set item props if the values were posted. - * - * @param \WC_Order_Item $item Order item data. - * @param string[] $props Properties. - * @param array $posted Request data. - */ - protected function maybe_set_item_props( $item, $props, $posted ) { - foreach ( $props as $prop ) { - $this->maybe_set_item_prop( $item, $prop, $posted ); - } - } - - /** - * Maybe set item meta if posted. - * - * @param \WC_Order_Item $item Order item data. - * @param array $posted Request data. - */ - protected function maybe_set_item_meta_data( $item, $posted ) { - if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { - foreach ( $posted['meta_data'] as $meta ) { - if ( isset( $meta['key'] ) ) { - $value = isset( $meta['value'] ) ? $meta['value'] : null; - $item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - } - } - - /** - * Gets the product ID from the SKU or posted ID. - * - * @param array $posted Request data. - * @return int - * @throws \WC_REST_Exception When SKU or ID is not valid. - */ - protected function get_product_id_from_line_item( $posted ) { - if ( ! empty( $posted['sku'] ) ) { - $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); - } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { - $product_id = (int) $posted['product_id']; - } elseif ( ! empty( $posted['variation_id'] ) ) { - $product_id = (int) $posted['variation_id']; - } else { - throw new \WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); - } - return $product_id; - } - - /** - * Create or update a line item. - * - * @param array $posted Line item data. - * @param string $action 'create' to add line item or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return \WC_Order_Item_Product - * @throws \WC_REST_Exception Invalid data, server error. - */ - protected function prepare_line_items( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new \WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - $product = wc_get_product( $this->get_product_id_from_line_item( $posted ) ); - - if ( $product !== $item->get_product() ) { - $item->set_product( $product ); - - if ( 'create' === $action ) { - $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; - $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); - $item->set_total( $total ); - $item->set_subtotal( $total ); - } - } - - $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Create or update an order shipping method. - * - * @param array $posted $shipping Item data. - * @param string $action 'create' to add shipping or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return \WC_Order_Item_Shipping - * @throws \WC_REST_Exception Invalid data, server error. - */ - protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new \WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - - if ( 'create' === $action ) { - if ( empty( $posted['method_id'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce-rest-api' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Create or update an order fee. - * - * @param array $posted Item data. - * @param string $action 'create' to add fee or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return \WC_Order_Item_Fee - * @throws \WC_REST_Exception Invalid data, server error. - */ - protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new \WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - - if ( 'create' === $action ) { - if ( empty( $posted['name'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce-rest-api' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Wrapper method to create/update order items. - * When updating, the item ID provided is checked to ensure it is associated - * with the order. - * - * @param \WC_Order $order order object. - * @param string $item_type The item type. - * @param array $posted item provided in the request body. - * @throws \WC_REST_Exception If item ID is not associated with order. - */ - protected function set_item( &$order, $item_type, $posted ) { - if ( ! empty( $posted['id'] ) ) { - $action = 'update'; - } else { - $action = 'create'; - } - - $method = 'prepare_' . $item_type; - $item = null; - - // Verify provided line item ID is associated with order. - if ( 'update' === $action ) { - $item = $order->get_item( absint( $posted['id'] ), false ); - - if ( ! $item ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce-rest-api' ), 400 ); - } - } - - // Prepare item data. - $item = $this->$method( $posted, $action, $item ); - - do_action( 'woocommerce_rest_set_order_item', $item, $posted ); - - // If creating the order, add the item to it. - if ( 'create' === $action ) { - $order->add_item( $item ); - } else { - $item->save(); - } - } - - /** - * Parse address data. - * - * @param array $data Posted data. - * @param \WC_Order $object Order object reference. - * @param string $type Address type. - * @return array - */ - protected function parse_address_field( $data, $object, $type = 'billing' ) { - $address = []; - foreach ( $data as $key => $value ) { - if ( is_callable( array( $object, "set_{$type}_{$key}" ) ) ) { - $address[ "{$type}_{$key}" ] = $value; - } - } - return $address; - } - - /** - * Parse customer ID. - * - * @throws \WC_REST_Exception Will throw an exception if the customer is invalid. - * @param int $customer_id Customer ID to set. - * @return int - */ - protected function parse_customer_id_field( $customer_id ) { - if ( 0 !== $customer_id ) { - // Make sure customer exists. - if ( false === get_user_by( 'id', $customer_id ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); - } - - // Make sure customer is part of blog. - if ( is_multisite() && ! is_user_member_of_blog( $customer_id ) ) { - add_user_to_blog( get_current_blog_id(), $customer_id, 'customer' ); - } - } - return $customer_id; - } - - /** - * Calculate coupons. - * - * @throws \WC_REST_Exception When fails to set any item. - * - * @param \WC_Order $order Order data. - * @return bool - */ - protected function calculate_coupons( &$order ) { - $coupon_lines = $this->get_param( 'coupon_lines', false ); - - if ( ! is_array( $coupon_lines ) ) { - return false; - } - - // Remove all coupons first to ensure calculation is correct. - foreach ( $order->get_items( 'coupon' ) as $coupon ) { - $order->remove_coupon( $coupon->get_code() ); - } - - foreach ( $coupon_lines as $item ) { - if ( is_array( $item ) ) { - if ( empty( $item['id'] ) ) { - if ( empty( $item['code'] ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); - } - - $results = $order->apply_coupon( wc_clean( $item['code'] ) ); - - if ( is_wp_error( $results ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); - } - } - } - } - - return true; - } -} diff --git a/src/Controllers/Version4/Requests/ProductRequest.php b/src/Controllers/Version4/Requests/ProductRequest.php deleted file mode 100644 index 4187677a22c..00000000000 --- a/src/Controllers/Version4/Requests/ProductRequest.php +++ /dev/null @@ -1,440 +0,0 @@ -get_product_object(); - - $this->set_common_props( $object ); - $this->set_meta_data( $object ); - - switch ( $object->get_type() ) { - case 'grouped': - $this->set_grouped_props( $object ); - break; - case 'variable': - $this->set_variable_props( $object ); - break; - case 'external': - $this->set_external_props( $object ); - break; - } - - if ( $object->get_downloadable() ) { - $this->set_downloadable_props( $object ); - } - - return $object; - } - - /** - * Get product object from request args. - * - * @throws \WC_REST_Exception Will throw an exception if the resulting product object is invalid. - * @return \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External - */ - protected function get_product_object() { - $id = (int) $this->get_param( 'id', 0 ); - $type = $this->get_param( 'type', '' ); - - if ( $type ) { - $classname = \WC_Product_Factory::get_classname_from_product_type( $type ); - if ( $classname && class_exists( '\\' . $classname ) ) { - $classname = '\\' . $classname; - } else { - $classname = '\WC_Product_Simple'; - } - $object = new $classname( $id ); - } elseif ( $id ) { - $object = wc_get_product( $id ); - } else { - $object = new \WC_Product_Simple(); - } - - if ( ! $object ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_product_id', __( 'Invalid product.', 'woocommerce-rest-api' ), 404 ); - } - - if ( $object->is_type( 'variation' ) ) { - throw new \WC_REST_Exception( 'woocommerce_rest_invalid_product_id', __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), 404 ); - } - - return $object; - } - - /** - * Set common product props. - * - * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object reference. - */ - protected function set_common_props( &$object ) { - $props = [ - 'name', - 'sku', - 'description', - 'short_description', - 'slug', - 'menu_order', - 'reviews_allowed', - 'virtual', - 'tax_status', - 'tax_class', - 'catalog_visibility', - 'purchase_note', - 'status', - 'featured', - 'regular_price', - 'sale_price', - 'date_on_sale_from', - 'date_on_sale_from_gmt', - 'date_on_sale_to', - 'date_on_sale_to_gmt', - 'parent_id', - 'sold_individually', - 'manage_stock', - 'backorders', - 'stock_status', - 'stock_quantity', - 'downloadable', - 'date_created', - 'date_created_gmt', - 'upsell_ids', - 'cross_sell_ids', - 'images', - 'categories', - 'tags', - 'attributes', - 'weight', - 'dimensions', - 'shipping_class', - ]; - - $request_props = array_intersect_key( $this->request, array_flip( $props ) ); - $prop_values = []; - - foreach ( $request_props as $prop => $value ) { - switch ( $prop ) { - case 'date_created': - case 'date_created_gmt': - $prop_values[ $prop ] = rest_parse_date( $value ); - break; - case 'upsell_ids': - case 'cross_sell_ids': - $prop_values[ $prop ] = wp_parse_id_list( $value ); - break; - case 'images': - $images = $this->parse_images_field( $value, $object ); - $prop_values = array_merge( $prop_values, $images ); - break; - case 'categories': - $prop_values['category_ids'] = wp_list_pluck( $value, 'id' ); - break; - case 'tags': - $prop_values['tag_ids'] = wp_list_pluck( $value, 'id' ); - break; - case 'attributes': - $prop_values['attributes'] = $this->parse_attributes_field( $value ); - break; - case 'dimensions': - $dimensions = $this->parse_dimensions_fields( $value ); - $prop_values = array_merge( $prop_values, $dimensions ); - break; - case 'shipping_class': - $prop_values['shipping_class_id'] = $this->parse_shipping_class( $value, $object ); - break; - default: - $prop_values[ $prop ] = $value; - } - } - - foreach ( $prop_values as $prop => $value ) { - $object->{"set_$prop"}( $value ); - } - } - - /** - * Set grouped product props. - * - * @param \WC_Product_Grouped $object Product object reference. - */ - protected function set_grouped_props( &$object ) { - $children = $this->get_param( 'grouped_products', null ); - - if ( ! is_null( $children ) ) { - $object->set_children( $children ); - } - } - - /** - * Set variable product props. - * - * @param \WC_Product_Variable $object Product object reference. - */ - protected function set_variable_props( &$object ) { - $default_attributes = $this->get_param( 'default_attributes', null ); - - if ( ! is_null( $default_attributes ) ) { - $object->set_default_attributes( $this->parse_default_attributes( $default_attributes, $object ) ); - } - } - - /** - * Set external product props. - * - * @param \WC_Product_External $object Product object reference. - */ - protected function set_external_props( &$object ) { - $button_text = $this->get_param( 'button_text', null ); - $external_url = $this->get_param( 'external_url', null ); - - if ( ! is_null( $button_text ) ) { - $object->set_button_text( $button_text ); - } - - if ( ! is_null( $external_url ) ) { - $object->set_product_url( $external_url ); - } - } - - /** - * Set downloadable product props. - * - * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object reference. - */ - protected function set_downloadable_props( &$object ) { - $download_limit = $this->get_param( 'download_limit', null ); - $download_expiry = $this->get_param( 'download_expiry', null ); - $downloads = $this->get_param( 'downloads', null ); - - if ( ! is_null( $download_limit ) ) { - $object->set_download_limit( $download_limit ); - } - - if ( ! is_null( $download_expiry ) ) { - $object->set_download_expiry( $download_expiry ); - } - - if ( ! is_null( $downloads ) ) { - $object->set_downloads( $this->parse_downloads_field( $downloads ) ); - } - } - - /** - * Set product object's attributes. - * - * @param array $raw_attributes Attribute data from request. - * @return array - */ - protected function parse_attributes_field( $raw_attributes ) { - $attributes = array(); - - foreach ( $raw_attributes as $attribute ) { - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_id = 0; - $attribute_name = wc_clean( $attribute['name'] ); - } - - if ( ! $attribute_name || ! isset( $attribute['options'] ) ) { - continue; - } - - if ( ! is_array( $attribute['options'] ) ) { - $attribute['options'] = explode( \WC_DELIMITER, $attribute['options'] ); - } - - if ( $attribute_id ) { - $attribute['options'] = array_filter( array_map( 'wc_sanitize_term_text_based', $attribute['options'] ), 'strlen' ); - } - - $attribute_object = new \WC_Product_Attribute(); - $attribute_object->set_id( $attribute_id ); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $attribute['options'] ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ! empty( $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ! empty( $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - return $attributes; - } - - /** - * Set product images. - * - * @throws \WC_REST_Exception REST API exceptions. - * @param array $images Images data. - * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object. - * @return array - */ - protected function parse_images_field( $images, $object ) { - $response = [ - 'image_id' => '', - 'gallery_image_ids' => [], - ]; - - $images = is_array( $images ) ? array_filter( $images ) : []; - - if ( empty( $images ) ) { - return $response; - } - - foreach ( $images as $index => $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - $attachment = new ImageAttachment( $attachment_id, $object->get_id() ); - - if ( 0 === $attachment->id && ! empty( $image['src'] ) ) { - $attachment->upload_image_from_src( $image['src'] ); - } - - if ( ! empty( $image['alt'] ) ) { - $attachment->update_alt_text( $image['alt'] ); - } - - if ( ! empty( $image['name'] ) ) { - $attachment->update_name( $image['name'] ); - } - - if ( 0 === $index ) { - $response['image_id'] = $attachment->id; - } else { - $response['gallery_image_ids'][] = $attachment->id; - } - } - - return $response; - } - - /** - * Parse dimensions. - * - * @param array $dimensions Product dimensions. - * @return array - */ - protected function parse_dimensions_fields( $dimensions ) { - $response = []; - - if ( isset( $dimensions['length'] ) ) { - $response['length'] = $dimensions['length']; - } - - if ( isset( $dimensions['width'] ) ) { - $response['width'] = $dimensions['width']; - } - - if ( isset( $dimensions['height'] ) ) { - $response['height'] = $dimensions['height']; - } - - return $response; - } - - /** - * Parse shipping class. - * - * @param string $shipping_class Shipping class slug. - * @param \WC_Product_Simple|\WC_Product_Grouped|\WC_Product_Variable|\WC_Product_External $object Product object. - * @return int - */ - protected function parse_shipping_class( $shipping_class, $object ) { - $data_store = $object->get_data_store(); - return $data_store->get_shipping_class_id_by_slug( wc_clean( $shipping_class ) ); - } - - /** - * Parse downloadable files. - * - * @param array $downloads Downloads data. - * @return array - */ - protected function parse_downloads_field( $downloads ) { - $files = array(); - foreach ( $downloads as $key => $file ) { - if ( empty( $file['file'] ) ) { - continue; - } - - $download = new \WC_Product_Download(); - $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); - $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); - $download->set_file( $file['file'] ); - $files[] = $download; - } - return $files; - } - - /** - * Save default attributes. - * - * @param array $raw_default_attributes Default attributes. - * @param \WC_Product_Variable $object Product object reference. - * @return array - */ - protected function parse_default_attributes( $raw_default_attributes, $object ) { - $attributes = $object->get_attributes(); - $default_attributes = array(); - - foreach ( $raw_default_attributes as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( isset( $attributes[ $attribute_name ] ) ) { - $_attribute = $attributes[ $attribute_name ]; - - if ( $_attribute['is_variation'] ) { - $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( ! empty( $_attribute['is_taxonomy'] ) ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $value = $term->slug; - } else { - $value = sanitize_title( $value ); - } - } - - if ( $value ) { - $default_attributes[ $attribute_name ] = $value; - } - } - } - } - - return $default_attributes; - } -} diff --git a/src/Controllers/Version4/Requests/ProductVariationRequest.php b/src/Controllers/Version4/Requests/ProductVariationRequest.php deleted file mode 100644 index 69059c66a6b..00000000000 --- a/src/Controllers/Version4/Requests/ProductVariationRequest.php +++ /dev/null @@ -1,188 +0,0 @@ -get_param( 'id', 0 ); - $object = new \WC_Product_Variation( $id ); - $object->set_parent_id( (int) $this->get_param( 'product_id', 0 ) ); - $parent = wc_get_product( $object->get_parent_id() ); - - if ( ! $parent ) { - throw new \WC_REST_Exception( 'woocommerce_rest_product_variation_invalid_parent', __( 'Invalid parent product.', 'woocommerce-rest-api' ), 404 ); - } - - $this->set_common_props( $object ); - $this->set_meta_data( $object ); - - if ( $object->get_downloadable() ) { - $this->set_downloadable_props( $object ); - } - - return $object; - } - - /** - * Set common product props. - * - * @param \WC_Product_Variation $object Product object reference. - */ - protected function set_common_props( &$object ) { - $props = [ - 'status', - 'sku', - 'virtual', - 'downloadable', - 'download_limit', - 'download_expiry', - 'manage_stock', - 'stock_status', - 'backorders', - 'regular_price', - 'sale_price', - 'date_on_sale_from', - 'date_on_sale_from_gmt', - 'date_on_sale_to', - 'date_on_sale_to_gmt', - 'tax_class', - 'description', - 'menu_order', - 'stock_quantity', - 'image', - 'downloads', - 'attributes', - 'weight', - 'dimensions', - 'shipping_class', - ]; - - $request_props = array_intersect_key( $this->request, array_flip( $props ) ); - $prop_values = []; - - foreach ( $request_props as $prop => $value ) { - switch ( $prop ) { - case 'image': - $prop_values['image_id'] = $this->parse_image_field( $value, $object ); - break; - case 'attributes': - $prop_values['attributes'] = $this->parse_attributes_field( $value, $object ); - break; - case 'dimensions': - $dimensions = $this->parse_dimensions_fields( $value ); - $prop_values = array_merge( $prop_values, $dimensions ); - break; - case 'shipping_class': - $prop_values['shipping_class_id'] = $this->parse_shipping_class( $value, $object ); - break; - default: - $prop_values[ $prop ] = $value; - } - } - - foreach ( $prop_values as $prop => $value ) { - $object->{"set_$prop"}( $value ); - } - } - - /** - * Set product object's attributes. - * - * @param array $raw_attributes Attribute data from request. - * @param \WC_Product_Variation $object Product object. - */ - protected function parse_attributes_field( $raw_attributes, $object = null ) { - $attributes = array(); - $parent = wc_get_product( $object->get_parent_id() ); - $parent_attributes = $parent->get_attributes(); - - foreach ( $raw_attributes as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { - continue; - } - - $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); - $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $attribute_value = $term->slug; - } else { - $attribute_value = sanitize_title( $attribute_value ); - } - } - - $attributes[ $attribute_key ] = $attribute_value; - } - - return $attributes; - } - - /** - * Set product images. - * - * @throws \WC_REST_Exception REST API exceptions. - * @param array $image Image data. - * @param \WC_Product_Variation $object Product object. - * @return array - */ - protected function parse_image_field( $image, $object ) { - if ( empty( $image ) ) { - return ''; - } - - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - $attachment = new ImageAttachment( $attachment_id, $object->get_id() ); - - if ( 0 === $attachment->id && ! empty( $image['src'] ) ) { - $attachment->upload_image_from_src( $image['src'] ); - } - - if ( ! empty( $image['alt'] ) ) { - $attachment->update_alt_text( $image['alt'] ); - } - - if ( ! empty( $image['name'] ) ) { - $attachment->update_name( $image['name'] ); - } - - return $attachment->id; - } -} diff --git a/src/Controllers/Version4/Responses/AbstractObjectResponse.php b/src/Controllers/Version4/Responses/AbstractObjectResponse.php deleted file mode 100644 index e92882f7682..00000000000 --- a/src/Controllers/Version4/Responses/AbstractObjectResponse.php +++ /dev/null @@ -1,25 +0,0 @@ -get_data(); - $format_date = array( 'date_created', 'date_modified' ); - - // Format date values. - foreach ( $format_date as $key ) { - // Date created is stored UTC, date modified is stored WP local time. - $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - return array( - 'id' => $object->get_id(), - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => $data['email'], - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'role' => $data['role'], - 'username' => $data['username'], - 'billing' => $data['billing'], - 'shipping' => $data['shipping'], - 'is_paying_customer' => $data['is_paying_customer'], - 'avatar_url' => $object->get_avatar_url(), - 'meta_data' => $data['meta_data'], - ); - } -} diff --git a/src/Controllers/Version4/Responses/OrderResponse.php b/src/Controllers/Version4/Responses/OrderResponse.php deleted file mode 100644 index 8ccdbf4fbf9..00000000000 --- a/src/Controllers/Version4/Responses/OrderResponse.php +++ /dev/null @@ -1,183 +0,0 @@ -dp = wc_get_price_decimals(); - } - - /** - * Set decimal places. - * - * @param int $dp Decimals. - */ - public function set_dp( $dp ) { - $this->dp = (int) $dp; - } - - /** - * Convert object to match data in the schema. - * - * @param \WC_Order $object Product data. - * @param string $context Request context. Options: 'view' and 'edit'. - * @return array - */ - public function prepare_response( $object, $context ) { - $data = $object->get_data(); - $format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' ); - $format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' ); - $format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->dp ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $datetime = $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - // Format the order status. - $data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status']; - - // Format line items. - foreach ( $format_line_items as $key ) { - $data[ $key ] = array_values( array_map( array( $this, 'prepare_order_item_data' ), $data[ $key ] ) ); - } - - // Refunds. - $data['refunds'] = array(); - foreach ( $object->get_refunds() as $refund ) { - $data['refunds'][] = array( - 'id' => $refund->get_id(), - 'reason' => $refund->get_reason() ? $refund->get_reason() : '', - 'total' => '-' . wc_format_decimal( $refund->get_amount(), $this->dp ), - ); - } - - // Currency symbols. - $currency_symbol = get_woocommerce_currency_symbol( $data['currency'] ); - $data['currency_symbol'] = html_entity_decode( $currency_symbol ); - - return array( - 'id' => $object->get_id(), - 'parent_id' => $data['parent_id'], - 'number' => $data['number'], - 'order_key' => $data['order_key'], - 'created_via' => $data['created_via'], - 'version' => $data['version'], - 'status' => $data['status'], - 'currency' => $data['currency'], - 'currency_symbol' => $data['currency_symbol'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'discount_total' => $data['discount_total'], - 'discount_tax' => $data['discount_tax'], - 'shipping_total' => $data['shipping_total'], - 'shipping_tax' => $data['shipping_tax'], - 'cart_tax' => $data['cart_tax'], - 'total' => $data['total'], - 'total_tax' => $data['total_tax'], - 'prices_include_tax' => $data['prices_include_tax'], - 'customer_id' => $data['customer_id'], - 'customer_ip_address' => $data['customer_ip_address'], - 'customer_user_agent' => $data['customer_user_agent'], - 'customer_note' => $data['customer_note'], - 'billing' => $data['billing'], - 'shipping' => $data['shipping'], - 'payment_method' => $data['payment_method'], - 'payment_method_title' => $data['payment_method_title'], - 'transaction_id' => $data['transaction_id'], - 'date_paid' => $data['date_paid'], - 'date_paid_gmt' => $data['date_paid_gmt'], - 'date_completed' => $data['date_completed'], - 'date_completed_gmt' => $data['date_completed_gmt'], - 'cart_hash' => $data['cart_hash'], - 'meta_data' => $data['meta_data'], - 'line_items' => $data['line_items'], - 'tax_lines' => $data['tax_lines'], - 'shipping_lines' => $data['shipping_lines'], - 'fee_lines' => $data['fee_lines'], - 'coupon_lines' => $data['coupon_lines'], - 'refunds' => $data['refunds'], - ); - } - - /** - * Expands an order item to get its data. - * - * @param \WC_Order_item $item Order item data. - * @return array - */ - protected function prepare_order_item_data( $item ) { - $data = $item->get_data(); - $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - if ( isset( $data[ $key ] ) ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->dp ); - } - } - - // Add SKU and PRICE to products. - if ( is_callable( array( $item, 'get_product' ) ) ) { - $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; - $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; - } - - // Format taxes. - if ( ! empty( $data['taxes']['total'] ) ) { - $taxes = array(); - - foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { - $taxes[] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', - ); - } - $data['taxes'] = $taxes; - } elseif ( isset( $data['taxes'] ) ) { - $data['taxes'] = array(); - } - - // Remove names for coupons, taxes and shipping. - if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { - unset( $data['name'] ); - } - - // Remove props we don't want to expose. - unset( $data['order_id'] ); - unset( $data['type'] ); - - return $data; - } -} diff --git a/src/Controllers/Version4/Responses/ProductResponse.php b/src/Controllers/Version4/Responses/ProductResponse.php deleted file mode 100644 index fc6839387a8..00000000000 --- a/src/Controllers/Version4/Responses/ProductResponse.php +++ /dev/null @@ -1,354 +0,0 @@ - $object->get_id(), - 'name' => $object->get_name( $context ), - 'slug' => $object->get_slug( $context ), - 'permalink' => $object->get_permalink(), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created( $context ), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created( $context ) ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified( $context ), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified( $context ) ), - 'type' => $object->get_type(), - 'status' => $object->get_status( $context ), - 'featured' => $object->is_featured(), - 'catalog_visibility' => $object->get_catalog_visibility( $context ), - 'description' => $object->get_description( $context ), - 'short_description' => $object->get_short_description( $context ), - 'sku' => $object->get_sku( $context ), - 'price' => $object->get_price( $context ), - 'regular_price' => $object->get_regular_price( $context ), - 'sale_price' => $object->get_sale_price( $context ) ? $object->get_sale_price( $context ) : '', - 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from( $context ) ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to( $context ) ), - 'price_html' => $object->get_price_html(), - 'on_sale' => $object->is_on_sale( $context ), - 'purchasable' => $object->is_purchasable(), - 'total_sales' => $object->get_total_sales( $context ), - 'virtual' => $object->is_virtual(), - 'downloadable' => $object->is_downloadable(), - 'downloads' => $this->prepare_downloads( $object ), - 'download_limit' => $object->get_download_limit( $context ), - 'download_expiry' => $object->get_download_expiry( $context ), - 'external_url' => '', - 'button_text' => '', - 'tax_status' => $object->get_tax_status( $context ), - 'tax_class' => $object->get_tax_class( $context ), - 'manage_stock' => $object->managing_stock(), - 'stock_quantity' => $object->get_stock_quantity( $context ), - 'stock_status' => $object->get_stock_status( $context ), - 'backorders' => $object->get_backorders( $context ), - 'backorders_allowed' => $object->backorders_allowed(), - 'backordered' => $object->is_on_backorder(), - 'sold_individually' => $object->is_sold_individually(), - 'weight' => $object->get_weight( $context ), - 'dimensions' => array( - 'length' => $object->get_length( $context ), - 'width' => $object->get_width( $context ), - 'height' => $object->get_height( $context ), - ), - 'shipping_required' => $object->needs_shipping(), - 'shipping_taxable' => $object->is_shipping_taxable(), - 'shipping_class' => $object->get_shipping_class(), - 'shipping_class_id' => $object->get_shipping_class_id( $context ), - 'reviews_allowed' => $object->get_reviews_allowed( $context ), - 'average_rating' => $object->get_average_rating( $context ), - 'rating_count' => $object->get_rating_count(), - 'related_ids' => wp_parse_id_list( wc_get_related_products( $object->get_id() ) ), - 'upsell_ids' => wp_parse_id_list( $object->get_upsell_ids( $context ) ), - 'cross_sell_ids' => wp_parse_id_list( $object->get_cross_sell_ids( $context ) ), - 'parent_id' => $object->get_parent_id( $context ), - 'purchase_note' => $object->get_purchase_note( $context ), - 'categories' => $this->prepare_taxonomy_terms( $object ), - 'tags' => $this->prepare_taxonomy_terms( $object, 'tag' ), - 'images' => $this->prepare_images( $object ), - 'attributes' => $this->prepare_attributes( $object ), - 'default_attributes' => $this->prepare_default_attributes( $object ), - 'variations' => array(), - 'grouped_products' => array(), - 'menu_order' => $object->get_menu_order( $context ), - 'meta_data' => $object->get_meta_data(), - ); - - // Add variations to variable products. - if ( $object->is_type( 'variable' ) ) { - $data['variations'] = $object->get_children(); - } - - // Add grouped products data. - if ( $object->is_type( 'grouped' ) ) { - $data['grouped_products'] = $object->get_children(); - } - - // Add external product data. - if ( $object->is_type( 'external' ) ) { - $data['external_url'] = $object->get_product_url( $context ); - $data['button_text'] = $object->get_button_text( $context ); - } - - if ( 'view' === $context ) { - $data['description'] = wpautop( do_shortcode( $data['description'] ) ); - $data['short_description'] = apply_filters( 'woocommerce_short_description', $data['short_description'] ); - $data['average_rating'] = wc_format_decimal( $data['average_rating'], 2 ); - $data['purchase_note'] = wpautop( do_shortcode( $data['purchase_note'] ) ); - } - - return $data; - } - - /** - * Get the downloads for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $object Product instance. - * - * @return array - */ - protected function prepare_downloads( $object ) { - $downloads = array(); - - if ( $object->is_downloadable() ) { - foreach ( $object->get_downloads() as $file_id => $file ) { - $downloads[] = array( - 'id' => $file_id, // MD5 hash. - 'name' => $file['name'], - 'file' => $file['file'], - ); - } - } - - return $downloads; - } - - /** - * Get taxonomy terms. - * - * @param \WC_Product $object Product instance. - * @param string $taxonomy Taxonomy slug. - * - * @return array - */ - protected function prepare_taxonomy_terms( $object, $taxonomy = 'cat' ) { - $terms = array(); - - foreach ( wc_get_object_terms( $object->get_id(), 'product_' . $taxonomy ) as $term ) { - $terms[] = array( - 'id' => $term->term_id, - 'name' => $term->name, - 'slug' => $term->slug, - ); - } - - return $terms; - } - - /** - * Get the images for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $object Product instance. - * @return array - */ - protected function prepare_images( $object ) { - $images = array(); - $attachment_ids = array(); - - // Add featured image. - if ( $object->get_image_id() ) { - $attachment_ids[] = $object->get_image_id(); - } - - // Add gallery images. - $attachment_ids = array_merge( $attachment_ids, $object->get_gallery_image_ids() ); - - // Build image data. - foreach ( $attachment_ids as $attachment_id ) { - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - continue; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - continue; - } - - $images[] = array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - - return $images; - } - - /** - * Get default attributes. - * - * @param \WC_Product $object Product instance. - * - * @return array - */ - protected function prepare_default_attributes( $object ) { - $default = array(); - - if ( $object->is_type( 'variable' ) ) { - foreach ( array_filter( (array) $object->get_default_attributes(), 'strlen' ) as $key => $value ) { - if ( 0 === strpos( $key, 'pa_' ) ) { - $default[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $key ), - 'name' => $this->get_attribute_taxonomy_name( $key, $object ), - 'option' => $value, - ); - } else { - $default[] = array( - 'id' => 0, - 'name' => $this->get_attribute_taxonomy_name( $key, $object ), - 'option' => $value, - ); - } - } - } - - return $default; - } - - /** - * Get the attributes for a product or product variation. - * - * @param \WC_Product|\WC_Product_Variation $object Product instance. - * - * @return array - */ - protected function prepare_attributes( $object ) { - $attributes = array(); - - if ( $object->is_type( 'variation' ) ) { - $_product = wc_get_product( $object->get_parent_id() ); - foreach ( $object->get_variation_attributes() as $attribute_name => $attribute ) { - $name = str_replace( 'attribute_', '', $attribute_name ); - - if ( empty( $attribute ) && '0' !== $attribute ) { - continue; - } - - // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. - if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { - $option_term = get_term_by( 'slug', $attribute, $name ); - $attributes[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $name ), - 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), - 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, - ); - } else { - $attributes[] = array( - 'id' => 0, - 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), - 'option' => $attribute, - ); - } - } - } else { - foreach ( $object->get_attributes() as $attribute ) { - $attributes[] = array( - 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, - 'name' => $this->get_attribute_taxonomy_name( $attribute['name'], $object ), - 'position' => (int) $attribute['position'], - 'visible' => (bool) $attribute['is_visible'], - 'variation' => (bool) $attribute['is_variation'], - 'options' => $this->get_attribute_options( $object->get_id(), $attribute ), - ); - } - } - - return $attributes; - } - - /** - * Get product attribute taxonomy name. - * - * @param string $slug Taxonomy name. - * @param \WC_Product $object Product data. - * - * @since 3.0.0 - * @return string - */ - protected function get_attribute_taxonomy_name( $slug, $object ) { - // Format slug so it matches attributes of the product. - $slug = wc_attribute_taxonomy_slug( $slug ); - $attributes = $object->get_attributes(); - $attribute = false; - - // pa_ attributes. - if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { - $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; - } elseif ( isset( $attributes[ $slug ] ) ) { - $attribute = $attributes[ $slug ]; - } - - if ( ! $attribute ) { - return $slug; - } - - // Taxonomy attribute name. - if ( $attribute->is_taxonomy() ) { - $taxonomy = $attribute->get_taxonomy_object(); - return $taxonomy->attribute_label; - } - - // Custom product attribute name. - return $attribute->get_name(); - } - - /** - * Get attribute options. - * - * @param int $object_id Product ID. - * @param array $attribute Attribute data. - * - * @return array - */ - protected function get_attribute_options( $object_id, $attribute ) { - if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { - return wc_get_product_terms( - $object_id, - $attribute['name'], - array( - 'fields' => 'names', - ) - ); - } elseif ( isset( $attribute['value'] ) ) { - return array_map( 'trim', explode( '|', $attribute['value'] ) ); - } - - return array(); - } -} diff --git a/src/Controllers/Version4/Responses/ProductReviewResponse.php b/src/Controllers/Version4/Responses/ProductReviewResponse.php deleted file mode 100644 index 63ba58e8761..00000000000 --- a/src/Controllers/Version4/Responses/ProductReviewResponse.php +++ /dev/null @@ -1,71 +0,0 @@ - (int) $object->comment_ID, - 'date_created' => wc_rest_prepare_date_response( $object->comment_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->comment_date_gmt ), - 'product_id' => (int) $object->comment_post_ID, - 'status' => $this->prepare_status_response( (string) $object->comment_approved ), - 'reviewer' => $object->comment_author, - 'reviewer_email' => $object->comment_author_email, - 'review' => $object->comment_content, - 'rating' => (int) get_comment_meta( $object->comment_ID, 'rating', true ), - 'verified' => wc_review_is_from_verified_owner( $object->comment_ID ), - 'reviewer_avatar_urls' => rest_get_avatar_urls( $object->comment_author_email ), - ); - - if ( 'view' === $context ) { - $data['review'] = wpautop( $data['review'] ); - } - - return $data; - } - - /** - * Checks comment_approved to set comment status for single comment output. - * - * @param string|int $comment_approved comment status. - * @return string Comment status. - */ - protected function prepare_status_response( $comment_approved ) { - switch ( $comment_approved ) { - case 'hold': - case '0': - $status = 'hold'; - break; - case 'approve': - case '1': - $status = 'approved'; - break; - case 'spam': - case 'trash': - default: - $status = $comment_approved; - break; - } - - return $status; - } -} diff --git a/src/Controllers/Version4/Responses/ProductVariationResponse.php b/src/Controllers/Version4/Responses/ProductVariationResponse.php deleted file mode 100644 index 63a96c5dd3d..00000000000 --- a/src/Controllers/Version4/Responses/ProductVariationResponse.php +++ /dev/null @@ -1,111 +0,0 @@ - $object->get_id(), - 'name' => $object->get_name( $context ), - 'type' => $object->get_type(), - 'parent_id' => $object->get_parent_id( $context ), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), - 'description' => wc_format_content( $object->get_description() ), - 'permalink' => $object->get_permalink(), - 'sku' => $object->get_sku(), - 'price' => $object->get_price(), - 'regular_price' => $object->get_regular_price(), - 'sale_price' => $object->get_sale_price(), - 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), - 'on_sale' => $object->is_on_sale(), - 'status' => $object->get_status(), - 'purchasable' => $object->is_purchasable(), - 'virtual' => $object->is_virtual(), - 'downloadable' => $object->is_downloadable(), - 'downloads' => $this->prepare_downloads( $object ), - 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, - 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, - 'tax_status' => $object->get_tax_status(), - 'tax_class' => $object->get_tax_class(), - 'manage_stock' => $object->managing_stock(), - 'stock_quantity' => $object->get_stock_quantity(), - 'stock_status' => $object->get_stock_status(), - 'backorders' => $object->get_backorders(), - 'backorders_allowed' => $object->backorders_allowed(), - 'backordered' => $object->is_on_backorder(), - 'weight' => $object->get_weight(), - 'dimensions' => array( - 'length' => $object->get_length(), - 'width' => $object->get_width(), - 'height' => $object->get_height(), - ), - 'shipping_class' => $object->get_shipping_class(), - 'shipping_class_id' => $object->get_shipping_class_id(), - 'image' => $this->prepare_image( $object ), - 'attributes' => $this->prepare_attributes( $object ), - 'menu_order' => $object->get_menu_order(), - 'meta_data' => $object->get_meta_data(), - ); - return $data; - } - - /** - * Get the image for a product variation. - * - * @param \WC_Product_Variation $object Variation data. - * @return array - */ - protected static function prepare_image( $object ) { - if ( ! $object->get_image_id() ) { - return; - } - - $attachment_id = $object->get_image_id(); - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - return; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - return; - } - - if ( ! isset( $image ) ) { - return array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - } -} diff --git a/src/Controllers/Version4/Settings.php b/src/Controllers/Version4/Settings.php deleted file mode 100644 index 6d76f20bb9c..00000000000 --- a/src/Controllers/Version4/Settings.php +++ /dev/null @@ -1,208 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - $this->register_batch_route(); - } - - /** - * Update a setting. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function update_item( $request ) { - $options_controller = new \WC_REST_Setting_Options_Controller(); - $response = $options_controller->update_item( $request ); - - return $response; - } - - /** - * Get all settings groups items. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new \WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $defaults = $this->group_defaults(); - $filtered_groups = array(); - foreach ( $groups as $group ) { - $sub_groups = array(); - foreach ( $groups as $_group ) { - if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { - $sub_groups[] = $_group['id']; - } - } - $group['sub_groups'] = $sub_groups; - - $group = wp_parse_args( $group, $defaults ); - if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { - $group_obj = $this->filter_group( $group ); - $group_data = $this->prepare_item_for_response( $group_obj, $request ); - $group_data = $this->prepare_response_for_collection( $group_data ); - - $filtered_groups[] = $group_data; - } - } - - $response = rest_ensure_response( $filtered_groups ); - return $response; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - $links = array( - 'options' => array( - 'href' => rest_url( trailingslashit( $base ) . $item['id'] ), - ), - ); - - return $links; - } - - /** - * Filters out bad values from the groups array/filter so we - * only return known values via the API. - * - * @since 3.0.0 - * @param array $group Group. - * @return array - */ - public function filter_group( $group ) { - return array_intersect_key( - $group, - array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) - ); - } - - /** - * Callback for allowed keys for each group response. - * - * @since 3.0.0 - * @param string $key Key to check. - * @return boolean - */ - public function allowed_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); - } - - /** - * Returns default settings for groups. null means the field is required. - * - * @since 3.0.0 - * @return array - */ - protected function group_defaults() { - return array( - 'id' => null, - 'label' => null, - 'description' => '', - 'parent_id' => '', - 'sub_groups' => array(), - ); - } - - /** - * Get the groups schema, conforming to JSON Schema. - * - * @since 3.0.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'setting_group', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/SettingsOptions.php b/src/Controllers/Version4/SettingsOptions.php deleted file mode 100644 index 992159bc4ea..00000000000 --- a/src/Controllers/Version4/SettingsOptions.php +++ /dev/null @@ -1,581 +0,0 @@ -[\w-]+)'; - - /** - * Register routes. - * - * @since 3.0.0 - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - 'args' => array( - 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - 'args' => array( - 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\w-]+)', - array( - 'args' => array( - 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Return a single setting. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $setting = $this->get_setting( $request['group_id'], $request['id'] ); - - if ( is_wp_error( $setting ) ) { - return $setting; - } - - $response = $this->prepare_item_for_response( $setting, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Return all settings in a group. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $settings = $this->get_group_settings( $request['group_id'] ); - - if ( is_wp_error( $settings ) ) { - return $settings; - } - - $data = array(); - - foreach ( $settings as $setting_obj ) { - $setting = $this->prepare_item_for_response( $setting_obj, $request ); - $setting = $this->prepare_response_for_collection( $setting ); - if ( $this->is_setting_type_valid( $setting['type'] ) ) { - $data[] = $setting; - } - } - - return rest_ensure_response( $data ); - } - - /** - * Get all settings in a group. - * - * @param string $group_id Group ID. - * @return array|\WP_Error - */ - public function get_group_settings( $group_id ) { - if ( empty( $group_id ) ) { - return new \WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores - - if ( empty( $settings ) ) { - return new \WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $filtered_settings = array(); - foreach ( $settings as $setting ) { - $option_key = $setting['option_key']; - $setting = $this->filter_setting( $setting ); - $default = isset( $setting['default'] ) ? $setting['default'] : ''; - // Get the option value. - if ( is_array( $option_key ) ) { - $option = get_option( $option_key[0] ); - $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; - } else { - $admin_setting_value = \WC_Admin_Settings::get_option( $option_key, $default ); - $setting['value'] = $admin_setting_value; - } - - if ( 'multi_select_countries' === $setting['type'] ) { - $setting['options'] = WC()->countries->get_countries(); - $setting['type'] = 'multiselect'; - } elseif ( 'single_select_country' === $setting['type'] ) { - $setting['type'] = 'select'; - $setting['options'] = $this->get_countries_and_states(); - } elseif ( 'single_select_page' === $setting['type'] ) { - $pages = get_pages( - array( - 'sort_column' => 'menu_order', - 'sort_order' => 'ASC', - 'hierarchical' => 0, - ) - ); - $options = array(); - foreach ( $pages as $page ) { - $options[ $page->ID ] = ! empty( $page->post_title ) ? $page->post_title : '#' . $page->ID; - } - $setting['type'] = 'select'; - $setting['options'] = $options; - } - - $filtered_settings[] = $setting; - } - - return $filtered_settings; - } - - /** - * Returns a list of countries and states for use in the base location setting. - * - * @since 3.0.7 - * @return array Array of states and countries. - */ - private function get_countries_and_states() { - $countries = WC()->countries->get_countries(); - if ( empty( $countries ) ) { - return array(); - } - $output = array(); - foreach ( $countries as $key => $value ) { - $states = WC()->countries->get_states( $key ); - - if ( $states ) { - foreach ( $states as $state_key => $state_value ) { - $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; - } - } else { - $output[ $key ] = $value; - } - } - return $output; - } - - /** - * Get setting data. - * - * @since 3.0.0 - * @param string $group_id Group ID. - * @param string $setting_id Setting ID. - * @return stdClass|\WP_Error - */ - public function get_setting( $group_id, $setting_id ) { - if ( empty( $setting_id ) ) { - return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $settings = $this->get_group_settings( $group_id ); - - if ( is_wp_error( $settings ) ) { - return $settings; - } - - $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); - - if ( empty( $array_key ) ) { - return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $setting = $settings[ $array_key[0] ]; - - if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { - return new \WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( is_wp_error( $setting ) ) { - return $setting; - } - - $setting['group_id'] = $group_id; - - return $setting; - } - - /** - * Get batch of items from requst. - * - * @param \WP_REST_Request $request Full details about the request. - * @param string $batch_type Batch type; one of create, update, delete. - * @return array - */ - protected function get_batch_of_items_from_request( $request, $batch_type ) { - $params = $request->get_params(); - - if ( ! isset( $params[ $batch_type ] ) ) { - return array(); - } - - /** - * Since our batch settings update is group-specific and matches based on the route, - * we inject the URL parameters (containing group) into the batch items - */ - $items = array_filter( $params[ $batch_type ] ); - - if ( 'update' === $batch_type ) { - foreach ( $items as $key => $item ) { - $items[ $key ] = array_merge( $request->get_url_params(), $item ); - } - } - - return array_filter( $items ); - } - - /** - * Update a single setting in a group. - * - * @since 3.0.0 - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function update_item( $request ) { - $setting = $this->get_setting( $request['group_id'], $request['id'] ); - - if ( is_wp_error( $setting ) ) { - return $setting; - } - - if ( is_callable( array( $this, 'validate_setting_' . $setting['type'] . '_field' ) ) ) { - $value = $this->{'validate_setting_' . $setting['type'] . '_field'}( $request['value'], $setting ); - } else { - $value = $this->validate_setting_text_field( $request['value'], $setting ); - } - - if ( is_wp_error( $value ) ) { - return $value; - } - - if ( is_array( $setting['option_key'] ) ) { - $setting['value'] = $value; - $option_key = $setting['option_key']; - $prev = get_option( $option_key[0] ); - $prev[ $option_key[1] ] = $request['value']; - update_option( $option_key[0], $prev ); - } else { - $update_data = array(); - $update_data[ $setting['option_key'] ] = $value; - $setting['value'] = $value; - \WC_Admin_Settings::save_fields( array( $setting ), $update_data ); - } - - $response = $this->prepare_item_for_response( $setting, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WC_Shipping_Method $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - unset( $object['option_key'] ); - return $this->filter_setting( $object ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = str_replace( '(?P[\w-]+)', $request['group_id'], $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $base, $item['id'] ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - ); - - return $links; - } - - /** - * Filters out bad values from the settings array/filter so we - * only return known values via the API. - * - * @since 3.0.0 - * @param array $setting Settings. - * @return array - */ - public function filter_setting( $setting ) { - $setting = array_intersect_key( - $setting, - array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) - ); - - if ( empty( $setting['options'] ) ) { - unset( $setting['options'] ); - } - - if ( 'image_width' === $setting['type'] ) { - $setting = $this->cast_image_width( $setting ); - } - - return $setting; - } - - /** - * For image_width, Crop can return "0" instead of false -- so we want - * to make sure we return these consistently the same we accept them. - * - * @todo remove in 4.0 - * @since 3.0.0 - * @param array $setting Settings. - * @return array - */ - public function cast_image_width( $setting ) { - foreach ( array( 'default', 'value' ) as $key ) { - if ( isset( $setting[ $key ] ) ) { - $setting[ $key ]['width'] = intval( $setting[ $key ]['width'] ); - $setting[ $key ]['height'] = intval( $setting[ $key ]['height'] ); - $setting[ $key ]['crop'] = (bool) $setting[ $key ]['crop']; - } - } - return $setting; - } - - /** - * Callback for allowed keys for each setting response. - * - * @param string $key Key to check. - * @return boolean - */ - public function allowed_setting_keys( $key ) { - return in_array( - $key, array( - 'id', - 'group_id', - 'label', - 'description', - 'default', - 'tip', - 'placeholder', - 'type', - 'options', - 'value', - 'option_key', - ), true - ); - } - - /** - * Boolean for if a setting type is a valid supported setting type. - * - * @since 3.0.0 - * @param string $type Type. - * @return bool - */ - public function is_setting_type_valid( $type ) { - return in_array( - $type, array( - 'text', // Validates with validate_setting_text_field. - 'email', // Validates with validate_setting_text_field. - 'number', // Validates with validate_setting_text_field. - 'color', // Validates with validate_setting_text_field. - 'password', // Validates with validate_setting_text_field. - 'textarea', // Validates with validate_setting_textarea_field. - 'select', // Validates with validate_setting_select_field. - 'multiselect', // Validates with validate_setting_multiselect_field. - 'radio', // Validates with validate_setting_radio_field (-> validate_setting_select_field). - 'checkbox', // Validates with validate_setting_checkbox_field. - 'image_width', // Validates with validate_setting_image_width_field. - 'thumbnail_cropping', // Validates with validate_setting_text_field. - ) - ); - } - - /** - * Get the settings schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'setting', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'group_id' => array( - 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/ShippingMethods.php b/src/Controllers/Version4/ShippingMethods.php deleted file mode 100644 index 8aa7d3def17..00000000000 --- a/src/Controllers/Version4/ShippingMethods.php +++ /dev/null @@ -1,191 +0,0 @@ - - */ - public function register_routes() { - register_rest_route( - $this->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 . '/(?P[\w-]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Get shipping methods. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $wc_shipping = \WC_Shipping::instance(); - $response = array(); - foreach ( $wc_shipping->get_shipping_methods() as $id => $shipping_method ) { - $method = $this->prepare_item_for_response( $shipping_method, $request ); - $method = $this->prepare_response_for_collection( $method ); - $response[] = $method; - } - return rest_ensure_response( $response ); - } - - /** - * Get a single Shipping Method. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function get_item( $request ) { - $wc_shipping = \WC_Shipping::instance(); - $methods = $wc_shipping->get_shipping_methods(); - if ( empty( $methods[ $request['id'] ] ) ) { - return new \WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $method = $methods[ $request['id'] ]; - $response = $this->prepare_item_for_response( $method, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WC_Shipping_Method $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return array( - 'id' => $object->id, - 'title' => $object->method_title, - 'description' => $object->method_description, - ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the shipping method schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_method', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Method ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get any query params needed. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version4/ShippingZoneLocations.php b/src/Controllers/Version4/ShippingZoneLocations.php deleted file mode 100644 index 503b6ff3845..00000000000 --- a/src/Controllers/Version4/ShippingZoneLocations.php +++ /dev/null @@ -1,172 +0,0 @@ -/locations endpoint. - * - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Shipping Zone Locations class. - */ -class ShippingZoneLocations extends AbstractShippingZonesController { - - /** - * Register the routes for Shipping Zone Locations. - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)/locations', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_items' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Get all Shipping Zone Locations. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function get_items( $request ) { - $zone = $this->get_zone( (int) $request['id'] ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $locations = $zone->get_zone_locations(); - $data = array(); - - foreach ( $locations as $location_obj ) { - $location = $this->prepare_item_for_response( (array) $location_obj, $request ); - $location = $this->prepare_response_for_collection( $location ); - $data[] = $location; - } - - return rest_ensure_response( $data ); - } - - /** - * Update all Shipping Zone Locations. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function update_items( $request ) { - $zone = $this->get_zone( (int) $request['id'] ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - if ( 0 === $zone->get_id() ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); - } - - $raw_locations = $request->get_json_params(); - $locations = array(); - - foreach ( (array) $raw_locations as $raw_location ) { - if ( empty( $raw_location['code'] ) ) { - continue; - } - - $type = ! empty( $raw_location['type'] ) ? sanitize_text_field( $raw_location['type'] ) : 'country'; - - if ( ! in_array( $type, array( 'postcode', 'state', 'country', 'continent' ), true ) ) { - continue; - } - - $locations[] = array( - 'code' => sanitize_text_field( $raw_location['code'] ), - 'type' => sanitize_text_field( $type ), - ); - } - - $zone->set_locations( $locations ); - $zone->save(); - - return $this->get_items( $request ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $request['id']; - $links = array( - 'collection' => array( - 'href' => rest_url( $base . '/locations' ), - ), - 'describes' => array( - 'href' => rest_url( $base ), - ), - ); - - return $links; - } - - /** - * Get the Shipping Zone Locations schema, conforming to JSON Schema - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone_location', - 'type' => 'object', - 'properties' => array( - 'code' => array( - 'description' => __( 'Shipping zone location code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'type' => array( - 'description' => __( 'Shipping zone location type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'country', - 'enum' => array( - 'postcode', - 'state', - 'country', - 'continent', - ), - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/ShippingZoneMethods.php b/src/Controllers/Version4/ShippingZoneMethods.php deleted file mode 100644 index ca547399671..00000000000 --- a/src/Controllers/Version4/ShippingZoneMethods.php +++ /dev/null @@ -1,557 +0,0 @@ -/methods endpoint. - * - * @package Automattic/WooCommerce/RestApi - */ - -namespace Automattic\WooCommerce\RestApi\Controllers\Version4; - -defined( 'ABSPATH' ) || exit; - -use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\SettingsTrait; - -/** - * REST API Shipping Zone Methods class. - */ -class ShippingZoneMethods extends AbstractShippingZonesController { - use SettingsTrait; - - /** - * Register the routes for Shipping Zone Methods. - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)/methods', - array( - 'args' => array( - 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'method_id' => array( - 'required' => true, - 'readonly' => false, - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', - array( - 'args' => array( - 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'instance_id' => array( - 'description' => __( 'Unique ID for the instance.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Get a single Shipping Zone Method. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function get_item( $request ) { - $zone = $this->get_zone( $request['zone_id'] ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $instance_id = (int) $request['instance_id']; - $methods = $zone->get_shipping_methods(); - $method = false; - - foreach ( $methods as $method_obj ) { - if ( $instance_id === $method_obj->instance_id ) { - $method = $method_obj; - break; - } - } - - if ( false === $method ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $data = $this->prepare_item_for_response( $method, $request ); - - return rest_ensure_response( $data ); - } - - /** - * Get all Shipping Zone Methods. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function get_items( $request ) { - $zone = $this->get_zone( $request['zone_id'] ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $methods = $zone->get_shipping_methods(); - $data = array(); - - foreach ( $methods as $method_obj ) { - $method = $this->prepare_item_for_response( $method_obj, $request ); - $data[] = $method; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a new shipping zone method instance. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function create_item( $request ) { - $method_id = $request['method_id']; - $zone = $this->get_zone( $request['zone_id'] ); - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $instance_id = $zone->add_shipping_method( $method_id ); - $methods = $zone->get_shipping_methods(); - $method = false; - foreach ( $methods as $method_obj ) { - if ( $instance_id === $method_obj->instance_id ) { - $method = $method_obj; - break; - } - } - - if ( false === $method ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $method = $this->update_fields( $instance_id, $method, $request ); - if ( is_wp_error( $method ) ) { - return $method; - } - - $data = $this->prepare_item_for_response( $method, $request ); - return rest_ensure_response( $data ); - } - - /** - * Delete a shipping method instance. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|boolean - */ - public function delete_item( $request ) { - $zone = $this->get_zone( $request['zone_id'] ); - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $instance_id = (int) $request['instance_id']; - $force = $request['force']; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $methods = $zone->get_shipping_methods(); - $method = false; - - foreach ( $methods as $method_obj ) { - if ( $instance_id === $method_obj->instance_id ) { - $method = $method_obj; - break; - } - } - - if ( false === $method ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $method = $this->update_fields( $instance_id, $method, $request ); - if ( is_wp_error( $method ) ) { - return $method; - } - - $request->set_param( 'context', 'view' ); - $previous = $this->prepare_item_for_response( $method, $request ); - - // Actually delete. - $zone->delete_shipping_method( $instance_id ); - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous, - ) - ); - - /** - * Fires after a method is deleted via the REST API. - * - * @param object $method - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_shipping_zone_method', $method, $response, $request ); - - return $response; - } - - /** - * Update A Single Shipping Zone Method. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function update_item( $request ) { - $zone = $this->get_zone( $request['zone_id'] ); - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $instance_id = (int) $request['instance_id']; - $methods = $zone->get_shipping_methods(); - $method = false; - - foreach ( $methods as $method_obj ) { - if ( $instance_id === $method_obj->instance_id ) { - $method = $method_obj; - break; - } - } - - if ( false === $method ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $method = $this->update_fields( $instance_id, $method, $request ); - if ( is_wp_error( $method ) ) { - return $method; - } - - $data = $this->prepare_item_for_response( $method, $request ); - return rest_ensure_response( $data ); - } - - /** - * Updates settings, order, and enabled status on create. - * - * @param int $instance_id Instance ID. - * @param \WC_Shipping_Method $method Shipping method data. - * @param \WP_REST_Request $request Request data. - * - * @return WC_Shipping_Method - */ - public function update_fields( $instance_id, $method, $request ) { - global $wpdb; - - // Update settings if present. - if ( isset( $request['settings'] ) ) { - $method->init_instance_settings(); - $instance_settings = $method->instance_settings; - $errors_found = false; - foreach ( $method->get_instance_form_fields() as $key => $field ) { - if ( isset( $request['settings'][ $key ] ) ) { - if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { - $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); - } else { - $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); - } - if ( is_wp_error( $value ) ) { - $errors_found = true; - break; - } - $instance_settings[ $key ] = $value; - } - } - - if ( $errors_found ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); - } - - // Update order. - if ( isset( $request['order'] ) ) { - $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'method_order' => absint( $request['order'] ) ), array( 'instance_id' => absint( $instance_id ) ) ); - $method->method_order = absint( $request['order'] ); - } - - // Update if this method is enabled or not. - if ( isset( $request['enabled'] ) ) { - if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'is_enabled' => $request['enabled'] ), array( 'instance_id' => absint( $instance_id ) ) ) ) { - do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method->id, $request['zone_id'], $request['enabled'] ); - $method->enabled = ( true === $request['enabled'] ? 'yes' : 'no' ); - } - } - - return $method; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param array $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return array( - 'id' => $object->instance_id, - 'instance_id' => $object->instance_id, - 'title' => $object->instance_settings['title'], - 'order' => $object->method_order, - 'enabled' => ( 'yes' === $object->enabled ), - 'method_id' => $object->id, - 'method_title' => $object->method_title, - 'method_description' => $object->method_description, - 'settings' => $this->get_settings( $object ), - ); - } - - /** - * Prepare a single item for response. - * - * @param mixed $item Object used to create response. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - $response = parent::prepare_item_for_response( $item, $request ); - $response = $this->prepare_response_for_collection( $response ); - return $response; - } - - /** - * Return settings associated with this shipping zone method instance. - * - * @param WC_Shipping_Method $item Shipping method data. - * - * @return array - */ - public function get_settings( $item ) { - $item->init_instance_settings(); - $settings = array(); - foreach ( $item->get_instance_form_fields() as $id => $field ) { - $data = array( - 'id' => $id, - 'label' => $field['title'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => $item->instance_settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $request['zone_id']; - $links = array( - 'self' => array( - 'href' => rest_url( $base . '/methods/' . $item->instance_id ), - ), - 'collection' => array( - 'href' => rest_url( $base . '/methods' ), - ), - 'describes' => array( - 'href' => rest_url( $base ), - ), - ); - - return $links; - } - - /** - * Get the Shipping Zone Methods schema, conforming to JSON Schema - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone_method', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'instance_id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Shipping method customer facing title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'order' => array( - 'description' => __( 'Shipping method sort order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'enabled' => array( - 'description' => __( 'Shipping method enabled status.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - ), - 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'settings' => array( - 'description' => __( 'Shipping method settings.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/ShippingZones.php b/src/Controllers/Version4/ShippingZones.php deleted file mode 100644 index a80af9c47f5..00000000000 --- a/src/Controllers/Version4/ShippingZones.php +++ /dev/null @@ -1,306 +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' ), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'name' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d-]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Get a single Shipping Zone. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response|\WP_Error - */ - public function get_item( $request ) { - $zone = $this->get_zone( $request->get_param( 'id' ) ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $data = $zone->get_data(); - $data = $this->prepare_item_for_response( $data, $request ); - $data = $this->prepare_response_for_collection( $data ); - - return rest_ensure_response( $data ); - } - - /** - * Get all Shipping Zones. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_REST_Response - */ - public function get_items( $request ) { - $rest_of_the_world = \WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); - - $zones = \WC_Shipping_Zones::get_zones(); - array_unshift( $zones, $rest_of_the_world->get_data() ); - $data = array(); - - foreach ( $zones as $zone_obj ) { - $zone = $this->prepare_item_for_response( $zone_obj, $request ); - $zone = $this->prepare_response_for_collection( $zone ); - $data[] = $zone; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a single Shipping Zone. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function create_item( $request ) { - $zone = new \WC_Shipping_Zone( null ); - - if ( ! is_null( $request->get_param( 'name' ) ) ) { - $zone->set_zone_name( $request->get_param( 'name' ) ); - } - - if ( ! is_null( $request->get_param( 'order' ) ) ) { - $zone->set_zone_order( $request->get_param( 'order' ) ); - } - - $zone->save(); - - if ( $zone->get_id() !== 0 ) { - $request->set_param( 'id', $zone->get_id() ); - $response = $this->get_item( $request ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); - return $response; - } else { - return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - } - - /** - * Update a single Shipping Zone. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function update_item( $request ) { - $zone = $this->get_zone( $request->get_param( 'id' ) ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - if ( 0 === $zone->get_id() ) { - return new \WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); - } - - $zone_changed = false; - - if ( ! is_null( $request->get_param( 'name' ) ) ) { - $zone->set_zone_name( $request->get_param( 'name' ) ); - $zone_changed = true; - } - - if ( ! is_null( $request->get_param( 'order' ) ) ) { - $zone->set_zone_order( $request->get_param( 'order' ) ); - $zone_changed = true; - } - - if ( $zone_changed ) { - $zone->save(); - } - - return $this->get_item( $request ); - } - - /** - * Delete a single Shipping Zone. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Request|\WP_Error - */ - public function delete_item( $request ) { - $zone = $this->get_zone( $request->get_param( 'id' ) ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $force = $request['force']; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $previous = $this->get_item( $request ); - $zone->delete(); - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - - return $response; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param object $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return array( - 'id' => (int) $object['id'], - 'name' => $object['zone_name'], - 'order' => (int) $object['zone_order'], - ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - $links = array( - 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $item['id'] ), - ), - 'collection' => array( - 'href' => rest_url( $base ), - ), - 'describedby' => array( - 'href' => rest_url( trailingslashit( $base ) . $item['id'] . '/locations' ), - ), - ); - - return $links; - } - - /** - * Get the Shipping Zones schema, conforming to JSON Schema - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'order' => array( - 'description' => __( 'Shipping zone order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version4/SystemStatus.php b/src/Controllers/Version4/SystemStatus.php deleted file mode 100644 index f2f458c4090..00000000000 --- a/src/Controllers/Version4/SystemStatus.php +++ /dev/null @@ -1,588 +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 - ); - } - - /** - * Get a system status info, by section. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $schema = $this->get_item_schema(); - $mappings = $this->get_item_mappings(); - $response = array(); - - foreach ( $mappings as $section => $values ) { - $response[ $section ] = $values; - } - - $response = $this->prepare_item_for_response( $response, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Get the system status schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'system_status', - 'type' => 'object', - 'properties' => array( - 'environment' => array( - 'description' => __( 'Environment.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'home_url' => array( - 'description' => __( 'Home URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'site_url' => array( - 'description' => __( 'Site URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wc_version' => array( - 'description' => __( 'WooCommerce version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'log_directory' => array( - 'description' => __( 'Log directory.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'log_directory_writable' => array( - 'description' => __( 'Is log directory writable?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_version' => array( - 'description' => __( 'WordPress version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_multisite' => array( - 'description' => __( 'Is WordPress multisite?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_memory_limit' => array( - 'description' => __( 'WordPress memory limit.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_debug_mode' => array( - 'description' => __( 'Is WordPress debug mode active?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_cron' => array( - 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'language' => array( - 'description' => __( 'WordPress language.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'server_info' => array( - 'description' => __( 'Server info.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'php_version' => array( - 'description' => __( 'PHP version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'php_post_max_size' => array( - 'description' => __( 'PHP post max size.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'php_max_execution_time' => array( - 'description' => __( 'PHP max execution time.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'php_max_input_vars' => array( - 'description' => __( 'PHP max input vars.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'curl_version' => array( - 'description' => __( 'cURL version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'suhosin_installed' => array( - 'description' => __( 'Is SUHOSIN installed?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'max_upload_size' => array( - 'description' => __( 'Max upload size.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'mysql_version' => array( - 'description' => __( 'MySQL version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'mysql_version_string' => array( - 'description' => __( 'MySQL version string.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'default_timezone' => array( - 'description' => __( 'Default timezone.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'fsockopen_or_curl_enabled' => array( - 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'soapclient_enabled' => array( - 'description' => __( 'Is SoapClient class enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'domdocument_enabled' => array( - 'description' => __( 'Is DomDocument class enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'gzip_enabled' => array( - 'description' => __( 'Is GZip enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'mbstring_enabled' => array( - 'description' => __( 'Is mbstring enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'remote_post_successful' => array( - 'description' => __( 'Remote POST successful?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'remote_post_response' => array( - 'description' => __( 'Remote POST response.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'remote_get_successful' => array( - 'description' => __( 'Remote GET successful?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'remote_get_response' => array( - 'description' => __( 'Remote GET response.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - 'database' => array( - 'description' => __( 'Database.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'wc_database_version' => array( - 'description' => __( 'WC database version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'database_prefix' => array( - 'description' => __( 'Database prefix.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'maxmind_geoip_database' => array( - 'description' => __( 'MaxMind GeoIP database.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'database_tables' => array( - 'description' => __( 'Database tables.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - ), - ), - 'active_plugins' => array( - 'description' => __( 'Active plugins.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'inactive_plugins' => array( - 'description' => __( 'Inactive plugins.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'dropins_mu_plugins' => array( - 'description' => __( 'Dropins & MU plugins.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'theme' => array( - 'description' => __( 'Theme.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'name' => array( - 'description' => __( 'Theme name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'version' => array( - 'description' => __( 'Theme version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'version_latest' => array( - 'description' => __( 'Latest version of theme.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'author_url' => array( - 'description' => __( 'Theme author URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'is_child_theme' => array( - 'description' => __( 'Is this theme a child theme?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'has_woocommerce_support' => array( - 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'has_woocommerce_file' => array( - 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'has_outdated_templates' => array( - 'description' => __( 'Does this theme have outdated templates?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'overrides' => array( - 'description' => __( 'Template overrides.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'parent_name' => array( - 'description' => __( 'Parent theme name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'parent_version' => array( - 'description' => __( 'Parent theme version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'parent_author_url' => array( - 'description' => __( 'Parent theme author URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - 'settings' => array( - 'description' => __( 'Settings.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'api_enabled' => array( - 'description' => __( 'REST API enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'force_ssl' => array( - 'description' => __( 'SSL forced?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency' => array( - 'description' => __( 'Currency.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency_symbol' => array( - 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency_position' => array( - 'description' => __( 'Currency position.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'thousand_separator' => array( - 'description' => __( 'Thousand separator.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'decimal_separator' => array( - 'description' => __( 'Decimal separator.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'number_of_decimals' => array( - 'description' => __( 'Number of decimals.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'geolocation_enabled' => array( - 'description' => __( 'Geolocation enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'taxonomies' => array( - 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'product_visibility_terms' => array( - 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - ), - ), - 'security' => array( - 'description' => __( 'Security.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'secure_connection' => array( - 'description' => __( 'Is the connection to your store secure?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'hide_errors' => array( - 'description' => __( 'Hide errors from visitors?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - 'pages' => array( - 'description' => __( 'WooCommerce pages.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'post_type_counts' => array( - 'description' => __( 'Post type counts.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Return an array of sections and the data associated with each. - * - * @return array - */ - public function get_item_mappings() { - $plugin_info = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\PluginInformation(); - $theme_info = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\ThemeInformation(); - $server = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\ServerEnvironment(); - $database = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\DatabaseInformation(); - $wp_environment = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\WPEnvironment(); - $woo_environment = new \Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\WooEnvironment(); - - return array( - 'environment' => $server->get_environment_info(), - 'database' => $database->get_database_info(), - 'active_plugins' => $plugin_info->get_active_plugin_data(), - 'inactive_plugins' => $plugin_info->get_inactive_plugin_data(), - 'dropins_mu_plugins' => $plugin_info->get_dropin_and_mu_plugin_data(), - 'theme' => $theme_info->get_theme_info(), - 'settings' => $woo_environment->get_settings(), - 'security' => $wp_environment->get_security_info(), - 'pages' => $wp_environment->get_pages(), - 'post_type_counts' => $wp_environment->get_post_type_counts(), - ); - } - - /** - * Get any query params needed. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version4/SystemStatusTools.php b/src/Controllers/Version4/SystemStatusTools.php deleted file mode 100644 index 72fc9b8e513..00000000000 --- a/src/Controllers/Version4/SystemStatusTools.php +++ /dev/null @@ -1,577 +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 . '/(?P[\w-]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - 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_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * A list of available tools for use in the system status section. - * 'button' becomes 'action' in the API. - * - * @return array - */ - public function get_tools() { - $tools = array( - 'clear_transients' => array( - 'name' => __( 'WooCommerce transients', 'woocommerce-rest-api' ), - 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce-rest-api' ), - ), - 'clear_expired_transients' => array( - 'name' => __( 'Expired transients', 'woocommerce-rest-api' ), - 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce-rest-api' ), - ), - 'delete_orphaned_variations' => array( - 'name' => __( 'Orphaned variations', 'woocommerce-rest-api' ), - 'button' => __( 'Delete orphaned variations', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce-rest-api' ), - ), - 'clear_expired_download_permissions' => array( - 'name' => __( 'Used-up download permissions', 'woocommerce-rest-api' ), - 'button' => __( 'Clean up download permissions', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce-rest-api' ), - ), - 'regenerate_product_lookup_tables' => array( - 'name' => __( 'Product lookup tables', 'woocommerce-rest-api' ), - 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce-rest-api' ), - ), - 'recount_terms' => array( - 'name' => __( 'Term counts', 'woocommerce-rest-api' ), - 'button' => __( 'Recount terms', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce-rest-api' ), - ), - 'reset_roles' => array( - 'name' => __( 'Capabilities', 'woocommerce-rest-api' ), - 'button' => __( 'Reset capabilities', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce-rest-api' ), - ), - 'clear_sessions' => array( - 'name' => __( 'Clear customer sessions', 'woocommerce-rest-api' ), - 'button' => __( 'Clear', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce-rest-api' ) - ), - ), - 'install_pages' => array( - 'name' => __( 'Create default WooCommerce pages', 'woocommerce-rest-api' ), - 'button' => __( 'Create pages', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce-rest-api' ) - ), - ), - 'delete_taxes' => array( - 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce-rest-api' ), - 'button' => __( 'Delete tax rates', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce-rest-api' ) - ), - ), - 'regenerate_thumbnails' => array( - 'name' => __( 'Regenerate shop thumbnails', 'woocommerce-rest-api' ), - 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), - 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce-rest-api' ), - ), - 'db_update_routine' => array( - 'name' => __( 'Update database', 'woocommerce-rest-api' ), - 'button' => __( 'Update database', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce-rest-api' ) - ), - ), - ); - - // Jetpack does the image resizing heavy lifting so you don't have to. - if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) { - unset( $tools['regenerate_thumbnails'] ); - } - - return apply_filters( 'woocommerce_debug_tools', $tools ); - } - - /** - * Get a list of system status tools. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $tools = array(); - foreach ( $this->get_tools() as $id => $tool ) { - $tools[] = $this->prepare_response_for_collection( - $this->prepare_item_for_response( - array( - 'id' => $id, - 'name' => $tool['name'], - 'action' => $tool['button'], - 'description' => $tool['desc'], - ), - $request - ) - ); - } - - $response = rest_ensure_response( $tools ); - return $response; - } - - /** - * Return a single tool. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $tools = $this->get_tools(); - if ( empty( $tools[ $request['id'] ] ) ) { - return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - $tool = $tools[ $request['id'] ]; - return rest_ensure_response( - $this->prepare_item_for_response( - array( - 'id' => $request['id'], - 'name' => $tool['name'], - 'action' => $tool['button'], - 'description' => $tool['desc'], - ), - $request - ) - ); - } - - /** - * Update (execute) a tool. - * - * @param \WP_REST_Request $request Request data. - * @return \WP_Error|\WP_REST_Response - */ - public function update_item( $request ) { - $tools = $this->get_tools(); - if ( empty( $tools[ $request['id'] ] ) ) { - return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $tool = $tools[ $request['id'] ]; - $tool = array( - 'id' => $request['id'], - 'name' => $tool['name'], - 'action' => $tool['button'], - 'description' => $tool['desc'], - ); - - $execute_return = $this->execute_tool( $request['id'] ); - $tool = array_merge( $tool, $execute_return ); - - /** - * Fires after a WooCommerce REST system status tool has been executed. - * - * @param array $tool Details about the tool that has been executed. - * @param \WP_REST_Request $request The current \WP_REST_Request object. - */ - do_action( 'woocommerce_rest_insert_system_status_tool', $tool, $request ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tool, $request ); - return rest_ensure_response( $response ); - } - - /** - * Get the system status tools schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'system_status_tool', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the tool.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'name' => array( - 'description' => __( 'Tool name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'action' => array( - 'description' => __( 'What running the tool will do.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'description' => array( - 'description' => __( 'Tool description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'success' => array( - 'description' => __( 'Did the tool run successfully?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'edit' ), - ), - 'message' => array( - 'description' => __( 'Tool return message.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - $links = array( - 'item' => array( - 'href' => rest_url( trailingslashit( $base ) . $item['id'] ), - 'embeddable' => true, - ), - ); - - return $links; - } - - /** - * Get any query params needed. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } - - /** - * Actually executes a tool. - * - * @throws Exception When the tool cannot run. - * @param string $tool Tool. - * @return array - */ - public function execute_tool( $tool ) { - $ran = false; - $tools = $this->get_tools(); - - try { - if ( ! isset( $tools[ $tool ] ) ) { - throw new Exception( __( 'There was an error calling this tool. There is no callback present.', 'woocommerce-rest-api' ) ); - } - - $callback = isset( $tools[ $tool ]['callback'] ) ? $tools[ $tool ]['callback'] : array( $this, $tool ); - - if ( ! is_callable( $callback ) ) { - throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce-rest-api' ) ); - } - - $message = call_user_func( $callback ); - - if ( false === $message ) { - throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce-rest-api' ) ); - } - - if ( empty( $message ) || ! is_string( $message ) ) { - $message = __( 'Tool ran.', 'woocommerce-rest-api' ); - } - - $ran = true; - } catch ( Exception $e ) { - $message = $e->getMessage(); - $ran = false; - } - - return array( - 'success' => $ran, - 'message' => $message, - ); - } - - /** - * Tool: clear_transients. - * - * @return string Success message. - */ - protected function clear_transients() { - wc_delete_product_transients(); - wc_delete_shop_order_transients(); - delete_transient( 'wc_count_comments' ); - - $attribute_taxonomies = wc_get_attribute_taxonomies(); - - if ( ! empty( $attribute_taxonomies ) ) { - foreach ( $attribute_taxonomies as $attribute ) { - delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name ); - } - } - - \WC_Cache_Helper::get_transient_version( 'shipping', true ); - return __( 'Product transients cleared', 'woocommerce-rest-api' ); - } - - /** - * Tool: clear_expired_transients. - * - * @return string Success message. - */ - protected function clear_expired_transients() { - /* translators: %d: amount of expired transients */ - return sprintf( __( '%d transients rows cleared', 'woocommerce-rest-api' ), wc_delete_expired_transients() ); - } - - /** - * Tool: delete_orphaned_variations. - * - * @return string Success message. - */ - protected function delete_orphaned_variations() { - global $wpdb; - - $result = absint( - $wpdb->query( - "DELETE products - FROM {$wpdb->posts} products - LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent - WHERE wp.ID IS NULL AND products.post_type = 'product_variation';" - ) - ); - /* translators: %d: amount of orphaned variations */ - return sprintf( __( '%d orphaned variations deleted', 'woocommerce-rest-api' ), $result ); - } - - /** - * Tool: clear_expired_download_permissions. - * - * @return string Success message. - */ - protected function clear_expired_download_permissions() { - global $wpdb; - - $result = absint( - $wpdb->query( - $wpdb->prepare( - "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions - WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )", - date( 'Y-m-d', current_time( 'timestamp' ) ) - ) - ) - ); - /* translators: %d: amount of permissions */ - return sprintf( __( '%d permissions deleted', 'woocommerce-rest-api' ), $result ); - } - - /** - * Tool: regenerate_product_lookup_tables. - * - * @return string Success message. - */ - protected function regenerate_product_lookup_tables() { - if ( ! wc_update_product_lookup_tables_is_running() ) { - wc_update_product_lookup_tables(); - } - return __( 'Lookup tables are regenerating', 'woocommerce-rest-api' ); - } - - /** - * Tool: reset_roles. - * - * @return string Success message. - */ - protected function reset_roles() { - \WC_Install::remove_roles(); - \WC_Install::create_roles(); - return __( 'Roles successfully reset', 'woocommerce-rest-api' ); - } - - /** - * Tool: recount_terms. - * - * @return string Success message. - */ - protected function recount_terms() { - $product_cats = get_terms( - 'product_cat', - array( - 'hide_empty' => false, - 'fields' => 'id=>parent', - ) - ); - _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false ); - $product_tags = get_terms( - 'product_tag', - array( - 'hide_empty' => false, - 'fields' => 'id=>parent', - ) - ); - _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); - return __( 'Terms successfully recounted', 'woocommerce-rest-api' ); - } - - /** - * Tool: clear_sessions. - * - * @return string Success message. - */ - protected function clear_sessions() { - global $wpdb; - - $wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" ); - $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. - wp_cache_flush(); - /* translators: %d: amount of sessions */ - return sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce-rest-api' ), absint( $result ) ); - } - - /** - * Tool: install_pages. - * - * @return string Success message. - */ - protected function install_pages() { - \WC_Install::create_pages(); - return __( 'All missing WooCommerce pages successfully installed', 'woocommerce-rest-api' ); - } - - /** - * Tool: delete_taxes. - * - * @return string Success message. - */ - protected function delete_taxes() { - global $wpdb; - $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); - $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); - \WC_Cache_Helper::incr_cache_prefix( 'taxes' ); - return __( 'Tax rates successfully deleted', 'woocommerce-rest-api' ); - } - - /** - * Tool: regenerate_thumbnails. - * - * @return string Success message. - */ - protected function regenerate_thumbnails() { - \WC_Regenerate_Images::queue_image_regeneration(); - return __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce-rest-api' ); - } - - /** - * Tool: db_update_routine. - * - * @return string Success message. - */ - protected function db_update_routine() { - $blog_id = get_current_blog_id(); - // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). - // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. - do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); - return __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce-rest-api' ); - } -} diff --git a/src/Controllers/Version4/TaxClasses.php b/src/Controllers/Version4/TaxClasses.php deleted file mode 100644 index 3f3a527f2de..00000000000 --- a/src/Controllers/Version4/TaxClasses.php +++ /dev/null @@ -1,310 +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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', - array( - 'args' => array( - 'slug' => array( - 'description' => __( 'Unique slug for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - } - - /** - * Get all tax classes. - * - * @param \WP_REST_Request $request Request params. - * @return array - */ - public function get_items( $request ) { - $tax_classes = array(); - - // Add standard class. - $tax_classes[] = array( - 'slug' => 'standard', - 'name' => __( 'Standard rate', 'woocommerce-rest-api' ), - ); - - $classes = \WC_Tax::get_tax_classes(); - - foreach ( $classes as $class ) { - $tax_classes[] = array( - 'slug' => sanitize_title( $class ), - 'name' => $class, - ); - } - - $data = array(); - foreach ( $tax_classes as $tax_class ) { - $class = $this->prepare_item_for_response( $tax_class, $request ); - $class = $this->prepare_response_for_collection( $class ); - $data[] = $class; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a single tax. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - $exists = false; - $classes = \WC_Tax::get_tax_classes(); - $tax_class = array( - 'slug' => sanitize_title( $request['name'] ), - 'name' => $request['name'], - ); - - // Check if class exists. - foreach ( $classes as $key => $class ) { - if ( sanitize_title( $class ) === $tax_class['slug'] ) { - $exists = true; - break; - } - } - - // Return error if tax class already exists. - if ( $exists ) { - return new \WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - // Add the new class. - $classes[] = $tax_class['name']; - - update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); - - $this->update_additional_fields_for_object( $tax_class, $request ); - - /** - * Fires after a tax class is created or updated via the REST API. - * - * @param \stdClass $tax_class Data used to create the tax class. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating tax class, false when updating tax class. - */ - do_action( 'woocommerce_rest_insert_tax_class', (object) $tax_class, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax_class, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $tax_class['slug'] ) ) ); - - return $response; - } - - /** - * Delete a single tax class. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function delete_item( $request ) { - global $wpdb; - - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $tax_class = array( - 'slug' => sanitize_title( $request['slug'] ), - 'name' => '', - ); - $classes = \WC_Tax::get_tax_classes(); - $deleted = false; - - foreach ( $classes as $key => $class ) { - if ( sanitize_title( $class ) === $tax_class['slug'] ) { - $tax_class['name'] = $class; - unset( $classes[ $key ] ); - $deleted = true; - break; - } - } - - if ( ! $deleted ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $request->set_param( 'context', 'edit' ); - $previous = $this->prepare_item_for_response( $tax_class, $request ); - - update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); - - // Delete tax rate locations locations from the selected class. - $wpdb->query( - $wpdb->prepare( - " - DELETE locations.* - FROM {$wpdb->prefix}woocommerce_tax_rate_locations AS locations - INNER JOIN - {$wpdb->prefix}woocommerce_tax_rates AS rates - ON rates.tax_rate_id = locations.tax_rate_id - WHERE rates.tax_rate_class = %s - ", - $tax_class['slug'] - ) - ); - - // Delete tax rates in the selected class. - $wpdb->delete( $wpdb->prefix . 'woocommerce_tax_rates', array( 'tax_rate_class' => $tax_class['slug'] ), array( '%s' ) ); - - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - - /** - * Fires after a tax class is deleted via the REST API. - * - * @param \stdClass $tax_class The tax data. - * @param \WP_REST_Response $response The response returned from the API. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_tax_class', (object) $tax_class, $response, $request ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the Tax Classes schema, conforming to JSON Schema - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'tax_class', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Tax class name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'required' => true, - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version4/Taxes.php b/src/Controllers/Version4/Taxes.php deleted file mode 100644 index b1adf12669f..00000000000 --- a/src/Controllers/Version4/Taxes.php +++ /dev/null @@ -1,623 +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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - $this->register_batch_route(); - } - - /** - * Get all taxes and allow filtering by tax code. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - global $wpdb; - - $prepared_args = array(); - $prepared_args['order'] = $request['order']; - $prepared_args['number'] = $request['per_page']; - if ( ! empty( $request['offset'] ) ) { - $prepared_args['offset'] = $request['offset']; - } else { - $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; - } - $orderby_possibles = array( - 'id' => 'tax_rate_id', - 'order' => 'tax_rate_order', - ); - $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; - $prepared_args['class'] = $request['class']; - $prepared_args['code'] = $request['code']; - $prepared_args['include'] = $request['include']; - - /** - * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. - * - * @param array $prepared_args Array of arguments for $wpdb->get_results(). - * @param \WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request ); - - $query = " - SELECT * - FROM {$wpdb->prefix}woocommerce_tax_rates - WHERE 1 = 1 - "; - - // Filter by tax class. - if ( ! empty( $prepared_args['class'] ) ) { - $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; - $query .= " AND tax_rate_class = '$class'"; - } - - // Filter by tax code. - $tax_code_search = $prepared_args['code']; - if ( $tax_code_search ) { - $tax_code_search = $wpdb->esc_like( $tax_code_search ); - $tax_code_search = ' \'%' . $tax_code_search . '%\''; - $query .= ' AND CONCAT_WS( "-", NULLIF(tax_rate_country, ""), NULLIF(tax_rate_state, ""), NULLIF(tax_rate_name, ""), NULLIF(tax_rate_priority, "") ) LIKE ' . $tax_code_search; - } - - // Filter by included tax rate IDs. - $included_taxes = $prepared_args['include']; - if ( ! empty( $included_taxes ) ) { - $included_taxes = implode( ',', $prepared_args['include'] ); - $query .= " AND tax_rate_id IN ({$included_taxes})"; - } - - // Order tax rates. - $order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) ); - - // Pagination. - $pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] ); - - // Query taxes. - $results = $wpdb->get_results( $query . $order_by . $pagination ); // @codingStandardsIgnoreLine. - - $taxes = array(); - foreach ( $results as $tax ) { - $data = $this->prepare_item_for_response( $tax, $request ); - $taxes[] = $this->prepare_response_for_collection( $data ); - } - - // Store pagination values for headers then unset for count query. - $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); - - // Query only for ids. - $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); // @codingStandardsIgnoreLine. - - // Calculate totals. - $total_taxes = (int) $wpdb->num_rows; - $max_pages = ceil( $total_taxes / $per_page ); - - $response = rest_ensure_response( $taxes ); - $response = Pagination::add_pagination_headers( $response, $request, $total_taxes, $max_pages ); - - return $response; - } - - /** - * Take tax data from the request and return the updated or newly created rate. - * - * @param \WP_REST_Request $request Full details about the request. - * @param \stdClass|null $current Existing tax object. - * @return object - */ - protected function create_or_update_tax( $request, $current = null ) { - $id = absint( isset( $request['id'] ) ? $request['id'] : 0 ); - $data = array(); - $fields = array( - 'tax_rate_country', - 'tax_rate_state', - 'tax_rate', - 'tax_rate_name', - 'tax_rate_priority', - 'tax_rate_compound', - 'tax_rate_shipping', - 'tax_rate_order', - 'tax_rate_class', - ); - - foreach ( $fields as $field ) { - // Keys via API differ from the stored names returned by _get_tax_rate. - $key = 'tax_rate' === $field ? 'rate' : str_replace( 'tax_rate_', '', $field ); - - // Remove data that was not posted. - if ( ! isset( $request[ $key ] ) ) { - continue; - } - - // Test new data against current data. - if ( $current && $current->$field === $request[ $key ] ) { - continue; - } - - // Add to data array. - switch ( $key ) { - case 'tax_rate_priority': - case 'tax_rate_compound': - case 'tax_rate_shipping': - case 'tax_rate_order': - $data[ $field ] = absint( $request[ $key ] ); - break; - case 'tax_rate_class': - $data[ $field ] = 'standard' !== $request['tax_rate_class'] ? $request['tax_rate_class'] : ''; - break; - default: - $data[ $field ] = wc_clean( $request[ $key ] ); - break; - } - } - - if ( $id ) { - \WC_Tax::_update_tax_rate( $id, $data ); - } else { - $id = \WC_Tax::_insert_tax_rate( $data ); - } - - // Add locales. - if ( ! empty( $request['postcode'] ) ) { - \WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) ); - } - if ( ! empty( $request['city'] ) ) { - \WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) ); - } - - return \WC_Tax::_get_tax_rate( $id, OBJECT ); - } - - /** - * Create a single tax. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - return new \WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $tax = $this->create_or_update_tax( $request ); - - $this->update_additional_fields_for_object( $tax, $request ); - - /** - * Fires after a tax is created or updated via the REST API. - * - * @param \stdClass $tax Data used to create the tax. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating tax, false when updating tax. - */ - do_action( 'woocommerce_rest_insert_tax', $tax, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ) ); - - return $response; - } - - /** - * Get a single tax. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $tax_obj = \WC_Tax::_get_tax_rate( $id, OBJECT ); - - if ( empty( $id ) || empty( $tax_obj ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $tax = $this->prepare_item_for_response( $tax_obj, $request ); - $response = rest_ensure_response( $tax ); - - return $response; - } - - /** - * Update a single tax. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function update_item( $request ) { - $id = (int) $request['id']; - $tax_obj = \WC_Tax::_get_tax_rate( $id, OBJECT ); - - if ( empty( $id ) || empty( $tax_obj ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $tax = $this->create_or_update_tax( $request, $tax_obj ); - - $this->update_additional_fields_for_object( $tax, $request ); - - /** - * Fires after a tax is created or updated via the REST API. - * - * @param \stdClass $tax Data used to create the tax. - * @param \WP_REST_Request $request Request object. - * @param boolean $creating True when creating tax, false when updating tax. - */ - do_action( 'woocommerce_rest_insert_tax', $tax, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax, $request ); - $response = rest_ensure_response( $response ); - - return $response; - } - - /** - * Delete a single tax. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function delete_item( $request ) { - global $wpdb; - - $id = (int) $request['id']; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $tax = \WC_Tax::_get_tax_rate( $id, OBJECT ); - - if ( empty( $id ) || empty( $tax ) ) { - return new \WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax, $request ); - - \WC_Tax::_delete_tax_rate( $id ); - - if ( 0 === $wpdb->rows_affected ) { - return new \WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a tax is deleted via the REST API. - * - * @param \stdClass $tax The tax data. - * @param \WP_REST_Response $response The response returned from the API. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request ); - - return $response; - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \stdClass $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - global $wpdb; - - $id = (int) $object->tax_rate_id; - $data = array( - 'id' => $id, - 'country' => $object->tax_rate_country, - 'state' => $object->tax_rate_state, - 'postcode' => '', - 'city' => '', - 'rate' => $object->tax_rate, - 'name' => $object->tax_rate_name, - 'priority' => (int) $object->tax_rate_priority, - 'compound' => (bool) $object->tax_rate_compound, - 'shipping' => (bool) $object->tax_rate_shipping, - 'order' => (int) $object->tax_rate_order, - 'class' => $object->tax_rate_class ? $object->tax_rate_class : 'standard', - ); - - // Get locales from a tax rate. - $locales = $wpdb->get_results( - $wpdb->prepare( - " - SELECT location_code, location_type - FROM {$wpdb->prefix}woocommerce_tax_rate_locations - WHERE tax_rate_id = %d - ", - $id - ) - ); - - if ( ! is_wp_error( $locales ) && ! is_null( $locales ) ) { - foreach ( $locales as $locale ) { - $data[ $locale->location_type ] = $locale->location_code; - } - } - return $data; - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->tax_rate_id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the Taxes schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'tax', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'country' => array( - 'description' => __( 'Country ISO 3166 code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'State code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postcode / ZIP.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'rate' => array( - 'description' => __( 'Tax rate.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Tax rate name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'priority' => array( - 'description' => __( 'Tax priority.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => 1, - 'context' => array( 'view', 'edit' ), - ), - 'compound' => array( - 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'shipping' => array( - 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'order' => array( - 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'standard', - 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - 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(); - $params['context']['default'] = 'view'; - - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'enum' => array( 'asc', 'desc' ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'default' => 'order', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'enum' => array( - 'id', - 'order', - ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['class'] = array( - 'description' => __( 'Sort by tax class.', 'woocommerce-rest-api' ), - 'enum' => array_merge( array( 'standard' ), \WC_Tax::get_tax_class_slugs() ), - 'sanitize_callback' => 'sanitize_title', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['code'] = array( - 'description' => __( 'Search by similar tax code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['include'] = array( - 'description' => __( 'Limit result set to items that have the specified rate ID(s) assigned.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version4/Utilities/BatchTrait.php b/src/Controllers/Version4/Utilities/BatchTrait.php deleted file mode 100644 index 74870676955..00000000000 --- a/src/Controllers/Version4/Utilities/BatchTrait.php +++ /dev/null @@ -1,281 +0,0 @@ -get_params(); - $limit = $this->check_batch_limit( $items ); - if ( is_wp_error( $limit ) ) { - return $limit; - } - - $batches = [ 'create', 'update', 'delete' ]; - $response = []; - - foreach ( $batches as $batch ) { - $response[ $batch ] = $this->{"batch_$batch"}( $this->get_batch_of_items_from_request( $request, $batch ) ); - } - - return array_filter( $response ); - } - - /** - * Get batch of items from requst. - * - * @param \WP_REST_Request $request Full details about the request. - * @param string $batch_type Batch type; one of create, update, delete. - * @return array - */ - protected function get_batch_of_items_from_request( $request, $batch_type ) { - $params = $request->get_params(); - - if ( ! isset( $params[ $batch_type ] ) ) { - return array(); - } - - return array_filter( $params[ $batch_type ] ); - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param \WP_REST_Request $request Full details about the request. - * @return boolean|\WP_Error - */ - public function batch_items_permissions_check( $request ) { - return update_item_permissions_check( $request ); - } - - /** - * Register route for batch requests. - */ - protected function register_batch_route() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ), - true - ); - } - - /** - * Get the batch schema, conforming to JSON Schema. - * - * @return array - */ - protected function get_public_batch_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'batch', - 'type' => 'object', - 'properties' => array( - 'create' => array( - 'description' => __( 'List of created resources.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - ), - ), - 'update' => array( - 'description' => __( 'List of updated resources.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - ), - ), - 'delete' => array( - 'description' => __( 'List of delete resources.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'integer', - ), - ), - ), - ); - - return $schema; - } - - /** - * Get normalized rest base. - * - * @return string - */ - protected function get_normalized_rest_base() { - return preg_replace( '/\(.*\)\//i', '', $this->rest_base ); - } - - /** - * Check batch limit. - * - * @param array $items Request items. - * @return bool|\WP_Error - */ - protected function check_batch_limit( $items ) { - $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); - $total = 0; - $batches = [ 'create', 'update', 'delete' ]; - - foreach ( $batches as $batch ) { - if ( ! isset( $items[ $batch ] ) ) { - continue; - } - $total = $total + count( $items[ $batch ] ); - } - - if ( $total > $limit ) { - /* translators: %s: items limit */ - return new \WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce-rest-api' ), $limit ), array( 'status' => 413 ) ); - } - - return true; - } - - /** - * Get default params from schema. - * - * @return array - */ - protected function get_default_params() { - $defaults = []; - $schema = $this->get_public_item_schema(); - foreach ( $schema['properties'] as $arg => $options ) { - if ( isset( $options['default'] ) ) { - $defaults[ $arg ] = $options['default']; - } - } - return $defaults; - } - - /** - * Batch create items. - * - * @param array $items Array of items. - * @return array Response data. - */ - protected function batch_create( $items ) { - $batch_response = []; - - foreach ( $items as $item ) { - $request = new \WP_REST_Request( 'POST' ); - $request->set_default_params( $this->get_default_params() ); - $request->set_body_params( $item ); - - $response = $this->create_item( $request ); - $batch_response[] = $this->format_response( 0, $response ); - } - - return $batch_response; - } - - /** - * Batch update items. - * - * @param array $items Array of items. - * @return array Response data. - */ - protected function batch_update( $items ) { - $batch_response = []; - - foreach ( $items as $item ) { - $request = new \WP_REST_Request( 'PUT' ); - $request->set_body_params( $item ); - - $response = $this->update_item( $request ); - $batch_response[] = $this->format_response( $item['id'], $response ); - } - - return $batch_response; - } - - /** - * Batch delete items. - * - * @param array $items Array of item ids. - * @return array Response data. - */ - protected function batch_delete( $items ) { - $batch_response = []; - $items = wp_parse_id_list( $items ); - - foreach ( $items as $id ) { - $request = new \WP_REST_Request( 'DELETE' ); - $request->set_query_params( - [ - 'id' => $id, - 'force' => true, - ] - ); - $response = $this->delete_item( $request ); - $batch_response[] = $this->format_response( $id, $response ); - } - - return $batch_response; - } - - /** - * Format response data. - * - * @param int $id ID of item being updated. - * @param \WP_REST_Response|\WP_Error $response Response object. - * @return array - */ - protected function format_response( $id, $response ) { - /** - * REST Server - * - * @var \WP_REST_Server $wp_rest_server - */ - global $wp_rest_server; - - if ( ! is_wp_error( $response ) ) { - return $wp_rest_server->response_to_data( $response, '' ); - } else { - return array( - 'id' => $id, - 'error' => $this->format_error_response( $response ), - ); - } - } - - /** - * Format WP Error to response data. - * - * @param \WP_Error $error Error object. - * @return array - */ - protected function format_error_response( $error ) { - return array( - 'code' => $error->get_error_code(), - 'message' => $error->get_error_message(), - 'data' => $error->get_error_data(), - ); - } -} diff --git a/src/Controllers/Version4/Utilities/DatabaseInformation.php b/src/Controllers/Version4/Utilities/DatabaseInformation.php deleted file mode 100644 index be946dc9e9e..00000000000 --- a/src/Controllers/Version4/Utilities/DatabaseInformation.php +++ /dev/null @@ -1,118 +0,0 @@ -prefix . $table; - } - - /** - * Get array of database information. Version, prefix, and table existence. - * - * @return array - */ - public function get_database_info() { - global $wpdb; - - $database_table_information = $wpdb->get_results( - $wpdb->prepare( - "SELECT - table_name AS 'name', - engine, - round( ( data_length / 1024 / 1024 ), 2 ) 'data', - round( ( index_length / 1024 / 1024 ), 2 ) 'index' - FROM information_schema.TABLES - WHERE table_schema = %s - ORDER BY name ASC;", - DB_NAME - ) - ); - - // WC Core tables to check existence of. - $core_tables = apply_filters( - 'woocommerce_database_tables', - array( - 'woocommerce_sessions', - 'woocommerce_api_keys', - 'woocommerce_attribute_taxonomies', - 'woocommerce_downloadable_product_permissions', - 'woocommerce_order_items', - 'woocommerce_order_itemmeta', - 'woocommerce_tax_rates', - 'woocommerce_tax_rate_locations', - 'woocommerce_shipping_zones', - 'woocommerce_shipping_zone_locations', - 'woocommerce_shipping_zone_methods', - 'woocommerce_payment_tokens', - 'woocommerce_payment_tokenmeta', - 'woocommerce_log', - ) - ); - - /** - * Adding the prefix to the tables array, for backwards compatibility. - * - * If we changed the tables above to include the prefix, then any filters against that table could break. - */ - $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); - - /** - * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. - * - * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. - */ - $tables = array( - 'woocommerce' => array_fill_keys( $core_tables, false ), - 'other' => array(), - ); - - $database_size = array( - 'data' => 0, - 'index' => 0, - ); - - $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); - $global_tables = $wpdb->tables( 'global', true ); - foreach ( $database_table_information as $table ) { - // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. - if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { - continue; - } - $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; - - $tables[ $table_type ][ $table->name ] = array( - 'data' => $table->data, - 'index' => $table->index, - 'engine' => $table->engine, - ); - - $database_size['data'] += $table->data; - $database_size['index'] += $table->index; - } - - // Return all database info. Described by JSON Schema. - return array( - 'wc_database_version' => get_option( 'woocommerce_db_version' ), - 'database_prefix' => $wpdb->prefix, - 'maxmind_geoip_database' => \WC_Geolocation::get_local_database_path(), - 'database_tables' => $tables, - 'database_size' => $database_size, - ); - } -} diff --git a/src/Controllers/Version4/Utilities/Pagination.php b/src/Controllers/Version4/Utilities/Pagination.php deleted file mode 100644 index 68336424fa6..00000000000 --- a/src/Controllers/Version4/Utilities/Pagination.php +++ /dev/null @@ -1,81 +0,0 @@ -header( 'X-WP-Total', $total_items ); - $response->header( 'X-WP-TotalPages', $total_pages ); - - $current_page = self::get_current_page( $request ); - $link_base = self::get_link_base( $request ); - - if ( $current_page > 1 ) { - $previous_page = $current_page - 1; - if ( $previous_page > $total_pages ) { - $previous_page = $total_pages; - } - self::add_page_link( $response, 'prev', $previous_page, $link_base ); - } - - if ( $total_pages > $current_page ) { - self::add_page_link( $response, 'next', ( $current_page + 1 ), $link_base ); - } - - return $response; - } - - /** - * Get current page. - * - * @param \WP_REST_Request $request The request object. - * @return int Get the page from the request object. - */ - protected static function get_current_page( $request ) { - return (int) $request->get_param( 'page' ); - } - - /** - * Get base for links from the request object. - * - * @param \WP_REST_Request $request The request object. - * @return string - */ - protected static function get_link_base( $request ) { - return add_query_arg( $request->get_query_params(), rest_url( $request->get_route() ) ); - } - - /** - * Add a page link. - * - * @param \WP_REST_Response $response Reference to the response object. - * @param string $name Page link name. e.g. prev. - * @param int $page Page number. - * @param string $link_base Base URL. - */ - protected static function add_page_link( &$response, $name, $page, $link_base ) { - $response->link_header( $name, add_query_arg( 'page', $page, $link_base ) ); - } -} diff --git a/src/Controllers/Version4/Utilities/Permissions.php b/src/Controllers/Version4/Utilities/Permissions.php deleted file mode 100644 index cb42a1150d8..00000000000 --- a/src/Controllers/Version4/Utilities/Permissions.php +++ /dev/null @@ -1,238 +0,0 @@ - [ - 'read' => 'read_shop_coupon', - 'list' => 'read_private_shop_coupons', - 'create' => 'publish_shop_coupons', - 'edit' => 'edit_shop_coupon', - 'delete' => 'delete_shop_coupon', - 'batch' => 'edit_others_shop_coupons', - ], - 'customer_download' => [ - 'read' => 'read_shop_order', - 'list' => 'read_private_shop_orders', - 'create' => 'publish_shop_orders', - 'edit' => 'edit_shop_order', - 'delete' => 'delete_shop_order', - 'batch' => 'edit_others_shop_orders', - ], - 'customer' => [ - 'read' => 'list_users', - 'list' => 'list_users', - 'create' => 'promote_users', - 'edit' => 'edit_users', - 'delete' => 'delete_users', - 'batch' => 'promote_users', - ], - 'shop_order' => [ - 'read' => 'read_shop_order', - 'list' => 'read_private_shop_orders', - 'create' => 'publish_shop_orders', - 'edit' => 'edit_shop_order', - 'delete' => 'delete_shop_order', - 'batch' => 'edit_others_shop_orders', - ], - 'product_attribute' => 'edit_product_terms', - 'product_attribute_term' => [ - 'read' => 'manage_product_terms', - 'list' => 'manage_product_terms', - 'create' => 'edit_product_terms', - 'edit' => 'edit_product_terms', - 'delete' => 'delete_product_terms', - 'batch' => 'edit_product_terms', - ], - 'product_cat' => [ - 'read' => 'manage_product_terms', - 'list' => 'manage_product_terms', - 'create' => 'edit_product_terms', - 'edit' => 'edit_product_terms', - 'delete' => 'delete_product_terms', - 'batch' => 'edit_product_terms', - ], - 'product_review' => 'moderate_comments', - 'product' => [ - 'read' => 'read_product', - 'list' => 'read_private_products', - 'create' => 'publish_products', - 'edit' => 'edit_product', - 'delete' => 'delete_product', - 'batch' => 'edit_others_products', - ], - 'product_shipping_class' => [ - 'read' => 'manage_product_terms', - 'list' => 'manage_product_terms', - 'create' => 'edit_product_terms', - 'edit' => 'edit_product_terms', - 'delete' => 'delete_product_terms', - 'batch' => 'edit_product_terms', - ], - 'product_tag' => [ - 'read' => 'manage_product_terms', - 'list' => 'manage_product_terms', - 'create' => 'edit_product_terms', - 'edit' => 'edit_product_terms', - 'delete' => 'delete_product_terms', - 'batch' => 'edit_product_terms', - ], - 'product_variation' => [ - 'read' => 'read_product', - 'list' => 'read_private_products', - 'create' => 'publish_products', - 'edit' => 'edit_product', - 'delete' => 'delete_product', - 'batch' => 'edit_others_products', - ], - ); - - /** - * Get capabilities required for a resource for a given context. - * - * @param string $type Item/resource type. Comes from schema title. - * @param string $context Read, edit, delete, batch, create. - * @return array List of caps to check. Defaults to manage_woocommerce. - */ - protected static function get_capabilities_for_type( $type, $context = 'read' ) { - if ( isset( self::$capabilities[ $type ][ $context ] ) ) { - $caps = self::$capabilities[ $type ][ $context ]; - } elseif ( isset( self::$capabilities[ $type ] ) ) { - $caps = self::$capabilities[ $type ]; - } else { - $caps = 'manage_woocommerce'; - } - return is_array( $caps ) ? $caps : array( $caps ); - } - - /** - * Check if user has a list of caps. - * - * @param array $capabilities List of caps to check. - * @param int $object_id Object ID to check. Optional. - * @return boolean - */ - protected static function has_required_capabilities( $capabilities, $object_id = null ) { - $permission = true; - - foreach ( $capabilities as $capability ) { - if ( ! current_user_can( $capability, $object_id ) ) { - $permission = false; - } - } - - return $permission; - } - - /** - * Check if user can list a collection of resources. - * - * @param string $type Item/resource type. Comes from schema title. - * @return bool True on success. - */ - public static function user_can_list( $type ) { - $capabilities = self::get_capabilities_for_type( $type, 'list' ); - $permission = self::has_required_capabilities( $capabilities ); - - return apply_filters( 'woocommerce_rest_user_can_list', $permission, $type ); - } - - /** - * Check if user can read a resource. - * - * @param string $type Item/resource type. Comes from schema title. - * @param int $object_id Resource ID. 0 to check access to read all. - * @return bool True on success. - */ - public static function user_can_read( $type, $object_id = 0 ) { - if ( 0 === $object_id ) { - return false; - } - - $capabilities = self::get_capabilities_for_type( $type, 'read' ); - $permission = self::has_required_capabilities( $capabilities, $object_id ); - - return apply_filters( 'woocommerce_rest_user_can_read', $permission, $type, $object_id ); - } - - /** - * Check if user can read a resource. - * - * @param string $type Item/resource type. Comes from schema title. - * @param int $object_id Resource ID. - * @return bool True on success. - */ - public static function user_can_edit( $type, $object_id ) { - if ( 0 === $object_id ) { - return false; - } - - $capabilities = self::get_capabilities_for_type( $type, 'edit' ); - $permission = self::has_required_capabilities( $capabilities, $object_id ); - - return apply_filters( 'woocommerce_rest_user_can_edit', $permission, $type, $object_id ); - } - - /** - * Check if user can create a resource. - * - * @param string $type Item/resource type. Comes from schema title. - * @return bool True on success. - */ - public static function user_can_create( $type ) { - $capabilities = self::get_capabilities_for_type( $type, 'create' ); - $permission = self::has_required_capabilities( $capabilities ); - - return apply_filters( 'woocommerce_rest_user_can_create', $permission, $type ); - } - - /** - * Check if user can delete a resource. - * - * @param string $type Item/resource type. Comes from schema title. - * @param int $object_id Resource ID. - * @return bool True on success. - */ - public static function user_can_delete( $type, $object_id ) { - if ( 0 === $object_id ) { - return false; - } - - $capabilities = self::get_capabilities_for_type( $type, 'delete' ); - $permission = self::has_required_capabilities( $capabilities, $object_id ); - - return apply_filters( 'woocommerce_rest_user_can_delete', $permission, $type, $object_id ); - } - - /** - * Check if user can batch update a resource. - * - * @param string $type Item/resource type. Comes from schema title. - * @return bool True on success. - */ - public static function user_can_batch( $type ) { - $capabilities = self::get_capabilities_for_type( $type, 'batch' ); - $permission = self::has_required_capabilities( $capabilities ); - - return apply_filters( 'woocommerce_rest_user_can_batch', $permission, $type ); - } -} diff --git a/src/Controllers/Version4/Utilities/PluginInformation.php b/src/Controllers/Version4/Utilities/PluginInformation.php deleted file mode 100644 index ee7645b63d7..00000000000 --- a/src/Controllers/Version4/Utilities/PluginInformation.php +++ /dev/null @@ -1,149 +0,0 @@ -available_updates = get_plugin_updates(); - } - - /** - * Get formatted active plugin data. - * - * @return array - */ - public function get_active_plugin_data() { - return array_map( [ $this, 'format_plugin_data' ], array_map( [ $this, 'get_plugin_data' ], $this->get_active_plugins() ) ); - } - - /** - * Get formatted inactive plugin data. - * - * @return array - */ - public function get_inactive_plugin_data() { - return array_map( [ $this, 'format_plugin_data' ], array_map( [ $this, 'get_plugin_data' ], $this->get_inactive_plugins() ) ); - } - - /** - * Get a list of Dropins and MU plugins. - * - * @since 3.6.0 - * @return array - */ - public function get_dropin_and_mu_plugin_data() { - $plugins = [ - 'dropins' => [], - 'mu_plugins' => [], - ]; - - foreach ( get_dropins() as $plugin => $data ) { - $data['plugin_file'] = $plugin; - $plugins['dropins'][] = $this->format_plugin_data( $data ); - } - - foreach ( get_mu_plugins() as $plugin => $data ) { - $data['plugin_file'] = $plugin; - $plugins['mu_plugins'][] = $this->format_plugin_data( $data ); - } - - return $plugins; - } - - /** - * Get a list of plugins active on the site. - * - * @return array - */ - protected function get_active_plugins() { - $active_plugins = (array) get_option( 'active_plugins', array() ); - - if ( is_multisite() ) { - $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); - $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); - } - - return $active_plugins; - } - - /** - * Get a list of inplugins active on the site. - * - * @return array - */ - protected function get_inactive_plugins() { - $plugins = get_plugins(); - $active_plugins = $this->get_active_plugins(); - $inactive_plugins = []; - - foreach ( $plugins as $plugin => $data ) { - if ( in_array( $plugin, $active_plugins, true ) ) { - continue; - } - $inactive_plugins[] = $plugin; - } - - return $inactive_plugins; - } - - /** - * Undocumented function - * - * @param string $plugin Plugin directory/file. - * @return array Data. - */ - protected function get_plugin_data( $plugin ) { - $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); - $data['plugin_file'] = $plugin; - return $data; - } - - /** - * Format plugin data, including data on updates, into a standard format. - * - * @param array $data Plugin data. - * @return array Formatted data. - */ - protected function format_plugin_data( $data ) { - $version_latest = $data['Version']; - - // Find latest version. - if ( isset( $this->available_updates[ $data['plugin_file'] ]->update->new_version ) ) { - $version_latest = $this->available_updates[ $data['plugin_file'] ]->update->new_version; - } - - return array( - 'plugin' => $data['plugin_file'], - 'name' => $data['Name'], - 'version' => $data['Version'], - 'version_latest' => $version_latest, - 'url' => $data['PluginURI'], - 'author_name' => $data['AuthorName'], - 'author_url' => esc_url_raw( $data['AuthorURI'] ), - 'network_activated' => $data['Network'], - ); - } -} diff --git a/src/Controllers/Version4/Utilities/ServerEnvironment.php b/src/Controllers/Version4/Utilities/ServerEnvironment.php deleted file mode 100644 index 9d89040e51e..00000000000 --- a/src/Controllers/Version4/Utilities/ServerEnvironment.php +++ /dev/null @@ -1,187 +0,0 @@ -test_post_request(); - $get_request = $this->test_get_request(); - $database_version = wc_get_server_database_version(); - - // Return all environment info. Described by JSON Schema. - return array( - 'home_url' => get_option( 'home' ), - 'site_url' => get_option( 'siteurl' ), - 'version' => WC()->version, - 'log_directory' => \WC_LOG_DIR, - 'log_directory_writable' => (bool) @fopen( \WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore - 'wp_version' => get_bloginfo( 'version' ), - 'wp_multisite' => is_multisite(), - 'wp_memory_limit' => $this->get_wp_memory_limit(), - 'wp_debug_mode' => $this->is_constant_true( 'WP_DEBUG' ), - 'wp_cron' => ! $this->is_constant_true( 'DISABLE_WP_CRON' ), - 'language' => get_locale(), - 'external_object_cache' => wp_using_ext_object_cache(), - 'server_info' => $this->get_server_software(), - 'php_version' => phpversion(), - 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), - 'php_max_execution_time' => ini_get( 'max_execution_time' ), - 'php_max_input_vars' => ini_get( 'max_input_vars' ), - 'curl_version' => $this->get_curl_version(), - 'suhosin_installed' => extension_loaded( 'suhosin' ), - 'max_upload_size' => wp_max_upload_size(), - 'mysql_version' => $database_version['number'], - 'mysql_version_string' => $database_version['string'], - 'default_timezone' => date_default_timezone_get(), - 'fsockopen_or_curl_enabled' => $this->fsockopen_or_curl_enabled(), - 'soapclient_enabled' => class_exists( 'SoapClient' ), - 'domdocument_enabled' => class_exists( 'DOMDocument' ), - 'gzip_enabled' => is_callable( 'gzopen' ), - 'mbstring_enabled' => extension_loaded( 'mbstring' ), - 'remote_post_successful' => $post_request['success'], - 'remote_post_response' => $post_request['response'], - 'remote_get_successful' => $get_request['success'], - 'remote_get_response' => $get_request['response'], - ); - } - - /** - * Test POST to an external server. - * - * @return array - */ - protected function test_post_request() { - $post_response_code = get_transient( 'woocommerce_test_remote_post' ); - - if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { - $response = wp_safe_remote_post( - 'https://www.paypal.com/cgi-bin/webscr', - array( - 'timeout' => 10, - 'user-agent' => 'WooCommerce/' . WC()->version, - 'httpversion' => '1.1', - 'body' => array( - 'cmd' => '_notify-validate', - ), - ) - ); - if ( ! is_wp_error( $response ) ) { - $post_response_code = $response['response']['code']; - } - set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); - } - - if ( is_wp_error( $post_response_code ) ) { - return array( - 'success' => false, - 'response' => $post_response_code->get_error_message(), - ); - } - - return array( - 'success' => $post_response_code >= 200 && $post_response_code < 300, - 'response' => $post_response_code, - ); - } - - /** - * Test GET to an external server. - * - * @return array - */ - protected function test_get_request() { - $get_response_code = get_transient( 'woocommerce_test_remote_get' ); - - if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { - $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); - if ( ! is_wp_error( $response ) ) { - $get_response_code = $response['response']['code']; - } - set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); - } - - if ( is_wp_error( $get_response_code ) ) { - return array( - 'success' => false, - 'response' => $get_response_code->get_error_message(), - ); - } - - return array( - 'success' => $get_response_code >= 200 && $get_response_code < 300, - 'response' => $get_response_code, - ); - } - - /** - * Return if a constant is defined and true. - * - * @param string $name Constant name. - * @return bool - */ - protected function is_constant_true( $name ) { - return defined( $name ) && (bool) constant( $name ); - } - - /** - * Return info about server software running. - * - * @return string - */ - protected function get_server_software() { - return isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : ''; - } - - /** - * Get CURL version running on server. - * - * @return string - */ - protected function get_curl_version() { - $curl_version = ''; - if ( function_exists( 'curl_version' ) ) { - $curl_version = curl_version(); - $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; - } elseif ( extension_loaded( 'curl' ) ) { - $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce-rest-api' ); - } - return $curl_version; - } - - /** - * Get WP memory limit. - * - * @return string - */ - protected function get_wp_memory_limit() { - $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); - if ( function_exists( 'memory_get_usage' ) ) { - $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); - } - return (string) $wp_memory_limit; - } - - /** - * See if modules are enabled. - * - * @return bool - */ - protected function fsockopen_or_curl_enabled() { - return function_exists( 'fsockopen' ) || function_exists( 'curl_init' ); - } - -} diff --git a/src/Controllers/Version4/Utilities/SettingsTrait.php b/src/Controllers/Version4/Utilities/SettingsTrait.php deleted file mode 100644 index f5ac8f64590..00000000000 --- a/src/Controllers/Version4/Utilities/SettingsTrait.php +++ /dev/null @@ -1,152 +0,0 @@ - 400 ) ); - } - } - - /** - * Validate multiselect based settings. - * - * @since 3.0.0 - * @param array $values Values. - * @param array $setting Setting. - * @return array|\WP_Error - */ - public function validate_setting_multiselect_field( $values, $setting ) { - if ( empty( $values ) ) { - return array(); - } - - if ( ! is_array( $values ) ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $final_values = array(); - foreach ( $values as $value ) { - if ( array_key_exists( $value, $setting['options'] ) ) { - $final_values[] = $value; - } - } - - return $final_values; - } - - /** - * Validate image_width based settings. - * - * @since 3.0.0 - * @param array $values Values. - * @param array $setting Setting. - * @return string|\WP_Error - */ - public function validate_setting_image_width_field( $values, $setting ) { - if ( ! is_array( $values ) ) { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $current = $setting['value']; - if ( isset( $values['width'] ) ) { - $current['width'] = intval( $values['width'] ); - } - if ( isset( $values['height'] ) ) { - $current['height'] = intval( $values['height'] ); - } - if ( isset( $values['crop'] ) ) { - $current['crop'] = (bool) $values['crop']; - } - return $current; - } - - /** - * Validate radio based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string|\WP_Error - */ - public function validate_setting_radio_field( $value, $setting ) { - return $this->validate_setting_select_field( $value, $setting ); - } - - /** - * Validate checkbox based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string|\WP_Error - */ - public function validate_setting_checkbox_field( $value, $setting ) { - if ( in_array( $value, array( 'yes', 'no' ), true ) ) { - return $value; - } elseif ( empty( $value ) ) { - $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; - return $value; - } else { - return new \WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - /** - * Validate textarea based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string - */ - public function validate_setting_textarea_field( $value, $setting ) { - $value = is_null( $value ) ? '' : $value; - return wp_kses( - trim( stripslashes( $value ) ), - array_merge( - array( - 'iframe' => array( - 'src' => true, - 'style' => true, - 'id' => true, - 'class' => true, - ), - ), - wp_kses_allowed_html( 'post' ) - ) - ); - } -} diff --git a/src/Controllers/Version4/Utilities/ThemeInformation.php b/src/Controllers/Version4/Utilities/ThemeInformation.php deleted file mode 100644 index fb99a3a48aa..00000000000 --- a/src/Controllers/Version4/Utilities/ThemeInformation.php +++ /dev/null @@ -1,96 +0,0 @@ -template ); - $parent_theme_info = array( - 'parent_name' => $parent_theme->name, - 'parent_version' => $parent_theme->version, - 'parent_version_latest' => \WC_Admin_Status::get_latest_theme_version( $parent_theme ), - 'parent_author_url' => $parent_theme->{'Author URI'}, - ); - } else { - $parent_theme_info = array( - 'parent_name' => '', - 'parent_version' => '', - 'parent_version_latest' => '', - 'parent_author_url' => '', - ); - } - - /** - * Scan the theme directory for all WC templates to see if our theme - * overrides any of them. - */ - $override_files = array(); - $outdated_templates = false; - $scan_files = \WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); - foreach ( $scan_files as $file ) { - $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' ); - - if ( file_exists( $located ) ) { - $theme_file = $located; - } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { - $theme_file = get_stylesheet_directory() . '/' . $file; - } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { - $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; - } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { - $theme_file = get_template_directory() . '/' . $file; - } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { - $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; - } else { - $theme_file = false; - } - - if ( ! empty( $theme_file ) ) { - $core_version = \WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); - $theme_version = \WC_Admin_Status::get_file_version( $theme_file ); - if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { - if ( ! $outdated_templates ) { - $outdated_templates = true; - } - } - $override_files[] = array( - 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), - 'version' => $theme_version, - 'core_version' => $core_version, - ); - } - } - - $active_theme_info = array( - 'name' => $active_theme->name, - 'version' => $active_theme->version, - 'version_latest' => \WC_Admin_Status::get_latest_theme_version( $active_theme ), - 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), - 'is_child_theme' => is_child_theme(), - 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), - 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), - 'has_outdated_templates' => $outdated_templates, - 'overrides' => $override_files, - ); - - return array_merge( $active_theme_info, $parent_theme_info ); - } -} diff --git a/src/Controllers/Version4/Utilities/WPEnvironment.php b/src/Controllers/Version4/Utilities/WPEnvironment.php deleted file mode 100644 index 1e0b2edf449..00000000000 --- a/src/Controllers/Version4/Utilities/WPEnvironment.php +++ /dev/null @@ -1,115 +0,0 @@ - 'https' === substr( $check_page, 0, 5 ), - 'hide_errors' => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), - ); - } - - /** - * Get array of counts of objects. Orders, products, etc. - * - * @return array - */ - public function get_post_type_counts() { - global $wpdb; - - $post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" ); - - return is_array( $post_type_counts ) ? $post_type_counts : array(); - } - - /** - * Returns a mini-report on WC pages and if they are configured correctly: - * Present, visible, and including the correct shortcode. - * - * @return array - */ - public function get_pages() { - // WC pages to check against. - $check_pages = array( - _x( 'Shop base', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_shop_page_id', - 'shortcode' => '', - ), - _x( 'Cart', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_cart_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', - ), - _x( 'Checkout', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_checkout_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', - ), - _x( 'My account', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_myaccount_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', - ), - _x( 'Terms and conditions', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_terms_page_id', - 'shortcode' => '', - ), - ); - - $pages_output = array(); - foreach ( $check_pages as $page_name => $values ) { - $page_id = get_option( $values['option'] ); - $page_set = false; - $page_exists = false; - $page_visible = false; - $shortcode_present = false; - $shortcode_required = false; - - // Page checks. - if ( $page_id ) { - $page_set = true; - } - if ( get_post( $page_id ) ) { - $page_exists = true; - } - if ( 'publish' === get_post_status( $page_id ) ) { - $page_visible = true; - } - - // Shortcode checks. - if ( $values['shortcode'] && get_post( $page_id ) ) { - $shortcode_required = true; - $page = get_post( $page_id ); - if ( strstr( $page->post_content, $values['shortcode'] ) ) { - $shortcode_present = true; - } - } - - // Wrap up our findings into an output array. - $pages_output[] = array( - 'page_name' => $page_name, - 'page_id' => $page_id, - 'page_set' => $page_set, - 'page_exists' => $page_exists, - 'page_visible' => $page_visible, - 'shortcode' => $values['shortcode'], - 'shortcode_required' => $shortcode_required, - 'shortcode_present' => $shortcode_present, - ); - } - - return $pages_output; - } -} diff --git a/src/Controllers/Version4/Utilities/WooEnvironment.php b/src/Controllers/Version4/Utilities/WooEnvironment.php deleted file mode 100644 index c85fc24efc8..00000000000 --- a/src/Controllers/Version4/Utilities/WooEnvironment.php +++ /dev/null @@ -1,59 +0,0 @@ - 0 ) ); - foreach ( $terms as $term ) { - $term_response[ $term->slug ] = strtolower( $term->name ); - } - - // Get a list of terms used for product visibility. - $product_visibility_terms = array(); - $terms = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) ); - foreach ( $terms as $term ) { - $product_visibility_terms[ $term->slug ] = strtolower( $term->name ); - } - - // Check if WooCommerce.com account is connected. - $woo_com_connected = 'no'; - $helper_options = get_option( 'woocommerce_helper_data', array() ); - if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) { - $woo_com_connected = 'yes'; - } - - // Return array of useful settings for debugging. - return array( - 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ), - 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ), - 'currency' => get_woocommerce_currency(), - 'currency_symbol' => get_woocommerce_currency_symbol(), - 'currency_position' => get_option( 'woocommerce_currency_pos' ), - 'thousand_separator' => wc_get_price_thousand_separator(), - 'decimal_separator' => wc_get_price_decimal_separator(), - 'number_of_decimals' => wc_get_price_decimals(), - 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ), - 'taxonomies' => $term_response, - 'product_visibility_terms' => $product_visibility_terms, - 'woocommerce_com_connected' => $woo_com_connected, - ); - } -} diff --git a/src/Controllers/Version4/Webhooks.php b/src/Controllers/Version4/Webhooks.php deleted file mode 100644 index 360661844a9..00000000000 --- a/src/Controllers/Version4/Webhooks.php +++ /dev/null @@ -1,685 +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(), - ), - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), - array( - 'topic' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), - ), - 'delivery_url' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Webhook delivery URL.', 'woocommerce-rest-api' ), - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => \WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ), - true - ); - - $this->register_batch_route(); - } - - /** - * Get the default REST API version. - * - * @since 3.0.0 - * @return string - */ - protected function get_default_api_version() { - return 'wp_api_v4'; - } - - /** - * Get all webhooks. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_items( $request ) { - $args = array(); - $args['order'] = $request['order']; - $args['orderby'] = $request['orderby']; - $args['status'] = 'all' === $request['status'] ? '' : $request['status']; - $args['include'] = implode( ',', $request['include'] ); - $args['exclude'] = implode( ',', $request['exclude'] ); - $args['limit'] = $request['per_page']; - $args['search'] = $request['search']; - $args['before'] = $request['before']; - $args['after'] = $request['after']; - - if ( empty( $request['offset'] ) ) { - $args['offset'] = 1 < $request['page'] ? ( $request['page'] - 1 ) * $args['limit'] : 0; - } - - /** - * Filter arguments, before passing to WC_Webhook_Data_Store->search_webhooks, when querying webhooks via the REST API. - * - * @param array $args Array of arguments for $wpdb->get_results(). - * @param \WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request ); - unset( $prepared_args['page'] ); - $prepared_args['paginate'] = true; - - // Get the webhooks. - $webhooks = array(); - $data_store = \WC_Data_Store::load( 'webhook' ); - $results = $data_store->search_webhooks( $prepared_args ); - $webhook_ids = $results->webhooks; - - foreach ( $webhook_ids as $webhook_id ) { - $object = $this->get_object( $webhook_id ); - - if ( ! $object || 0 === $object->get_id() ) { - continue; - } - - $data = $this->prepare_item_for_response( $object, $request ); - $webhooks[] = $this->prepare_response_for_collection( $data ); - } - - - $total_webhooks = $results->total; - $max_pages = $results->max_num_pages; - $response = rest_ensure_response( $webhooks ); - $response = Pagination::add_pagination_headers( $response, $request, $total_webhooks, $max_pages ); - - return $response; - } - - /** - * Get object. - * - * @param int $id Object ID. - * @return \WC_Webhook|bool - */ - protected function get_object( $id ) { - $webhook = wc_get_webhook( $id ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return false; - } - - return $webhook; - } - - /** - * Get a single item. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function get_item( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( ! $object || 0 === $object->get_id() ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - return $this->prepare_item_for_response( $object, $request ); - } - - /** - * Create a single webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - // Validate topic. - if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - // Validate delivery URL. - if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $post = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $post ) ) { - return $post; - } - - $webhook = new \WC_Webhook(); - $webhook->set_name( $post->post_title ); - $webhook->set_user_id( $post->post_author ); - $webhook->set_status( 'publish' === $post->post_status ? 'active' : 'disabled' ); - $webhook->set_topic( $request['topic'] ); - $webhook->set_delivery_url( $request['delivery_url'] ); - $webhook->set_secret( ! empty( $request['secret'] ) ? $request['secret'] : wp_generate_password( 50, true, true ) ); - $webhook->set_api_version( $this->get_default_api_version() ); - $webhook->save(); - - $this->update_additional_fields_for_object( $webhook, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WC_Webhook $webhook Webhook data. - * @param \WP_REST_Request $request Request object. - * @param bool $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $webhook, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $webhook->get_id() ) ) ); - - // Send ping. - $webhook->deliver_ping(); - - return $response; - } - - /** - * Update a single webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function update_item( $request ) { - $id = (int) $request['id']; - $webhook = wc_get_webhook( $id ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - // Update topic. - if ( ! empty( $request['topic'] ) ) { - if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { - $webhook->set_topic( $request['topic'] ); - } else { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - // Update delivery URL. - if ( ! empty( $request['delivery_url'] ) ) { - if ( wc_is_valid_url( $request['delivery_url'] ) ) { - $webhook->set_delivery_url( $request['delivery_url'] ); - } else { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - // Update secret. - if ( ! empty( $request['secret'] ) ) { - $webhook->set_secret( $request['secret'] ); - } - - // Update status. - if ( ! empty( $request['status'] ) ) { - if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { - $webhook->set_status( $request['status'] ); - } else { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - $post = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $post ) ) { - return $post; - } - - if ( isset( $post->post_title ) ) { - $webhook->set_name( $post->post_title ); - } - - $webhook->save(); - - $this->update_additional_fields_for_object( $webhook, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WC_Webhook $webhook Webhook data. - * @param \WP_REST_Request $request Request object. - * @param bool $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $webhook, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Delete a single webhook. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_REST_Response|\WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $webhook = wc_get_webhook( $id ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $request->set_param( 'context', 'edit' ); - $previous = $this->prepare_item_for_response( $webhook, $request ); - $result = $webhook->delete( true ); - if ( ! $result ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); - } - $response = new \WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - - /** - * Fires after a single item is deleted or trashed via the REST API. - * - * @param WC_Webhook $webhook The deleted or trashed item. - * @param \WP_REST_Response $response The response data. - * @param \WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_webhook_object', $webhook, $response, $request ); - - return $response; - } - - /** - * Prepare a single webhook for create or update. - * - * @param \WP_REST_Request $request Request object. - * @return \WP_Error|stdClass $data Post object. - */ - protected function prepare_item_for_database( $request ) { - $data = new \stdClass(); - - // Post ID. - if ( isset( $request['id'] ) ) { - $data->ID = absint( $request['id'] ); - } - - // Validate required POST fields. - if ( 'POST' === $request->get_method() && empty( $data->ID ) ) { - $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce-rest-api' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce-rest-api' ) ) ); // @codingStandardsIgnoreLine - - // Post author. - $data->post_author = get_current_user_id(); - - // Post password. - $data->post_password = 'webhook_' . wp_generate_password(); - - // Post status. - $data->post_status = 'publish'; - } else { - - // Allow edit post title. - if ( ! empty( $request['name'] ) ) { - $data->post_title = $request['name']; - } - } - - // Comment status. - $data->comment_status = 'closed'; - - // Ping status. - $data->ping_status = 'closed'; - - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for insertion. - * - * @param \stdClass $data An object representing a single item prepared - * for inserting or updating the database. - * @param \WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $data, $request ); - } - - /** - * Get data for this object in the format of this endpoint's schema. - * - * @param \WC_Webhook $object Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array Array of data in the correct format. - */ - protected function get_data_for_response( $object, $request ) { - return array( - 'id' => $object->get_id(), - 'name' => $object->get_name(), - 'status' => $object->get_status(), - 'topic' => $object->get_topic(), - 'resource' => $object->get_resource(), - 'event' => $object->get_event(), - 'hooks' => $object->get_hooks(), - 'delivery_url' => $object->get_delivery_url(), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), - ); - } - - /** - * Prepare links for the request. - * - * @param mixed $item Object to prepare. - * @param \WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $item, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the Webhook's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'webhook', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Webhook status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'active', - 'enum' => array_keys( wc_get_webhook_statuses() ), - 'context' => array( 'view', 'edit' ), - ), - 'topic' => array( - 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'resource' => array( - 'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'event' => array( - 'description' => __( 'Webhook event.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'hooks' => array( - 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'delivery_url' => array( - 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'secret' => array( - 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['context']['default'] = 'view'; - - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'id', - 'title', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['status'] = array( - 'default' => 'all', - 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array( 'all', 'active', 'paused', 'disabled' ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - - /** - * Return suffix for item action hooks. - * - * @return string - */ - protected function get_hook_suffix() { - return $this->post_type; - } -} diff --git a/src/Controllers/Version4/_changelog.md b/src/Controllers/Version4/_changelog.md deleted file mode 100644 index 3c98ab73b96..00000000000 --- a/src/Controllers/Version4/_changelog.md +++ /dev/null @@ -1,31 +0,0 @@ -# REST API v4 Change-log - -## Changes - -- All endpoints - Rewritten with namespaces as standalone classes. -- All endpoints - Normalized DELETE responses to return previous object. -- Coupons - Added `search` parameter. -- Orders - Added order number to schema. -- Orders - Added currency_symbol to schema. -- Product Reviews - Updated response links. -- Products - Added `low_in_stock` and `search` parameter. -- Product Variations - Added `search` parameter. -- Product Variations - Added `name`, `type`, `parent_id` to schema. -- Reports - Updated with updated list of available reports. -- Taxes - Added `code` and `include` params. -- Coupons/Orders/Products - Allow to sort by `modified` date. -- Coupons/Orders/Products - Added `date_column` property to use date, date_gmt, modified, modified_gmt in conjunction with before/after. - -## New endpoints - -- `data/download-ips` - -## Removed endpoints - -- `reports/top_sellers` -- `reports/sales` -- `reports/customers/totals` -- `reports/orders/totals` -- `reports/coupons/totals` -- `reports/reviews/totals` -- `reports/products/totals` diff --git a/src/Package.php b/src/Package.php index 6660b41560f..ec3cc6474d2 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.1.0-dev'; + const VERSION = '1.0.0'; /** * Init the package - load the REST API Server class. diff --git a/src/Server.php b/src/Server.php index f025003aba4..1c589c0da75 100644 --- a/src/Server.php +++ b/src/Server.php @@ -55,7 +55,6 @@ class Server { 'wc/v1' => $this->get_v1_controllers(), 'wc/v2' => $this->get_v2_controllers(), 'wc/v3' => $this->get_v3_controllers(), - 'wc/v4' => $this->get_v4_controllers(), ] ); } @@ -179,49 +178,4 @@ class Server { 'data-currencies' => 'WC_REST_Data_Currencies_Controller', ]; } - - /** - * List of controllers in the wc/v4 namespace. - * - * @return array - */ - protected function get_v4_controllers() { - $namespace = __NAMESPACE__ . '\\Controllers\\Version4\\'; - $controllers = [ - 'coupons' => $namespace . 'Coupons', - 'customer-downloads' => $namespace . 'CustomerDownloads', - 'customers' => $namespace . 'Customers', - 'data' => $namespace . 'Data', - 'data-continents' => $namespace . 'Data\Continents', - 'data-countries' => $namespace . 'Data\Countries', - 'data-currencies' => $namespace . 'Data\Currencies', - 'data-download-ips' => $namespace . 'Data\DownloadIPs', - 'network-orders' => $namespace . 'NetworkOrders', - 'order-notes' => $namespace . 'OrderNotes', - 'order-refunds' => $namespace . 'OrderRefunds', - 'orders' => $namespace . 'Orders', - 'payment-gateways' => $namespace . 'PaymentGateways', - 'product-attributes' => $namespace . 'ProductAttributes', - 'product-attribute-terms' => $namespace . 'ProductAttributeTerms', - 'product-categories' => $namespace . 'ProductCategories', - 'product-reviews' => $namespace . 'ProductReviews', - 'products' => $namespace . 'Products', - 'product-shipping-classes' => $namespace . 'ProductShippingClasses', - 'product-tags' => $namespace . 'ProductTags', - 'product-variations' => $namespace . 'ProductVariations', - 'settings' => $namespace . 'Settings', - 'settings-options' => $namespace . 'SettingsOptions', - 'shipping-methods' => $namespace . 'ShippingMethods', - 'shipping-zone-locations' => $namespace . 'ShippingZoneLocations', - 'shipping-zone-methods' => $namespace . 'ShippingZoneMethods', - 'shipping-zones' => $namespace . 'ShippingZones', - 'system-status' => $namespace . 'SystemStatus', - 'system-status-tools' => $namespace . 'SystemStatusTools', - 'tax-classes' => $namespace . 'TaxClasses', - 'taxes' => $namespace . 'Taxes', - 'webhooks' => $namespace . 'Webhooks', - ]; - - return $controllers; - } } diff --git a/unit-tests/Tests/Version4/Coupons.php b/unit-tests/Tests/Version4/Coupons.php deleted file mode 100644 index fef7f35776b..00000000000 --- a/unit-tests/Tests/Version4/Coupons.php +++ /dev/null @@ -1,319 +0,0 @@ -[\d]+)', - '/wc/v4/coupons/batch', - ]; - - /** - * The endpoint schema. - * - * @var array Keys are property names, values are supported context. - */ - protected $properties = [ - 'id' => array( 'view', 'edit' ), - 'code' => array( 'view', 'edit' ), - 'amount' => array( 'view', 'edit' ), - 'date_created' => array( 'view', 'edit' ), - 'date_created_gmt' => array( 'view', 'edit' ), - 'date_modified' => array( 'view', 'edit' ), - 'date_modified_gmt' => array( 'view', 'edit' ), - 'discount_type' => array( 'view', 'edit' ), - 'description' => array( 'view', 'edit' ), - 'date_expires' => array( 'view', 'edit' ), - 'date_expires_gmt' => array( 'view', 'edit' ), - 'usage_count' => array( 'view', 'edit' ), - 'individual_use' => array( 'view', 'edit' ), - 'product_ids' => array( 'view', 'edit' ), - 'excluded_product_ids' => array( 'view', 'edit' ), - 'usage_limit' => array( 'view', 'edit' ), - 'usage_limit_per_user' => array( 'view', 'edit' ), - 'limit_usage_to_x_items' => array( 'view', 'edit' ), - 'free_shipping' => array( 'view', 'edit' ), - 'product_categories' => array( 'view', 'edit' ), - 'excluded_product_categories' => array( 'view', 'edit' ), - 'exclude_sale_items' => array( 'view', 'edit' ), - 'minimum_amount' => array( 'view', 'edit' ), - 'maximum_amount' => array( 'view', 'edit' ), - 'email_restrictions' => array( 'view', 'edit' ), - 'used_by' => array( 'view', 'edit' ), - 'meta_data' => array( 'view', 'edit' ), - ]; - - /** - * Test create. - */ - public function test_create() { - $valid_data = [ - 'code' => 'test-coupon', - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - 'description' => 'Test description.', - 'date_expires' => date( 'Y-m-d\T00:00:00', strtotime( '+1 day' ) ), - 'individual_use' => true, - 'product_ids' => [ 1, 2, 3 ], - 'excluded_product_ids' => [ 3, 4, 5 ], - 'usage_limit' => 10, - 'usage_limit_per_user' => 10, - 'limit_usage_to_x_items' => 10, - 'free_shipping' => false, - 'product_categories' => [ 1, 2, 3 ], - 'excluded_product_categories' => [ 3, 4, 5 ], - 'exclude_sale_items' => true, - 'minimum_amount' => '100', - 'maximum_amount' => '200', - 'email_restrictions' => [ 'test@test.com' ], - 'meta_data' => [ - [ - 'key' => 'test_key', - 'value' => 'test_value', - ] - ] - ]; - $response = $this->do_request( '/wc/v4/coupons', 'POST', $valid_data ); - $this->assertExpectedResponse( $response, 201, $valid_data ); - } - - /** - * Test read. - */ - public function test_read() { - $coupon1 = CouponHelper::create_coupon( 'testcoupon-1' ); - $coupon2 = CouponHelper::create_coupon( 'testcoupon-2' ); - $coupon3 = CouponHelper::create_coupon( 'anothertestcoupon-3' ); - $coupon4 = CouponHelper::create_coupon( 'anothertestcoupon-4' ); - - // Collection. - $response = $this->do_request( '/wc/v4/coupons', 'GET' ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 4, count( $response->data ) ); - - // Collection args. - $response = $this->do_request( '/wc/v4/coupons', 'GET', [ 'code' => 'testcoupon-1' ] ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 1, count( $response->data ) ); - - $response = $this->do_request( '/wc/v4/coupons', 'GET', [ 'search' => 'anothertestcoupon' ] ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 2, count( $response->data ) ); - - // Single. - $response = $this->do_request( '/wc/v4/coupons/' . $coupon1->get_id(), 'GET' ); - $this->assertExpectedResponse( $response, 200 ); - - foreach ( $this->get_properties( 'view' ) as $property ) { - $this->assertArrayHasKey( $property, $response->data ); - } - - // Invalid. - $response = $this->do_request( '/wc/v4/coupons/0', 'GET' ); - $this->assertExpectedResponse( $response, 404 ); - } - - /** - * Test update. - */ - public function test_update() { - // Invalid. - $response = $this->do_request( '/wc/v4/coupons/0', 'POST', [ 'code' => 'test' ] ); - $this->assertExpectedResponse( $response, 404 ); - - // Update existing. - $coupon = CouponHelper::create_coupon( 'testcoupon-1' ); - $response = $this->do_request( - '/wc/v4/coupons/' . $coupon->get_id(), - 'POST', - [ - 'code' => 'new-code', - 'description' => 'new description', - ] - ); - $this->assertExpectedResponse( $response, 200 ); - - foreach ( $this->get_properties( 'view' ) as $property ) { - $this->assertArrayHasKey( $property, $response->data ); - } - - $this->assertEquals( $coupon->get_id(), $response->data['id'] ); - $this->assertEquals( 'new-code', $response->data['code'] ); - $this->assertEquals( 'new description', $response->data['description'] ); - } - - /** - * Test delete. - */ - public function test_delete() { - // Invalid. - $result = $this->do_request( '/wc/v4/coupons/0', 'DELETE', [ 'force' => false ] ); - $this->assertEquals( 404, $result->status ); - - // Trash. - $coupon = CouponHelper::create_coupon( 'testcoupon-1' ); - - $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); - $this->assertEquals( 200, $result->status ); - $this->assertEquals( 'trash', get_post_status( $coupon->get_id() ) ); - - // Force. - $coupon = CouponHelper::create_coupon( 'testcoupon-2' ); - - $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => true ] ); - $this->assertEquals( 200, $result->status ); - $this->assertEquals( false, get_post( $coupon->get_id() ) ); - } - - /** - * Test read. - */ - public function test_guest_create() { - wp_set_current_user( 0 ); - $valid_data = [ - 'code' => 'test-coupon', - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - 'description' => 'Test description.', - 'date_expires' => date( 'Y-m-d\T00:00:00', strtotime( '+1 day' ) ), - 'individual_use' => true, - 'product_ids' => [ 1, 2, 3 ], - 'excluded_product_ids' => [ 3, 4, 5 ], - 'usage_limit' => 10, - 'usage_limit_per_user' => 10, - 'limit_usage_to_x_items' => 10, - 'free_shipping' => false, - 'product_categories' => [ 1, 2, 3 ], - 'excluded_product_categories' => [ 3, 4, 5 ], - 'exclude_sale_items' => true, - 'minimum_amount' => '100', - 'maximum_amount' => '200', - 'email_restrictions' => [ 'test@test.com' ], - 'meta_data' => [ - [ - 'key' => 'test_key', - 'value' => 'test_value', - ] - ] - ]; - $response = $this->do_request( '/wc/v4/coupons', 'POST', $valid_data ); - $this->assertExpectedResponse( $response, 401 ); - } - - /** - * Test read. - */ - public function test_guest_read() { - wp_set_current_user( 0 ); - $response = $this->do_request( '/wc/v4/coupons', 'GET' ); - $this->assertExpectedResponse( $response, 401 ); - } - - /** - * Test update. - */ - public function test_guest_update() { - wp_set_current_user( 0 ); - $coupon = CouponHelper::create_coupon( 'testcoupon-1' ); - $response = $this->do_request( - '/wc/v4/coupons/' . $coupon->get_id(), - 'POST', - [ - 'code' => 'new-code', - 'description' => 'new description', - ] - ); - $this->assertExpectedResponse( $response, 401 ); - } - - /** - * Test delete. - */ - public function test_guest_delete() { - wp_set_current_user( 0 ); - $coupon = CouponHelper::create_coupon( 'testcoupon-1' ); - $result = $this->do_request( '/wc/v4/coupons/' . $coupon->get_id(), 'DELETE', [ 'force' => false ] ); - $this->assertEquals( 401, $result->status ); - } - - /** - * Test validation. - */ - public function test_enum_discount_type() { - $result = $this->do_request( - '/wc/v4/coupons', - 'POST', - [ - 'code' => 'test', - 'amount' => '5.00', - 'discount_type' => 'fake', - ] - ); - - $this->assertEquals( 400, $result->status ); - $this->assertEquals( 'Invalid parameter(s): discount_type', $result->data['message'] ); - } - - /** - * Test a batch update. - */ - public function test_batch() { - $coupon_1 = CouponHelper::create_coupon( 'batchcoupon-1' ); - $coupon_2 = CouponHelper::create_coupon( 'batchcoupon-2' ); - $coupon_3 = CouponHelper::create_coupon( 'batchcoupon-3' ); - $coupon_4 = CouponHelper::create_coupon( 'batchcoupon-4' ); - - $result = $this->do_request( - '/wc/v4/coupons/batch', - 'POST', - array( - 'update' => array( - array( - 'id' => $coupon_1->get_id(), - 'amount' => '5.15', - ), - ), - 'delete' => array( - $coupon_2->get_id(), - $coupon_3->get_id(), - ), - 'create' => array( - array( - 'code' => 'new-coupon', - 'amount' => '11.00', - ), - ), - ) - ); - - $this->assertEquals( '5.15', $result->data['update'][0]['amount'] ); - $this->assertEquals( '11.00', $result->data['create'][0]['amount'] ); - $this->assertEquals( 'new-coupon', $result->data['create'][0]['code'] ); - $this->assertEquals( $coupon_2->get_id(), $result->data['delete'][0]['previous']['id'] ); - $this->assertEquals( $coupon_3->get_id(), $result->data['delete'][1]['previous']['id'] ); - - $result = $this->do_request( '/wc/v4/coupons' ); - $this->assertEquals( 3, count( $result->data ) ); - } -} diff --git a/unit-tests/Tests/Version4/Customers.php b/unit-tests/Tests/Version4/Customers.php deleted file mode 100644 index a04bb241c17..00000000000 --- a/unit-tests/Tests/Version4/Customers.php +++ /dev/null @@ -1,649 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server, endpoints, and user info. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - - $this->assertArrayHasKey( '/wc/v4/customers', $routes ); - $this->assertArrayHasKey( '/wc/v4/customers/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v4/customers/batch', $routes ); - } - - /** - * Test getting customers. - * - * @since 3.5.0 - */ - public function test_get_customers() { - $customer_1 = CustomerHelper::create_customer(); - CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/customers' ); - $request->set_query_params( - array( - 'orderby' => 'id', - ) - ); - $response = $this->server->dispatch( $request ); - $customers = $response->get_data(); - $date_created = get_date_from_gmt( date( 'Y-m-d H:i:s', strtotime( $customer_1->get_date_created() ) ) ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $customers ) ); - - $this->assertContains( - array( - 'id' => $customer_1->get_id(), - 'date_created' => wc_rest_prepare_date_response( $date_created, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $date_created ), - 'date_modified' => wc_rest_prepare_date_response( $customer_1->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_1->get_date_modified() ), - 'email' => 'test@woo.local', - 'first_name' => 'Justin', - 'last_name' => '', - 'role' => 'customer', - 'username' => 'testcustomer', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'avatar_url' => $customer_1->get_avatar_url(), - 'meta_data' => array(), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/customers/' . $customer_1->get_id() . '' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/customers' ), - ), - ), - ), - ), - $customers - ); - - update_option( 'timezone_tring', 'America/New York' ); - $customer_3 = CustomerHelper::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/customers' ); - $request->set_query_params( - array( - 'orderby' => 'id', - ) - ); - $response = $this->server->dispatch( $request ); - $customers = $response->get_data(); - $date_created = get_date_from_gmt( date( 'Y-m-d H:i:s', strtotime( $customer_3->get_date_created() ) ) ); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertContains( - array( - 'id' => $customer_3->get_id(), - 'date_created' => wc_rest_prepare_date_response( $date_created, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $date_created ), - 'date_modified' => wc_rest_prepare_date_response( $customer_3->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_3->get_date_modified() ), - 'email' => 'timezonetest@woo.local', - 'first_name' => 'Justin', - 'last_name' => '', - 'role' => 'customer', - 'username' => 'timezonetest', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'avatar_url' => $customer_3->get_avatar_url(), - 'meta_data' => array(), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/customers/' . $customer_3->get_id() . '' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/customers' ), - ), - ), - ), - ), - $customers - ); - - } - - /** - * Test getting customers without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_customers_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test creating a new customer. - * - * @since 3.5.0 - */ - public function test_create_customer() { - // Test just the basics first.. - $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test', - 'password' => 'test123', - 'email' => 'create_customer_test@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'create_customer_test@woo.local', - 'first_name' => '', - 'last_name' => '', - 'role' => 'customer', - 'username' => 'create_customer_test', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => '', - 'postcode' => '', - 'country' => '', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => '', - 'postcode' => '', - 'country' => '', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - - // Test extra data. - $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test2', - 'password' => 'test123', - 'email' => 'create_customer_test2@woo.local', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - 'billing' => array( - 'country' => 'US', - 'state' => 'WA', - ), - 'shipping' => array( - 'state' => 'CA', - 'country' => 'US', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'create_customer_test2@woo.local', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - 'role' => 'customer', - 'username' => 'create_customer_test2', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => 'WA', - 'postcode' => '', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => 'CA', - 'postcode' => '', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - - // Test without required field. - $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test3', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating customers without valid permissions. - * - * @since 3.5.0 - */ - public function test_create_customer_without_permission() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'POST', '/wc/v4/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test_without_permission', - 'password' => 'test123', - 'email' => 'create_customer_test_without_permission@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single customer. - * - * @since 3.5.0 - */ - public function test_get_customer() { - $customer = CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'get_customer_test@woo.local', - 'first_name' => 'Justin', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'last_name' => '', - 'role' => 'customer', - 'username' => 'get_customer_test', - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - } - - /** - * Test getting a single customer without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single customer with an invalid ID. - * - * @since 3.5.0 - */ - public function test_get_customer_invalid_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a customer. - * - * @since 3.5.0 - */ - public function test_update_customer() { - $customer = CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); - $data = $response->get_data(); - $this->assertEquals( 'update_customer_test', $data['username'] ); - $this->assertEquals( 'update_customer_test@woo.local', $data['email'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v4/customers/' . $customer->get_id() ); - $request->set_body_params( - array( - 'email' => 'updated_email@woo.local', - 'first_name' => 'UpdatedTest', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'updated_email@woo.local', $data['email'] ); - $this->assertEquals( 'UpdatedTest', $data['first_name'] ); - } - - /** - * Test updating a customer without valid permissions. - * - * @since 3.5.0 - */ - public function test_update_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/' . $customer->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a customer with an invalid ID. - * - * @since 3.5.0 - */ - public function test_update_customer_invalid_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/customers/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - - /** - * Test deleting a customer. - * - * @since 3.5.0 - */ - public function test_delete_customer() { - $customer = CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/' . $customer->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test deleting a customer with an invalid ID. - * - * @since 3.5.0 - */ - public function test_delete_customer_invalid_id() { - $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test deleting a customer without valid permissions. - * - * @since 3.5.0 - */ - public function test_delete_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v4/customers/' . $customer->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test customer batch endpoint. - * - * @since 3.5.0 - */ - public function test_batch_customer() { - $customer_1 = CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); - $customer_2 = CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); - $customer_3 = CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); - $customer_4 = CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); - - $request = new WP_REST_Request( 'POST', '/wc/v4/customers/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $customer_1->get_id(), - 'last_name' => 'McTest', - ), - ), - 'delete' => array( - $customer_2->get_id(), - $customer_3->get_id(), - ), - 'create' => array( - array( - 'username' => 'newuser', - 'password' => 'test123', - 'email' => 'newuser@woo.local', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'McTest', $data['update'][0]['last_name'] ); - $this->assertEquals( 'newuser', $data['create'][0]['username'] ); - $this->assertEmpty( $data['create'][0]['last_name'] ); - $this->assertEquals( $customer_2->get_id(), $data['delete'][0]['id'] ); - $this->assertEquals( $customer_3->get_id(), $data['delete'][1]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/customers' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Test customer schema. - * - * @since 3.5.0 - */ - public function test_customer_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/customers' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 16, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_created_gmt', $properties ); - $this->assertArrayHasKey( 'date_modified', $properties ); - $this->assertArrayHasKey( 'date_modified_gmt', $properties ); - $this->assertArrayHasKey( 'email', $properties ); - $this->assertArrayHasKey( 'first_name', $properties ); - $this->assertArrayHasKey( 'last_name', $properties ); - $this->assertArrayHasKey( 'role', $properties ); - $this->assertArrayHasKey( 'username', $properties ); - $this->assertArrayHasKey( 'password', $properties ); - $this->assertArrayHasKey( 'avatar_url', $properties ); - $this->assertArrayHasKey( 'billing', $properties ); - $this->assertArrayHasKey( 'first_name', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'last_name', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'company', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'address_1', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'address_2', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'city', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'state', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'postcode', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'country', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'email', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'phone', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'shipping', $properties ); - $this->assertArrayHasKey( 'first_name', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'last_name', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'company', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'address_1', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'address_2', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'city', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'state', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'postcode', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'country', $properties['shipping']['properties'] ); - } -} diff --git a/unit-tests/Tests/Version4/Data.php b/unit-tests/Tests/Version4/Data.php deleted file mode 100644 index 8dd440d2ba7..00000000000 --- a/unit-tests/Tests/Version4/Data.php +++ /dev/null @@ -1,133 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup test class. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - } - - /** - * Test that the list of data endpoints includes download-ips. - */ - public function test_get_items_contains_download_ips() { - $request = new \WP_REST_Request( 'GET', $this->endpoint ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 4, count( $data ) ); - $this->assertEquals( 'download-ips', $data[3]['slug'] ); - } - - /** - * Test download-ips match searching. - */ - public function test_download_ips() { - $prod_download = new \WC_Product_Download(); - $prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' ); - $prod_download->set_id( 1 ); - - $product = new \WC_Product_Simple(); - $product->set_name( 'Test Product' ); - $product->set_downloadable( 'yes' ); - $product->set_downloads( array( $prod_download ) ); - $product->set_regular_price( 25 ); - $product->save(); - - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); - $order->set_status( 'completed' ); - $order->set_total( 100 ); - $order->save(); - - $download = new \WC_Customer_Download(); - $download->set_user_id( $this->user ); - $download->set_order_id( $order->get_id() ); - $download->set_product_id( $product->get_id() ); - $download->set_download_id( $prod_download->get_id() ); - $download->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '1.2.3.4' ); - $id = $object->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '54.2.1.3' ); - $id = $object->save(); - - // Save a second log for the same IP -- only one result for this IP should be returned. - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '54.2.1.3' ); - $id = $object->save(); - - $object = new \WC_Customer_Download_Log(); - $object->set_permission_id( $download->get_id() ); - $object->set_user_id( $this->user ); - $object->set_user_ip_address( '54.5.1.7' ); - $id = $object->save(); - - $request = new \WP_REST_Request( 'GET', $this->endpoint . '/download-ips' ); - $request->set_query_params( - array( - 'match' => '54', - ) - ); - - $response = $this->server->dispatch( $request ); - $addresses = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $addresses ) ); - - $this->assertEquals( '54.2.1.3', $addresses[0]['user_ip_address'] ); - $this->assertEquals( '54.5.1.7', $addresses[1]['user_ip_address'] ); - } -} diff --git a/unit-tests/Tests/Version4/Orders.php b/unit-tests/Tests/Version4/Orders.php deleted file mode 100644 index d8a5e0b955e..00000000000 --- a/unit-tests/Tests/Version4/Orders.php +++ /dev/null @@ -1,656 +0,0 @@ -[\d]+)', - '/wc/v4/orders/batch', - ]; - - /** - * The endpoint schema. - * - * @var array Keys are property names, values are supported context. - */ - protected $properties = [ - 'id' => array( 'view', 'edit' ), - 'parent_id' => array( 'view', 'edit' ), - 'number' => array( 'view', 'edit' ), - 'order_key' => array( 'view', 'edit' ), - 'created_via' => array( 'view', 'edit' ), - 'version' => array( 'view', 'edit' ), - 'status' => array( 'view', 'edit' ), - 'currency' => array( 'view', 'edit' ), - 'currency_symbol' => array( 'view', 'edit' ), - 'date_created' => array( 'view', 'edit' ), - 'date_created_gmt' => array( 'view', 'edit' ), - 'date_modified' => array( 'view', 'edit' ), - 'date_modified_gmt' => array( 'view', 'edit' ), - 'discount_total' => array( 'view', 'edit' ), - 'discount_tax' => array( 'view', 'edit' ), - 'shipping_total' => array( 'view', 'edit' ), - 'shipping_tax' => array( 'view', 'edit' ), - 'cart_tax' => array( 'view', 'edit' ), - 'total' => array( 'view', 'edit' ), - 'total_tax' => array( 'view', 'edit' ), - 'prices_include_tax' => array( 'view', 'edit' ), - 'customer_id' => array( 'view', 'edit' ), - 'customer_ip_address' => array( 'view', 'edit' ), - 'customer_user_agent' => array( 'view', 'edit' ), - 'customer_note' => array( 'view', 'edit' ), - 'billing' => array( 'view', 'edit' ), - 'shipping' => array( 'view', 'edit' ), - 'payment_method' => array( 'view', 'edit' ), - 'payment_method_title' => array( 'view', 'edit' ), - 'transaction_id' => array( 'view', 'edit' ), - 'date_paid' => array( 'view', 'edit' ), - 'date_paid_gmt' => array( 'view', 'edit' ), - 'date_completed' => array( 'view', 'edit' ), - 'date_completed_gmt' => array( 'view', 'edit' ), - 'cart_hash' => array( 'view', 'edit' ), - 'meta_data' => array( 'view', 'edit' ), - 'line_items' => array( 'view', 'edit' ), - 'tax_lines' => array( 'view', 'edit' ), - 'shipping_lines' => array( 'view', 'edit' ), - 'fee_lines' => array( 'view', 'edit' ), - 'coupon_lines' => array( 'view', 'edit' ), - 'refunds' => array( 'view', 'edit' ), - 'set_paid' => array( 'edit' ), - ]; - - /** - * Test create. - */ - public function test_create() { - $product = ProductHelper::create_simple_product(); - $data = [ - 'currency' => 'ZAR', - 'customer_id' => 1, - 'customer_note' => 'I am a note', - 'transaction_id' => 'test', - 'payment_method' => 'bacs', - 'payment_method_title' => 'Direct Bank Transfer', - 'set_paid' => true, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'company' => '', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'company' => '', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => '10', - ), - ), - ]; - $response = $this->do_request( '/wc/v4/orders', 'POST', $data ); - $this->assertExpectedResponse( $response, 201, $data ); - } - - /** - * Test the sanitization of the payment_method_title field through the API. - * - * @since 3.5.2 - */ - public function test_create_update_order_payment_method_title_sanitize() { - $product = ProductHelper::create_simple_product(); - $data = [ - 'payment_method' => 'bacs', - 'payment_method_title' => '

Sanitize this

', - 'set_paid' => true, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => '10', - ), - ), - ]; - $response = $this->do_request( '/wc/v4/orders', 'POST', $data ); - $order = wc_get_order( $response->data['id'] ); - $this->assertExpectedResponse( $response, 201 ); - $this->assertEquals( $order->get_payment_method(), $response->data['payment_method'] ); - $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this' ); - - // Test when updating order. - $response = $this->do_request( - '/wc/v4/orders/' . $response->data['id'], - 'POST', [ - 'payment_method' => 'bacs', - 'payment_method_title' => '

Sanitize this too

', - ] - ); - $order = wc_get_order( $response->data['id'] ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( $order->get_payment_method(), $response->data['payment_method'] ); - $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this too' ); - } - - /** - * Tests creating an order without required fields. - * @since 3.5.0 - */ - public function test_create_order_invalid_fields() { - $product = ProductHelper::create_simple_product(); - $data = [ - 'payment_method' => 'bacs', - 'payment_method_title' => 'Direct Bank Transfer', - 'set_paid' => true, - 'customer_id' => 99999, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => 10, - ), - ), - ]; - $response = $this->do_request( '/wc/v4/orders', 'POST', $data ); - $this->assertExpectedResponse( $response, 400 ); - } - - /** - * Test read. - */ - public function test_read() { - $product = ProductHelper::create_simple_product(); - $product->set_regular_price( 10.95 ); - $product->set_sale_price( false ); - $product->save(); - $customer = CustomerHelper::create_customer(); - $orders = []; - $orders[] = OrderHelper::create_order( $customer->get_id(), $product ); - - // Create orders. - for ( $i = 0; $i < 9; $i++ ) { - $orders[] = OrderHelper::create_order( $this->user ); - } - - $orders[5]->set_status( 'on-hold' ); - $orders[5]->save(); - $orders[6]->set_status( 'on-hold' ); - $orders[6]->save(); - $orders[0]->calculate_totals(); - $orders[0]->save(); - - // Collection. - $response = $this->do_request( '/wc/v4/orders', 'GET' ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 10, count( $response->data ) ); - - // Collection args. - $response = $this->do_request( '/wc/v4/orders', 'GET', [ 'status' => 'on-hold' ] ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 2, count( $response->data ) ); - - $response = $this->do_request( '/wc/v4/orders', 'GET', [ 'number' => (string) $orders[0]->get_id() ] ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 1, count( $response->data ) ); - - $response = $this->do_request( '/wc/v4/orders', 'GET', [ 'customer' => $customer->get_id() ] ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 1, count( $response->data ) ); - - $response = $this->do_request( '/wc/v4/orders', 'GET', [ 'product' => $product->get_id() ] ); - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 1, count( $response->data ) ); - - // Single collection args. - $response = $this->do_request( '/wc/v4/orders/' . $orders[0]->get_id(), 'GET', [ 'dp' => 0 ] ); - $this->assertEquals( '54', $response->data['total'] ); - $response = $this->do_request( '/wc/v4/orders/' . $orders[0]->get_id(), 'GET', [ 'dp' => 2 ] ); - $this->assertEquals( '53.80', $response->data['total'] ); - - // Single. - $response = $this->do_request( '/wc/v4/orders/' . $orders[0]->get_id(), 'GET' ); - $this->assertExpectedResponse( $response, 200 ); - - foreach ( $this->get_properties( 'view' ) as $property ) { - $this->assertArrayHasKey( $property, $response->data ); - } - - // Invalid. - $response = $this->do_request( '/wc/v4/orders/0', 'GET' ); - $this->assertExpectedResponse( $response, 404 ); - } - - /** - * Test update. - */ - public function test_update() { - // Invalid. - $response = $this->do_request( '/wc/v4/orders/0', 'POST', [ 'payment_method' => 'test' ] ); - $this->assertExpectedResponse( $response, 404 ); - - // Update existing. - $order = OrderHelper::create_order(); - $data = [ - 'payment_method' => 'test-update', - 'billing' => array( - 'first_name' => 'Fish', - 'last_name' => 'Face', - ), - ]; - $response = $this->do_request( - '/wc/v4/orders/' . $order->get_id(), - 'POST', - $data - ); - $this->assertExpectedResponse( $response, 200, $data ); - - foreach ( $this->get_properties( 'view' ) as $property ) { - $this->assertArrayHasKey( $property, $response->data ); - } - } - - /** - * Test delete. - */ - public function test_delete() { - // Invalid. - $result = $this->do_request( '/wc/v4/orders/0', 'DELETE', [ 'force' => false ] ); - $this->assertEquals( 404, $result->status ); - - // Trash. - $order = OrderHelper::create_order(); - $result = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => false ] ); - $this->assertEquals( 200, $result->status ); - $this->assertEquals( 'trash', get_post_status( $order->get_id() ) ); - - // Force. - $order = OrderHelper::create_order(); - $result = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => true ] ); - $this->assertEquals( 200, $result->status ); - $this->assertEquals( false, get_post( $order->get_id() ) ); - } - - /** - * Test read. - */ - public function test_guest_create() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_simple_product(); - $data = [ - 'currency' => 'ZAR', - 'customer_id' => 1, - 'customer_note' => 'I am a note', - 'transaction_id' => 'test', - 'payment_method' => 'bacs', - 'payment_method_title' => 'Direct Bank Transfer', - 'set_paid' => true, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'company' => '', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'company' => '', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => '10', - ), - ), - ]; - $response = $this->do_request( '/wc/v4/orders', 'POST', $data ); - $this->assertExpectedResponse( $response, 401, $data ); - } - - /** - * Test read. - */ - public function test_guest_read() { - wp_set_current_user( 0 ); - $response = $this->do_request( '/wc/v4/orders', 'GET' ); - $this->assertExpectedResponse( $response, 401 ); - } - - /** - * Test update. - */ - public function test_guest_update() { - wp_set_current_user( 0 ); - $order = OrderHelper::create_order(); - $data = [ - 'payment_method' => 'test-update', - 'billing' => array( - 'first_name' => 'Fish', - 'last_name' => 'Face', - ), - ]; - $response = $this->do_request( - '/wc/v4/orders/' . $order->get_id(), - 'POST', - $data - ); - $this->assertExpectedResponse( $response, 401 ); - } - - /** - * Test delete. - */ - public function test_guest_delete() { - wp_set_current_user( 0 ); - $order = OrderHelper::create_order(); - $response = $this->do_request( '/wc/v4/orders/' . $order->get_id(), 'DELETE', [ 'force' => true ] ); - $this->assertEquals( 401, $response->status ); - } - - /** - * Test validation. - */ - public function test_enums() { - $order = OrderHelper::create_order(); - - $response = $this->do_request( - '/wc/v4/orders/' . $order->get_id(), - 'POST', - [ - 'status' => 'invalid', - ] - ); - $this->assertEquals( 400, $response->status ); - $this->assertEquals( 'Invalid parameter(s): status', $response->data['message'] ); - - $response = $this->do_request( - '/wc/v4/orders/' . $order->get_id(), - 'POST', - [ - 'currency' => 'invalid', - ] - ); - $this->assertEquals( 400, $response->status ); - $this->assertEquals( 'Invalid parameter(s): currency', $response->data['message'] ); - } - - /** - * Test a batch update. - */ - public function test_batch() { - $order1 = OrderHelper::create_order(); - $order2 = OrderHelper::create_order(); - $order3 = OrderHelper::create_order(); - - $result = $this->do_request( - '/wc/v4/orders/batch', - 'POST', - array( - 'update' => array( - array( - 'id' => $order1->get_id(), - 'payment_method' => 'updated', - ), - ), - 'delete' => array( - $order2->get_id(), - $order3->get_id(), - ), - ) - ); - $this->assertEquals( 'updated', $result->data['update'][0]['payment_method'] ); - $this->assertEquals( $order2->get_id(), $result->data['delete'][0]['previous']['id'] ); - $this->assertEquals( $order3->get_id(), $result->data['delete'][1]['previous']['id'] ); - - $result = $this->do_request( '/wc/v4/orders' ); - $this->assertEquals( 1, count( $result->data ) ); - } - - /** - * Tests updating an order and removing items. - * - * @since 3.5.0 - */ - public function test_update_order_remove_items() { - $order = OrderHelper::create_order(); - $fee = new \WC_Order_Item_Fee(); - $fee->set_props( - array( - 'name' => 'Some Fee', - 'tax_status' => 'taxable', - 'total' => '100', - 'tax_class' => '', - ) - ); - $order->add_item( $fee ); - $order->save(); - - $fee_data = current( $order->get_items( 'fee' ) ); - $response = $this->do_request( - '/wc/v4/orders/' . $order->get_id(), - 'PUT', - [ - 'fee_lines' => array( - array( - 'id' => $fee_data->get_id(), - 'name' => null, - ), - ), - ] - ); - $this->assertEquals( 200, $response->status ); - $this->assertTrue( empty( $response->data['fee_lines'] ) ); - } - - /** - * Tests updating an order and adding a coupon. - * - * @since 3.5.0 - */ - public function test_update_order_add_coupons() { - $order = OrderHelper::create_order(); - $order_item = current( $order->get_items() ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); - $coupon->set_amount( 5 ); - $coupon->save(); - - $response = $this->do_request( - '/wc/v4/orders/' . $order->get_id(), - 'PUT', - [ - 'coupon_lines' => array( - array( - 'code' => 'fake-coupon', - ), - ), - ] - ); - $this->assertEquals( 200, $response->status ); - $this->assertCount( 1, $response->data['coupon_lines'] ); - $this->assertEquals( '45.00', $response->data['total'] ); - } - - /** - * Tests updating an order and removing a coupon. - * - * @since 3.5.0 - */ - public function test_update_order_remove_coupons() { - $order = OrderHelper::create_order(); - $order_item = current( $order->get_items() ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); - $coupon->set_amount( 5 ); - $coupon->save(); - $order->apply_coupon( $coupon ); - $order->save(); - - // Check that the coupon is applied. - $this->assertEquals( '45.00', $order->get_total() ); - - $coupon_data = current( $order->get_items( 'coupon' ) ); - $response = $this->do_request( - '/wc/v4/orders/' . $order->get_id(), - 'PUT', - [ - 'coupon_lines' => array( - array( - 'id' => $coupon_data->get_id(), - 'code' => null, - ), - ), - 'line_items' => array( - array( - 'id' => $order_item->get_id(), - 'product_id' => $order_item->get_product_id(), - 'total' => '40.00', - ), - ), - ] - ); - $this->assertEquals( 200, $response->status ); - $this->assertTrue( empty( $response->data['coupon_lines'] ) ); - $this->assertEquals( '50.00', $response->data['total'] ); - } - - /** - * Tests updating an order with an invalid coupon. - * - * @since 3.5.0 - */ - public function test_invalid_coupon() { - $order = OrderHelper::create_order(); - $response = $this->do_request( - '/wc/v4/orders/' . $order->get_id(), - 'PUT', - [ - 'coupon_lines' => array( - array( - 'code' => 'NON_EXISTING_COUPON', - ), - ), - ] - ); - $this->assertEquals( 400, $response->status ); - $this->assertEquals( 'woocommerce_rest_invalid_coupon', $response->data['code'] ); - $this->assertEquals( 'Coupon "non_existing_coupon" does not exist!', $response->data['message'] ); - } -} diff --git a/unit-tests/Tests/Version4/PaymentGateways.php b/unit-tests/Tests/Version4/PaymentGateways.php deleted file mode 100644 index 183dae52dda..00000000000 --- a/unit-tests/Tests/Version4/PaymentGateways.php +++ /dev/null @@ -1,358 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server, endpoints, and user info. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v4/payment_gateways', $routes ); - $this->assertArrayHasKey( '/wc/v4/payment_gateways/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all payment gateways. - * - * @since 3.5.0 - */ - public function test_get_payment_gateways() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways' ) ); - $gateways = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => 'cheque', - 'title' => 'Check payments', - 'description' => 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', - 'order' => '', - 'enabled' => false, - 'method_title' => 'Check payments', - 'method_description' => 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', - 'method_supports' => array( - 'products', - ), - 'settings' => array_diff_key( - $this->get_settings( 'WC_Gateway_Cheque' ), - array( - 'enabled' => false, - 'description' => false, - ) - ), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/payment_gateways/cheque' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/payment_gateways' ), - ), - ), - ), - ), - $gateways - ); - } - - /** - * Tests to make sure payment gateways cannot viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_payment_gateways_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single payment gateway. - * - * @since 3.5.0 - */ - public function test_get_payment_gateway() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/paypal' ) ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => 'paypal', - 'title' => 'PayPal', - 'description' => "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account.", - 'order' => '', - 'enabled' => false, - 'method_title' => 'PayPal', - 'method_description' => 'PayPal Standard redirects customers to PayPal to enter their payment information.', - 'method_supports' => array( - 'products', - 'refunds', - ), - 'settings' => array_diff_key( - $this->get_settings( 'WC_Gateway_Paypal' ), - array( - 'enabled' => false, - 'description' => false, - ) - ), - ), - $paypal - ); - } - - /** - * Test getting a payment gateway without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_payment_gateway_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/paypal' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a payment gateway with an invalid id. - * - * @since 3.5.0 - */ - public function test_get_payment_gateway_invalid_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/totally_fake_method' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a single payment gateway. - * - * @since 3.5.0 - */ - public function test_update_payment_gateway() { - // Test defaults - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/payment_gateways/paypal' ) ); - $paypal = $response->get_data(); - - $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'admin@example.org', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); - - // test updating single setting - $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'email' => 'woo@woo.local', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); - - // test updating multiple settings - $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'testmode' => 'yes', - 'title' => 'PayPal - New Title', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); - - // Test other parameters, and recheck settings - $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertFalse( $paypal['enabled'] ); - $this->assertEquals( 2, $paypal['order'] ); - $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); - - // test bogus - $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'paymentaction' => 'afasfasf', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'paymentaction' => 'authorization', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - $this->assertEquals( 'authorization', $paypal['settings']['paymentaction']['value'] ); - } - - /** - * Test updating a payment gateway without valid permissions. - * - * @since 3.5.0 - */ - public function test_update_payment_gateway_without_permission() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'testmode' => 'yes', - 'title' => 'PayPal - New Title', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a payment gateway with an invalid id. - * - * @since 3.5.0 - */ - public function test_update_payment_gateway_invalid_id() { - $request = new WP_REST_Request( 'POST', '/wc/v4/payment_gateways/totally_fake_method' ); - $request->set_body_params( - array( - 'enabled' => true, - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test the payment gateway schema. - * - * @since 3.5.0 - */ - public function test_payment_gateway_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/payment_gateways' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 9, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'title', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'order', $properties ); - $this->assertArrayHasKey( 'enabled', $properties ); - $this->assertArrayHasKey( 'method_title', $properties ); - $this->assertArrayHasKey( 'method_description', $properties ); - $this->assertArrayHasKey( 'method_supports', $properties ); - $this->assertArrayHasKey( 'settings', $properties ); - } - - /** - * Loads a particular gateway's settings so we can correctly test API output. - * - * @since 3.5.0 - * @param string $gateway_class Name of WC_Payment_Gateway class. - */ - private function get_settings( $gateway_class ) { - $gateway = new $gateway_class(); - $settings = array(); - $gateway->init_form_fields(); - foreach ( $gateway->form_fields as $id => $field ) { - // Make sure we at least have a title and type - if ( empty( $field['title'] ) || empty( $field['type'] ) ) { - continue; - } - // Ignore 'enabled' and 'description', to be in line with \WC_REST_Payment_Gateways_Controller::get_settings. - if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { - continue; - } - $data = array( - 'id' => $id, - 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => $gateway->settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - -} diff --git a/unit-tests/Tests/Version4/ProductReviews.php b/unit-tests/Tests/Version4/ProductReviews.php deleted file mode 100644 index 1315d550b81..00000000000 --- a/unit-tests/Tests/Version4/ProductReviews.php +++ /dev/null @@ -1,400 +0,0 @@ -[\d]+)', - '/wc/v4/products/reviews/batch', - ]; - - /** - * The endpoint schema. - * - * @var array Keys are property names, values are supported context. - */ - protected $properties = [ - 'id' => array( 'view', 'edit' ), - 'date_created' => array( 'view', 'edit' ), - 'date_created_gmt' => array( 'view', 'edit' ), - 'product_id' => array( 'view', 'edit' ), - 'status' => array( 'view', 'edit' ), - 'reviewer' => array( 'view', 'edit' ), - 'reviewer_email' => array( 'view', 'edit' ), - 'review' => array( 'view', 'edit' ), - 'rating' => array( 'view', 'edit' ), - 'verified' => array( 'view', 'edit' ), - 'reviewer_avatar_urls' => array( 'view', 'edit' ), - ]; - - /** - * Test creation using this method. - * If read-only, test to confirm this. - */ - public function test_create() { - $product = ProductHelper::create_simple_product(); - $data = [ - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - 'rating' => '5', - 'product_id' => $product->get_id(), - ]; - $response = $this->do_request( '/wc/v4/products/reviews', 'POST', $data ); - $this->assertExpectedResponse( $response, 201, $data ); - $this->assertEquals( - array( - 'id' => $response->data['id'], - 'date_created' => $response->data['date_created'], - 'date_created_gmt' => $response->data['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => 'Hello world.', - 'rating' => 5, - 'verified' => false, - 'reviewer_avatar_urls' => $response->data['reviewer_avatar_urls'], - ), - $response->data - ); - } - - /** - * Test get/read using this method. - */ - public function test_read() { - $product = ProductHelper::create_simple_product(); - for ( $i = 0; $i < 10; $i++ ) { - $review_id = ProductHelper::create_product_review( $product->get_id() ); - } - - // Invalid. - $response = $this->do_request( '/wc/v4/products/0/reviews' ); - $this->assertExpectedResponse( $response, 404 ); - - // Collections. - $response = $this->do_request( '/wc/v4/products/reviews' ); - $product_reviews = $response->data; - - $this->assertExpectedResponse( $response, 200 ); - $this->assertEquals( 10, count( $product_reviews ) ); - $this->assertContains( - array( - 'id' => $review_id, - 'date_created' => $product_reviews[0]['date_created'], - 'date_created_gmt' => $product_reviews[0]['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => "

Review content here

\n", - 'rating' => 0, - 'verified' => false, - 'reviewer_avatar_urls' => $product_reviews[0]['reviewer_avatar_urls'], - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/products/reviews/' . $review_id ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/products/reviews' ), - ), - ), - 'up' => array( - array( - 'embeddable' => true, - 'href' => rest_url( '/wc/v4/products/' . $product->get_id() ), - ), - ), - ), - ), - $product_reviews - ); - } - - /** - * Test updates using this method. - * If read-only, test to confirm this. - */ - public function test_update() { - $product = ProductHelper::create_simple_product(); - $product_review_id = ProductHelper::create_product_review( $product->get_id() ); - - $response = $this->do_request( '/wc/v4/products/reviews/' . $product_review_id ); - $this->assertEquals( 200, $response->status ); - $this->assertEquals( "

Review content here

\n", $response->data['review'] ); - $this->assertEquals( 'admin', $response->data['reviewer'] ); - $this->assertEquals( 'woo@woo.local', $response->data['reviewer_email'] ); - $this->assertEquals( 0, $response->data['rating'] ); - - $data = [ - 'review' => 'Hello world - updated.', - 'reviewer' => 'Justin', - 'reviewer_email' => 'woo2@woo.local', - 'rating' => 3, - ]; - $response = $this->do_request( '/wc/v4/products/reviews/' . $product_review_id, 'PUT', $data ); - - $this->assertExpectedResponse( $response, 200, $data ); - - foreach ( $this->get_properties( 'view' ) as $property ) { - $this->assertArrayHasKey( $property, $response->data ); - } - } - - /** - * Test delete using this method. - * If read-only, test to confirm this. - */ - public function test_delete() { - // Invalid. - $result = $this->do_request( '/wc/v4/products/reviews/0', 'DELETE', [ 'force' => true ] ); - $this->assertEquals( 404, $result->status ); - - // Valid. - $product = ProductHelper::create_simple_product(); - $product_review_id = ProductHelper::create_product_review( $product->get_id() ); - $result = $this->do_request( '/wc/v4/products/reviews/' . $product_review_id, 'DELETE', [ 'force' => true ] ); - $this->assertEquals( 200, $result->status ); - } - - /** - * Test get/read using this method. - */ - public function test_guest_read() { - wp_set_current_user( 0 ); - $result = $this->do_request( '/wc/v4/products/reviews' ); - $this->assertEquals( 401, $result->status ); - } - - /** - * Tests getting a single product review. - * - * @since 3.5.0 - */ - public function test_get_product_review() { - $product = ProductHelper::create_simple_product(); - $product_review_id = ProductHelper::create_product_review( $product->get_id() ); - - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v4/products/reviews/' . $product_review_id ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $product_review_id, - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => "

Review content here

\n", - 'rating' => 0, - 'verified' => false, - 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], - ), - $data - ); - } - - /** - * Tests getting a product review with an invalid ID. - * - * @since 3.5.0 - */ - public function test_get_product_review_invalid_id() { - $product = ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v4/products/reviews/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests creating a product review without required fields. - * - * @since 3.5.0 - */ - public function test_create_product_review_invalid_fields() { - $product = ProductHelper::create_simple_product(); - - // missing review - $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews' ); - $request->set_body_params( - array( - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - - // Missing reviewer. - $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer_email' => 'woo@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - - // missing reviewer_email - $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Tests updating a product review without the correct permissions. - * - * @since 3.5.0 - */ - public function test_update_product_review_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_simple_product(); - $product_review_id = ProductHelper::create_product_review( $product->get_id() ); - - $request = new \WP_REST_Request( 'PUT', '/wc/v4/products/reviews/' . $product_review_id ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.dev', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests that updating a product review with an invalid id fails. - * - * @since 3.5.0 - */ - public function test_update_product_review_invalid_id() { - wp_set_current_user( $this->user ); - $product = ProductHelper::create_simple_product(); - - $request = new \WP_REST_Request( 'PUT', '/wc/v4/products/reviews/0' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.dev', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test deleting a product review without permission/creds. - * - * @since 3.5.0 - */ - public function test_delete_product_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_simple_product(); - $product_review_id = ProductHelper::create_product_review( $product->get_id() ); - - $request = new \WP_REST_Request( 'DELETE', '/wc/v4/products/reviews/' . $product_review_id ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch managing product reviews. - * - * @since 3.5.0 - */ - public function test_product_reviews_batch() { - $product = ProductHelper::create_simple_product(); - - $review_1_id = ProductHelper::create_product_review( $product->get_id() ); - $review_2_id = ProductHelper::create_product_review( $product->get_id() ); - $review_3_id = ProductHelper::create_product_review( $product->get_id() ); - $review_4_id = ProductHelper::create_product_review( $product->get_id() ); - - $request = new \WP_REST_Request( 'POST', '/wc/v4/products/reviews/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $review_1_id, - 'review' => 'Updated review.', - ), - ), - 'delete' => array( - $review_2_id, - $review_3_id, - ), - 'create' => array( - array( - 'review' => 'New review.', - 'reviewer' => 'Justin', - 'reviewer_email' => 'woo3@woo.local', - 'product_id' => $product->get_id(), - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'Updated review.', $data['update'][0]['review'] ); - $this->assertEquals( 'New review.', $data['create'][0]['review'] ); - $this->assertEquals( $review_2_id, $data['delete'][0]['previous']['id'] ); - $this->assertEquals( $review_3_id, $data['delete'][1]['previous']['id'] ); - - $request = new \WP_REST_Request( 'GET', '/wc/v4/products/reviews' ); - $request->set_param( 'product', $product->get_id() ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } -} - diff --git a/unit-tests/Tests/Version4/ProductVariations.php b/unit-tests/Tests/Version4/ProductVariations.php deleted file mode 100644 index aa3188b3b2e..00000000000 --- a/unit-tests/Tests/Version4/ProductVariations.php +++ /dev/null @@ -1,487 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server, endpoints, and user info. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v4/products/(?P[\d]+)/variations', $routes ); - $this->assertArrayHasKey( '/wc/v4/products/(?P[\d]+)/variations/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v4/products/(?P[\d]+)/variations/batch', $routes ); - } - - /** - * Test getting variations. - * - * @since 3.5.0 - */ - public function test_get_variations() { - $product = ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $variations ) ); - $this->assertEquals( 'DUMMY SKU VARIABLE LARGE', $variations[0]['sku'] ); - $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); - } - - /** - * Test getting variations without permission. - * - * @since 3.5.0 - */ - public function test_get_variations_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single variation. - * - * @since 3.5.0 - */ - public function test_get_variation() { - $product = ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $variation_id, $variation['id'] ); - $this->assertEquals( 'size', $variation['attributes'][0]['name'] ); - } - - /** - * Test getting single variation without permission. - * - * @since 3.5.0 - */ - public function test_get_variation_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single variation. - * - * @since 3.5.0 - */ - public function test_delete_variation() { - $product = ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 1, count( $variations ) ); - } - - /** - * Test deleting a single variation without permission. - * - * @since 3.5.0 - */ - public function test_delete_variation_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single variation with an invalid ID. - * - * @since 3.5.0 - */ - public function test_delete_variation_with_invalid_id() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_variation_product(); - $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() . '/variations/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test editing a single variation. - * - * @since 3.5.0 - */ - public function test_update_variation() { - $product = ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $variation = $response->get_data(); - - $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variation['sku'] ); - $this->assertEquals( 10, $variation['regular_price'] ); - $this->assertEmpty( $variation['sale_price'] ); - $this->assertEquals( 'small', $variation['attributes'][0]['option'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'sku' => 'FIXED-\'SKU', - 'sale_price' => '8', - 'description' => 'O_O', - 'image' => array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertTrue( isset( $variation['description'] ), print_r( $variation, true ) ); - $this->assertContains( 'O_O', $variation['description'], print_r( $variation, true ) ); - $this->assertEquals( '8', $variation['price'], print_r( $variation, true ) ); - $this->assertEquals( '8', $variation['sale_price'], print_r( $variation, true ) ); - $this->assertEquals( '10', $variation['regular_price'], print_r( $variation, true ) ); - $this->assertEquals( 'FIXED-\'SKU', $variation['sku'], print_r( $variation, true ) ); - $this->assertEquals( 'medium', $variation['attributes'][0]['option'], print_r( $variation, true ) ); - $this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'], print_r( $variation, true ) ); - $this->assertContains( 'test upload image', $variation['image']['alt'], print_r( $variation, true ) ); - } - - /** - * Test updating a single variation without permission. - * - * @since 3.5.0 - */ - public function test_update_variation_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single variation with an invalid ID. - * - * @since 3.5.0 - */ - public function test_update_variation_with_invalid_id() { - $product = ProductHelper::create_variation_product(); - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/0' ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test creating a single variation. - * - * @since 3.5.0 - */ - public function test_create_variation() { - $product = ProductHelper::create_variation_product(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 2, count( $variations ) ); - - $request = new WP_REST_Request( 'POST', '/wc/v4/products/' . $product->get_id() . '/variations' ); - $request->set_body_params( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertContains( 'A medium size.', $variation['description'] ); - $this->assertEquals( '12', $variation['price'] ); - $this->assertEquals( '12', $variation['regular_price'] ); - $this->assertTrue( $variation['purchasable'] ); - $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $variation['sku'] ); - $this->assertEquals( 'medium', $variation['attributes'][0]['option'] ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 3, count( $variations ) ); - } - - /** - * Test creating a single variation without permission. - * - * @since 3.5.0 - */ - public function test_create_variation_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_variation_product(); - - $request = new WP_REST_Request( 'POST', '/wc/v4/products/' . $product->get_id() . '/variations' ); - $request->set_body_params( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch managing product variations. - * - * @since 3.5.0 - */ - public function test_product_variations_batch() { - $product = ProductHelper::create_variation_product(); - $children = $product->get_children(); - $request = new WP_REST_Request( 'POST', '/wc/v4/products/' . $product->get_id() . '/variations/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $children[0], - 'description' => 'Updated description.', - 'image' => array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - ), - ), - 'delete' => array( - $children[1], - ), - 'create' => array( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); - $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $data['create'][0]['sku'] ); - $this->assertEquals( 'medium', $data['create'][0]['attributes'][0]['option'] ); - $this->assertEquals( $children[1], $data['delete'][0]['previous']['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() . '/variations' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 2, count( $data ) ); - } - - /** - * Test variation schema. - * - * @since 3.5.0 - */ - public function test_variation_schema() { - $product = ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() . '/variations' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 40, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_modified', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'permalink', $properties ); - $this->assertArrayHasKey( 'sku', $properties ); - $this->assertArrayHasKey( 'price', $properties ); - $this->assertArrayHasKey( 'regular_price', $properties ); - $this->assertArrayHasKey( 'sale_price', $properties ); - $this->assertArrayHasKey( 'date_on_sale_from', $properties ); - $this->assertArrayHasKey( 'date_on_sale_to', $properties ); - $this->assertArrayHasKey( 'on_sale', $properties ); - $this->assertArrayHasKey( 'purchasable', $properties ); - $this->assertArrayHasKey( 'virtual', $properties ); - $this->assertArrayHasKey( 'downloadable', $properties ); - $this->assertArrayHasKey( 'downloads', $properties ); - $this->assertArrayHasKey( 'download_limit', $properties ); - $this->assertArrayHasKey( 'download_expiry', $properties ); - $this->assertArrayHasKey( 'tax_status', $properties ); - $this->assertArrayHasKey( 'tax_class', $properties ); - $this->assertArrayHasKey( 'manage_stock', $properties ); - $this->assertArrayHasKey( 'stock_quantity', $properties ); - $this->assertArrayHasKey( 'stock_status', $properties ); - $this->assertArrayHasKey( 'backorders', $properties ); - $this->assertArrayHasKey( 'backorders_allowed', $properties ); - $this->assertArrayHasKey( 'backordered', $properties ); - $this->assertArrayHasKey( 'weight', $properties ); - $this->assertArrayHasKey( 'dimensions', $properties ); - $this->assertArrayHasKey( 'shipping_class', $properties ); - $this->assertArrayHasKey( 'shipping_class_id', $properties ); - $this->assertArrayHasKey( 'image', $properties ); - $this->assertArrayHasKey( 'attributes', $properties ); - $this->assertArrayHasKey( 'menu_order', $properties ); - $this->assertArrayHasKey( 'meta_data', $properties ); - } - - /** - * Test updating a variation stock. - * - * @since 3.5.0 - */ - public function test_update_variation_manage_stock() { - $product = ProductHelper::create_variation_product(); - $product->set_manage_stock( false ); - $product->save(); - - $children = $product->get_children(); - $variation_id = $children[0]; - - // Set stock to true. - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => true, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( true, $variation['manage_stock'] ); - - // Set stock to false. - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => false, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( false, $variation['manage_stock'] ); - - // Set stock to false but parent is managing stock. - $product->set_manage_stock( true ); - $product->save(); - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => false, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'parent', $variation['manage_stock'] ); - } -} diff --git a/unit-tests/Tests/Version4/Products.php b/unit-tests/Tests/Version4/Products.php deleted file mode 100644 index fde184ea98a..00000000000 --- a/unit-tests/Tests/Version4/Products.php +++ /dev/null @@ -1,838 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server, endpoints, and user info. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v4/products', $routes ); - $this->assertArrayHasKey( '/wc/v4/products/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v4/products/batch', $routes ); - } - - /** - * Test getting products. - * - * @since 3.5.0 - */ - public function test_get_products() { - ProductHelper::create_external_product(); - sleep( 1 ); // So both products have different timestamps. - ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 2, count( $products ) ); - $this->assertEquals( 'Dummy Product', $products[0]['name'] ); - $this->assertEquals( 'DUMMY SKU', $products[0]['sku'] ); - $this->assertEquals( 'Dummy External Product', $products[1]['name'] ); - $this->assertEquals( 'DUMMY EXTERNAL SKU', $products[1]['sku'] ); - } - - /** - * Test getting products without permission. - * - * @since 3.5.0 - */ - public function test_get_products_without_permission() { - wp_set_current_user( 0 ); - ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single product. - * - * @since 3.5.0 - */ - public function test_get_product() { - $simple = ProductHelper::create_external_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $simple->get_id() ) ); - $product = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => $simple->get_id(), - 'name' => 'Dummy External Product', - 'type' => 'simple', - 'status' => 'publish', - 'sku' => 'DUMMY EXTERNAL SKU', - 'regular_price' => 10, - ), - $product - ); - } - - /** - * Test getting single product without permission. - * - * @since 3.5.0 - */ - public function test_get_product_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single product. - * - * @since 3.5.0 - */ - public function test_delete_product() { - $product = ProductHelper::create_simple_product(); - - $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); - $variations = $response->get_data(); - $this->assertEquals( 0, count( $variations ) ); - } - - /** - * Test deleting a single product without permission. - * - * @since 3.5.0 - */ - public function test_delete_product_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/' . $product->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single product with an invalid ID. - * - * @since 3.5.0 - */ - public function test_delete_product_with_invalid_id() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'DELETE', '/wc/v4/products/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test editing a single product. Tests multiple product types. - * - * @since 3.5.0 - */ - public function test_update_product() { - // test simple products. - $product = ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); - $data = $response->get_data(); - $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); - - $this->assertEquals( 'DUMMY SKU', $data['sku'] ); - $this->assertEquals( 10, $data['regular_price'] ); - $this->assertEmpty( $data['sale_price'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU', - 'sale_price' => '8', - 'description' => 'Testing', - 'date_created' => $date_created, - 'images' => array( - array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Testing', $data['description'] ); - $this->assertEquals( '8', $data['price'] ); - $this->assertEquals( '8', $data['sale_price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertEquals( 'FIXED-SKU', $data['sku'] ); - $this->assertEquals( $date_created, $data['date_created'] ); - $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); - $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); - $product->delete( true ); - - // test variable product (variations are tested in product-variations.php). - $product = ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); - $data = $response->get_data(); - - foreach ( array( 'small', 'large' ) as $term_name ) { - $this->assertContains( $term_name, $data['attributes'][0]['options'] ); - } - - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'attributes' => array( - array( - 'id' => 0, - 'name' => 'pa_color', - 'options' => array( - 'red', - 'yellow', - ), - 'visible' => false, - 'variation' => 1, - ), - array( - 'id' => 0, - 'name' => 'pa_size', - 'options' => array( - 'small', - ), - 'visible' => false, - 'variation' => 1, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( array( 'small' ), $data['attributes'][0]['options'] ); - - foreach ( array( 'red', 'yellow' ) as $term_name ) { - $this->assertContains( $term_name, $data['attributes'][1]['options'] ); - } - - $product->delete( true ); - - // test external product. - $product = ProductHelper::create_external_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products/' . $product->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 'Buy external product', $data['button_text'] ); - $this->assertEquals( 'http://woocommerce.com', $data['external_url'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'button_text' => 'Test API Update', - 'external_url' => 'http://automattic.com', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'Test API Update', $data['button_text'] ); - $this->assertEquals( 'http://automattic.com', $data['external_url'] ); - } - - /** - * Test updating a single product without permission. - * - * @since 3.5.0 - */ - public function test_update_product_without_permission() { - wp_set_current_user( 0 ); - $product = ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single product with an invalid ID. - * - * @since 3.5.0 - */ - public function test_update_product_with_invalid_id() { - $request = new WP_REST_Request( 'PUT', '/wc/v4/products/0' ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-INVALID-ID', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test creating a single product. - * - * @since 3.5.0 - */ - public function test_create_product() { - - $request = new WP_REST_Request( 'POST', '/wc/v4/products/shipping_classes' ); - $request->set_body_params( - array( - 'name' => 'Test', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $shipping_class_id = $data['id']; - - // Create simple. - $request = new WP_REST_Request( 'POST', '/wc/v4/products' ); - $request->set_body_params( - array( - 'type' => 'simple', - 'name' => 'Test Simple Product', - 'sku' => 'DUMMY SKU SIMPLE API', - 'regular_price' => '10', - 'shipping_class' => 'test', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '10', $data['price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertTrue( $data['purchasable'] ); - $this->assertEquals( 'DUMMY SKU SIMPLE API', $data['sku'] ); - $this->assertEquals( 'Test Simple Product', $data['name'] ); - $this->assertEquals( 'simple', $data['type'] ); - $this->assertEquals( $shipping_class_id, $data['shipping_class_id'] ); - - // Create external. - $request = new WP_REST_Request( 'POST', '/wc/v4/products' ); - $request->set_body_params( - array( - 'type' => 'external', - 'name' => 'Test External Product', - 'sku' => 'DUMMY SKU EXTERNAL API', - 'regular_price' => '10', - 'button_text' => 'Test Button', - 'external_url' => 'https://wordpress.org', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '10', $data['price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertFalse( $data['purchasable'] ); - $this->assertEquals( 'DUMMY SKU EXTERNAL API', $data['sku'] ); - $this->assertEquals( 'Test External Product', $data['name'] ); - $this->assertEquals( 'external', $data['type'] ); - $this->assertEquals( 'Test Button', $data['button_text'] ); - $this->assertEquals( 'https://wordpress.org', $data['external_url'] ); - - // Create variable. - $request = new WP_REST_Request( 'POST', '/wc/v4/products' ); - $request->set_body_params( - array( - 'type' => 'variable', - 'name' => 'Test Variable Product', - 'sku' => 'DUMMY SKU VARIABLE API', - 'attributes' => array( - array( - 'id' => 0, - 'name' => 'pa_size', - 'options' => array( - 'small', - 'medium', - ), - 'visible' => false, - 'variation' => 1, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'DUMMY SKU VARIABLE API', $data['sku'] ); - $this->assertEquals( 'Test Variable Product', $data['name'] ); - $this->assertEquals( 'variable', $data['type'] ); - $this->assertEquals( array( 'small', 'medium' ), $data['attributes'][0]['options'] ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/products' ) ); - $products = $response->get_data(); - $this->assertEquals( 3, count( $products ) ); - } - - /** - * Test creating a single product without permission. - * - * @since 3.5.0 - */ - public function test_create_product_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v4/products' ); - $request->set_body_params( - array( - 'name' => 'Test Product', - 'regular_price' => '12', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch managing products. - * - * @since 3.5.0 - */ - public function test_products_batch() { - $product = ProductHelper::create_simple_product(); - $product_2 = ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'POST', '/wc/v4/products/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $product->get_id(), - 'description' => 'Updated description.', - ), - ), - 'delete' => array( - $product_2->get_id(), - ), - 'create' => array( - array( - 'sku' => 'DUMMY SKU BATCH TEST 1', - 'regular_price' => '10', - 'name' => 'Test Batch Create 1', - 'type' => 'external', - 'button_text' => 'Test Button', - ), - array( - 'sku' => 'DUMMY SKU BATCH TEST 2', - 'regular_price' => '20', - 'name' => 'Test Batch Create 2', - 'type' => 'simple', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); - $this->assertEquals( 'DUMMY SKU BATCH TEST 1', $data['create'][0]['sku'] ); - $this->assertEquals( 'DUMMY SKU BATCH TEST 2', $data['create'][1]['sku'] ); - $this->assertEquals( 'Test Button', $data['create'][0]['button_text'] ); - $this->assertEquals( 'external', $data['create'][0]['type'] ); - $this->assertEquals( 'simple', $data['create'][1]['type'] ); - $this->assertEquals( $product_2->get_id(), $data['delete'][0]['previous']['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Tests to make sure you can filter products post statuses by both - * the status query arg and WP_Query. - * - * @since 3.5.0 - */ - public function test_products_filter_post_status() { - for ( $i = 0; $i < 8; $i++ ) { - $product = ProductHelper::create_simple_product(); - if ( 0 === $i % 2 ) { - wp_update_post( - array( - 'ID' => $product->get_id(), - 'post_status' => 'draft', - ) - ); - } - } - - // Test filtering with status=publish. - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_param( 'status', 'publish' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 4, count( $products ) ); - foreach ( $products as $product ) { - $this->assertEquals( 'publish', $product['status'] ); - } - - // Test filtering with status=draft. - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_param( 'status', 'draft' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 4, count( $products ) ); - foreach ( $products as $product ) { - $this->assertEquals( 'draft', $product['status'] ); - } - - // Test filtering with no filters - which should return 'any' (all 8). - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 8, count( $products ) ); - } - - /** - * Test product schema. - * - * @since 3.5.0 - */ - public function test_product_schema() { - $product = ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 65, count( $properties ) ); - } - - /** - * Test product category. - * - * @since 3.5.0 - */ - public function test_get_products_by_category() { - // Create one product with a category. - $category = wp_insert_term( 'Some Category', 'product_cat' ); - - $product = new \WC_Product_Simple(); - $product->set_category_ids( array( $category['term_id'] ) ); - $product->save(); - - // Create one product without category, i.e. Uncategorized. - $product_2 = new \WC_Product_Simple(); - $product_2->save(); - - // Test product assigned to a single category. - $query_params = array( - 'category' => (string) $category['term_id'], - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $product->get_id(), $response_product['id'] ); - $this->assertEquals( $product->get_category_ids(), wp_list_pluck( $response_product['categories'], 'id' ) ); - } - - // Test product without categories. - $request = new WP_REST_Request( 'GET', '/wc/v4/products/' . $product_2->get_id() ); - $response = $this->server->dispatch( $request ); - $response_product = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $response_product['categories'], print_r( $response_product, true ) ); - $this->assertEquals( 'uncategorized', $response_product['categories'][0]['slug'] ); - - } - - /** - * Test getting products by product type. - * - * @since 3.5.0 - */ - public function test_get_products_by_type() { - $simple = ProductHelper::create_simple_product(); - $external = ProductHelper::create_external_product(); - $grouped = ProductHelper::create_grouped_product(); - $variable = ProductHelper::create_variation_product(); - - $product_ids_for_type = array( - 'simple' => array( $simple->get_id() ), - 'external' => array( $external->get_id() ), - 'grouped' => array( $grouped->get_id() ), - 'variable' => array( $variable->get_id() ), - ); - - foreach ( $grouped->get_children() as $additional_product ) { - $product_ids_for_type['simple'][] = $additional_product; - } - - foreach ( $product_ids_for_type as $product_type => $product_ids ) { - $query_params = array( - 'type' => $product_type, - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $product_ids ), count( $response_products ) ); - foreach ( $response_products as $response_product ) { - $this->assertContains( $response_product['id'], $product_ids_for_type[ $product_type ], 'REST API: ' . $product_type . ' not found correctly' ); - } - } - } - - /** - * Test getting products by featured property. - * - * @since 3.5.0 - */ - public function test_get_featured_products() { - // Create a featured product. - $feat_product = ProductHelper::create_simple_product(); - $feat_product->set_featured( true ); - $feat_product->save(); - - // Create a non-featured product. - $nonfeat_product = ProductHelper::create_simple_product(); - $nonfeat_product->save(); - - $query_params = array( - 'featured' => 'true', - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $feat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' ); - } - - $query_params = array( - 'featured' => 'false', - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $nonfeat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' ); - } - } - - /** - * Test getting products by shipping class property. - * - * @since 3.5.0 - */ - public function test_get_products_by_shipping_class() { - $shipping_class_1 = wp_insert_term( 'Bulky', 'product_shipping_class' ); - - $product_1 = new \WC_Product_Simple(); - $product_1->set_shipping_class_id( $shipping_class_1['term_id'] ); - $product_1->save(); - - $query_params = array( - 'shipping_class' => (string) $shipping_class_1['term_id'], - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $product_1->get_id(), $response_product['id'] ); - } - } - - /** - * Test getting products by tag. - * - * @since 3.5.0 - */ - public function test_get_products_by_tag() { - $test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' ); - - // Product with a tag. - $product = ProductHelper::create_simple_product(); - $product->set_tag_ids( array( $test_tag_1['term_id'] ) ); - $product->save(); - - // Product without a tag. - $product_2 = ProductHelper::create_simple_product(); - - $query_params = array( - 'tag' => (string) $test_tag_1['term_id'], - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $product->get_id(), $response_product['id'] ); - } - } - - /** - * Test getting products by global attribute. - * - * @since 3.5.0 - */ - public function test_get_products_by_attribute() { - global $wpdb; - - // Variable product with 2 different variations. - $variable_product = ProductHelper::create_variation_product(); - - // Terms created by variable product. - $term_large = get_term_by( 'slug', 'large', 'pa_size' ); - $term_small = get_term_by( 'slug', 'small', 'pa_size' ); - - // Simple product without attribute. - $product_1 = ProductHelper::create_simple_product(); - - // Simple product with attribute size = large. - $product_2 = ProductHelper::create_simple_product(); - $product_2->set_attributes( array( 'pa_size' => 'large' ) ); - $product_2->save(); - - // Link the product to the term. - $wpdb->insert( - $wpdb->prefix . 'term_relationships', - array( - 'object_id' => $product_2->get_id(), - 'term_taxonomy_id' => $term_large->term_id, - 'term_order' => 0, - ) - ); - - // Products with attribute size == large. - $expected_product_ids = array( - $variable_product->get_id(), - $product_2->get_id(), - ); - $query_params = array( - 'attribute' => 'pa_size', - 'attribute_term' => (string) $term_large->term_id, - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $expected_product_ids ), count( $response_products ) ); - foreach ( $response_products as $response_product ) { - $this->assertContains( $response_product['id'], $expected_product_ids ); - } - - // Products with attribute size == small. - $expected_product_ids = array( - $variable_product->get_id(), - ); - $query_params = array( - 'attribute' => 'pa_size', - 'attribute_term' => (string) $term_small->term_id, - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $expected_product_ids ), count( $response_products ) ); - foreach ( $response_products as $response_product ) { - $this->assertContains( $response_product['id'], $expected_product_ids ); - } - } - - /** - * Test product schema contains embed fields. - */ - public function test_product_schema_embed() { - $product = ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/products/' . $product->get_id() ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $properties_to_embed = array( - 'id', - 'name', - 'slug', - 'permalink', - 'images', - 'description', - 'short_description', - ); - - foreach ( $properties as $property_key => $property ) { - if ( in_array( $property_key, $properties_to_embed, true ) ) { - $this->assertEquals( array( 'view', 'edit', 'embed' ), $property['context'] ); - } - } - - $product->delete( true ); - } -} diff --git a/unit-tests/Tests/Version4/Settings.php b/unit-tests/Tests/Version4/Settings.php deleted file mode 100644 index d65a4680a32..00000000000 --- a/unit-tests/Tests/Version4/Settings.php +++ /dev/null @@ -1,886 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server, endpoints, and user info. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - SettingsHelper::register(); - $this->zones = array(); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v4/settings', $routes ); - $this->assertArrayHasKey( '/wc/v4/settings/(?P[\w-]+)', $routes ); - $this->assertArrayHasKey( '/wc/v4/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all groups. - * - * @since 3.5.0 - */ - public function test_get_groups() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertContains( - array( - 'id' => 'test', - 'label' => 'Test extension', - 'parent_id' => '', - 'description' => 'My awesome test settings.', - 'sub_groups' => array( 'sub-test' ), - '_links' => array( - 'options' => array( - array( - 'href' => rest_url( '/wc/v4/settings/test' ), - ), - ), - ), - ), - $data - ); - - $this->assertContains( - array( - 'id' => 'sub-test', - 'label' => 'Sub test', - 'parent_id' => 'test', - 'description' => '', - 'sub_groups' => array(), - '_links' => array( - 'options' => array( - array( - 'href' => rest_url( '/wc/v4/settings/sub-test' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test /settings without valid permissions/creds. - * - * @since 3.5.0 - */ - public function test_get_groups_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test /settings without valid permissions/creds. - * - * @since 3.5.0 - * @covers WC_Rest_Settings_Controller::get_items - */ - public function test_get_groups_none_registered() { - remove_all_filters( 'woocommerce_settings_groups' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings' ) ); - $this->assertEquals( 500, $response->get_status() ); - - SettingsHelper::register(); - } - - /** - * Test groups schema. - * - * @since 3.5.0 - */ - public function test_get_group_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/settings' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 5, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'parent_id', $properties ); - $this->assertArrayHasKey( 'label', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'sub_groups', $properties ); - } - - /** - * Test settings schema. - * - * @since 3.5.0 - */ - public function test_get_setting_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/settings/test/woocommerce_shop_page_display' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 10, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'label', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'value', $properties ); - $this->assertArrayHasKey( 'default', $properties ); - $this->assertArrayHasKey( 'tip', $properties ); - $this->assertArrayHasKey( 'placeholder', $properties ); - $this->assertArrayHasKey( 'type', $properties ); - $this->assertArrayHasKey( 'options', $properties ); - $this->assertArrayHasKey( 'group_id', $properties ); - } - - /** - * Test getting a single group. - * - * @since 3.5.0 - */ - public function test_get_group() { - // test route callback receiving an empty group id - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // test getting a group that does not exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/not-real' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // test getting the 'invalid' group - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/invalid' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // test getting a valid group with settings attached to it - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test' ) ); - $data = $response->get_data(); - $this->assertEquals( 1, count( $data ) ); - $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); - $this->assertEmpty( $data[0]['value'] ); - } - - /** - * Test getting a single group without permission. - * - * @since 3.5.0 - */ - public function test_get_group_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/coupon-data' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single setting. - * - * @since 3.5.0 - */ - public function test_update_setting() { - // test defaults first - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - $this->assertEquals( '', $data['value'] ); - - // test updating shop display setting - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'both', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'both', $data['value'] ); - $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'subcategories', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'subcategories', $data['value'] ); - $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => '', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '', $data['value'] ); - $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); - } - - /** - * Test updating multiple settings at once. - * - * @since 3.5.0 - */ - public function test_update_settings() { - // test defaults first - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test' ) ); - $data = $response->get_data(); - $this->assertEquals( '', $data[0]['value'] ); - - // test setting both at once - $request = new WP_REST_Request( 'POST', '/wc/v4/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'both', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'both', $data['update'][0]['value'] ); - $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - - // test updating one, but making sure the other value stays the same - $request = new WP_REST_Request( 'POST', '/wc/v4/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'subcategories', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); - $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - } - - /** - * Test getting a single setting. - * - * @since 3.5.0 - */ - public function test_get_setting() { - // test getting an invalid setting from a group that does not exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/not-real/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - $this->assertEquals( 404, $response->get_status() ); - - // test getting an invalid setting from a group that does exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/invalid/invalid' ) ); - $data = $response->get_data(); - $this->assertEquals( 404, $response->get_status() ); - - // test getting a valid setting - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 'woocommerce_shop_page_display', $data['id'] ); - $this->assertEquals( 'Shop page display', $data['label'] ); - $this->assertEquals( '', $data['default'] ); - $this->assertEquals( 'select', $data['type'] ); - $this->assertEquals( '', $data['value'] ); - } - - /** - * Test getting a single setting without valid user permissions. - * - * @since 3.5.0 - */ - public function test_get_setting_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/woocommerce_shop_page_display' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests the GET single setting route handler receiving an empty setting ID. - * - * @since 3.5.0 - */ - public function test_get_setting_empty_setting_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests the GET single setting route handler receiving an invalid setting ID. - * - * @since 3.5.0 - */ - public function test_get_setting_invalid_setting_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/test/invalid' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests the GET single setting route handler encountering an invalid setting type. - * - * @since 3.5.0 - */ - public function test_get_setting_invalid_setting_type() { - // $controller = $this->getMock( 'WC_Rest_Setting_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); - $controller = $this->getMockBuilder( 'WC_Rest_Setting_Options_Controller' )->setMethods( array( 'get_group_settings', 'is_setting_type_valid' ) )->getMock(); - - $controller - ->expects( $this->any() ) - ->method( 'get_group_settings' ) - ->will( $this->returnValue( SettingsHelper::register_test_settings( array() ) ) ); - - $controller - ->expects( $this->any() ) - ->method( 'is_setting_type_valid' ) - ->will( $this->returnValue( false ) ); - - $result = $controller->get_setting( 'test', 'woocommerce_shop_page_display' ); - - $this->assertIsWPError( $result ); - } - - /** - * Test updating a single setting without valid user permissions. - * - * @since 3.5.0 - */ - public function test_update_setting_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'subcategories', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - - /** - * Test updating multiple settings without valid user permissions. - * - * @since 3.5.0 - */ - public function test_update_settings_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v4/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'subcategories', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a bad setting ID. - * - * @since 3.5.0 - * @covers WC_Rest_Setting_Options_Controller::update_item - */ - public function test_update_setting_bad_setting_id() { - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/test/invalid' ); - $request->set_body_params( - array( - 'value' => 'test', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. - * - * @since 3.5.0 - */ - public function test_classic_settings() { - // Make sure the group is properly registered - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/products' ) ); - $data = $response->get_data(); - $this->assertTrue( is_array( $data ) ); - $this->assertContains( - array( - 'id' => 'woocommerce_downloads_require_login', - 'label' => 'Access restriction', - 'description' => 'Downloads require login', - 'type' => 'checkbox', - 'default' => 'no', - 'tip' => 'This setting does not apply to guest purchases.', - 'value' => 'no', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/settings/products/woocommerce_downloads_require_login' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/settings/products' ), - ), - ), - ), - ), - $data - ); - - // test get single - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/products/woocommerce_dimension_unit' ) ); - $data = $response->get_data(); - - $this->assertEquals( 'cm', $data['default'] ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); - $request->set_body_params( - array( - 'value' => 'yd', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'yd', $data['value'] ); - $this->assertEquals( 'yd', get_option( 'woocommerce_dimension_unit' ) ); - } - - /** - * Tests our email etting registration to make sure settings added for WP-Admin are available over the API. - * - * @since 3.5.0 - */ - public function test_email_settings() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/email_new_order' ) ); - $settings = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertContains( - array( - 'id' => 'recipient', - 'label' => 'Recipient(s)', - 'description' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', - 'type' => 'text', - 'default' => '', - 'tip' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', - 'value' => '', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/settings/email_new_order/recipient' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/settings/email_new_order' ), - ), - ), - ), - ), - $settings - ); - - // test get single - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/email_new_order/subject' ) ); - $setting = $response->get_data(); - - $this->assertEquals( - array( - 'id' => 'subject', - 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', - 'type' => 'text', - 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', - 'value' => '', - 'group_id' => 'email_new_order', - ), - $setting - ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_new_order', 'subject' ) ); - $request->set_body_params( - array( - 'value' => 'This is my subject', - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEquals( - array( - 'id' => 'subject', - 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', - 'type' => 'text', - 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', - 'value' => 'This is my subject', - 'group_id' => 'email_new_order', - ), - $setting - ); - - // test updating another subject and making sure it works with a "similar" id - $request = new WP_REST_Request( 'GET', sprintf( '/wc/v4/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEmpty( $setting['value'] ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); - $request->set_body_params( - array( - 'value' => 'This is my new subject', - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEquals( 'This is my new subject', $setting['value'] ); - - // make sure the other is what we left it - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/email_new_order/subject' ) ); - $setting = $response->get_data(); - - $this->assertEquals( 'This is my subject', $setting['value'] ); - } - - /** - * Test validation of checkbox settings. - * - * @since 3.5.0 - */ - public function test_validation_checkbox() { - // test bogus value - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'not_yes_or_no', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // test yes - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'yes', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - // test no - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'no', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test validation of radio settings. - * - * @since 3.5.0 - */ - public function test_validation_radio() { - // not a valid option - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); - $request->set_body_params( - array( - 'value' => 'billing2', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // valid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); - $request->set_body_params( - array( - 'value' => 'billing', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test validation of multiselect. - * - * @since 3.5.0 - */ - public function test_validation_multiselect() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v4/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ) ); - $setting = $response->get_data(); - $this->assertEmpty( $setting['value'] ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ); - $request->set_body_params( - array( - 'value' => array( 'AX', 'DZ', 'MMM' ), - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( array( 'AX', 'DZ' ), $setting['value'] ); - } - - /** - * Test validation of select. - * - * @since 3.5.0 - */ - public function test_validation_select() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ) ); - $setting = $response->get_data(); - $this->assertEquals( 'kg', $setting['value'] ); - - // invalid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); - $request->set_body_params( - array( - 'value' => 'pounds', // invalid, should be lbs - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // valid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v4/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); - $request->set_body_params( - array( - 'value' => 'lbs', // invalid, should be lbs - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( 'lbs', $setting['value'] ); - } - - /** - * Test to make sure the 'base location' setting is present in the response. - * That it is returned as 'select' and not 'single_select_country', - * and that both state and country options are returned. - * - * @since 3.5.0 - */ - public function test_woocommerce_default_country() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_default_country' ) ); - $setting = $response->get_data(); - - $this->assertEquals( 'select', $setting['type'] ); - $this->assertArrayHasKey( 'GB', $setting['options'] ); - $this->assertArrayHasKey( 'US:OR', $setting['options'] ); - } - - /** - * Test to make sure the store address setting can be fetched and updated. - * - * @since 3.5.0 - */ - public function test_woocommerce_store_address() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_address' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_address' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_address' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store address 2 (line 2) setting can be fetched and updated. - * - * @since 3.5.0 - */ - public function test_woocommerce_store_address_2() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_address_2' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_address_2' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_address_2' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store city setting can be fetched and updated. - * - * @since 3.5.0 - */ - public function test_woocommerce_store_city() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_city' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_city' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_city' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store postcode setting can be fetched and updated. - * - * @since 3.5.0 - */ - public function test_woocommerce_store_postcode() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/settings/general/woocommerce_store_postcode' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_postcode' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v4/settings/general/woocommerce_store_postcode' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } -} diff --git a/unit-tests/Tests/Version4/ShippingMethods.php b/unit-tests/Tests/Version4/ShippingMethods.php deleted file mode 100644 index 987f5755fa9..00000000000 --- a/unit-tests/Tests/Version4/ShippingMethods.php +++ /dev/null @@ -1,159 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server, endpoints, and user info. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - $this->zones = array(); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v4/shipping_methods', $routes ); - $this->assertArrayHasKey( '/wc/v4/shipping_methods/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all shipping methods. - * - * @since 3.5.0 - */ - public function test_get_shipping_methods() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods' ) ); - $methods = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => 'free_shipping', - 'title' => 'Free shipping', - 'description' => 'Free shipping is a special method which can be triggered with coupons and minimum spends.', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/shipping_methods/free_shipping' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping_methods' ), - ), - ), - ), - ), - $methods - ); - } - - /** - * Tests to make sure shipping methods cannot viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_shipping_methods_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a single shipping method. - * - * @since 3.5.0 - */ - public function test_get_shipping_method() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods/local_pickup' ) ); - $method = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => 'local_pickup', - 'title' => 'Local pickup', - 'description' => 'Allow customers to pick up orders themselves. By default, when using local pickup store base taxes will apply regardless of customer address.', - ), - $method - ); - } - - /** - * Tests getting a single shipping method without the correct permissions. - * - * @since 3.5.0 - */ - public function test_get_shipping_method_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods/local_pickup' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a shipping method with an invalid ID. - * - * @since 3.5.0 - */ - public function test_get_shipping_method_invalid_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping_methods/fake_method' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test the shipping method schema. - * - * @since 3.5.0 - */ - public function test_shipping_method_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/shipping_methods' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'title', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - } -} diff --git a/unit-tests/Tests/Version4/ShippingZones.php b/unit-tests/Tests/Version4/ShippingZones.php deleted file mode 100644 index 38cacecda06..00000000000 --- a/unit-tests/Tests/Version4/ShippingZones.php +++ /dev/null @@ -1,811 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server, endpoints, and user info. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - $this->zones = array(); - } - - /** - * Helper method to create a Shipping Zone. - * - * @param string $name Zone name. - * @param int $order Optional. Zone sort order. - * @return WC_Shipping_Zone - */ - protected function create_shipping_zone( $name, $order = 0, $locations = array() ) { - $zone = new \WC_Shipping_Zone( null ); - $zone->set_zone_name( $name ); - $zone->set_zone_order( $order ); - $zone->set_locations( $locations ); - $zone->save(); - - $this->zones[] = $zone; - - return $zone; - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v4/shipping/zones', $routes ); - $this->assertArrayHasKey( '/wc/v4/shipping/zones/(?P[\d-]+)', $routes ); - $this->assertArrayHasKey( '/wc/v4/shipping/zones/(?P[\d]+)/locations', $routes ); - $this->assertArrayHasKey( '/wc/v4/shipping/zones/(?P[\d]+)/methods', $routes ); - $this->assertArrayHasKey( '/wc/v4/shipping/zones/(?P[\d]+)/methods/(?P[\d]+)', $routes ); - } - - /** - * Test getting all Shipping Zones. - * - * @since 3.5.0 - */ - public function test_get_zones() { - // "Rest of the World" zone exists by default - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertContains( - array( - 'id' => $data[0]['id'], - 'name' => 'Locations not covered by your other zones', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $data[0]['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $data[0]['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - - // Create a zone and make sure it's in the response - $this->create_shipping_zone( 'Zone 1' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 2 ); - $this->assertContains( - array( - 'id' => $data[1]['id'], - 'name' => 'Zone 1', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $data[1]['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $data[1]['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test /shipping/zones without valid permissions/creds. - * - * @since 3.5.0 - */ - public function test_get_shipping_zones_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test /shipping/zones while Shipping is disabled in WooCommerce. - * - * @since 3.5.0 - */ - public function test_get_shipping_zones_disabled_shipping() { - add_filter( 'wc_shipping_enabled', '__return_false' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones' ) ); - $this->assertEquals( 404, $response->get_status() ); - - remove_filter( 'wc_shipping_enabled', '__return_false' ); - } - - /** - * Test Shipping Zone schema. - * - * @since 3.5.0 - */ - public function test_get_shipping_zone_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/shipping/zones' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertTrue( $properties['id']['readonly'] ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'order', $properties ); - } - - /** - * Test Shipping Zone create endpoint. - * - * @since 3.5.0 - */ - public function test_create_shipping_zone() { - $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones' ); - $request->set_body_params( - array( - 'name' => 'Test Zone', - 'order' => 1, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'name' => 'Test Zone', - 'order' => 1, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $data['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $data['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test Shipping Zone create endpoint. - * - * @since 3.5.0 - */ - public function test_create_shipping_zone_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones' ); - $request->set_body_params( - array( - 'name' => 'Test Zone', - 'order' => 1, - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test Shipping Zone update endpoint. - * - * @since 3.5.0 - */ - public function test_update_shipping_zone() { - $zone = $this->create_shipping_zone( 'Test Zone' ); - - $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/' . $zone->get_id() ); - $request->set_body_params( - array( - 'name' => 'Zone Test', - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $zone->get_id(), - 'name' => 'Zone Test', - 'order' => 2, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test Shipping Zone update endpoint with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_update_shipping_zone_invalid_id() { - $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/555555' ); - $request->set_body_params( - array( - 'name' => 'Zone Test', - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint. - * - * @since 3.5.0 - */ - public function test_delete_shipping_zone() { - $zone = $this->create_shipping_zone( 'Zone 1' ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/' . $zone->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint without permissions. - * - * @since 3.5.0 - */ - public function test_delete_shipping_zone_without_permission() { - wp_set_current_user( 0 ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/' . $zone->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_delete_shipping_zone_invalid_id() { - $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/555555' ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single Shipping Zone. - * - * @since 3.5.0 - */ - public function test_get_single_shipping_zone() { - $zone = $this->create_shipping_zone( 'Test Zone' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $zone->get_id(), - 'name' => 'Test Zone', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test getting a single Shipping Zone with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_get_single_shipping_zone_invalid_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting Shipping Zone Locations. - * - * @since 3.5.0 - */ - public function test_get_locations() { - // Create a zone - $zone = $this->create_shipping_zone( - 'Zone 1', - 0, - array( - array( - 'code' => 'US', - 'type' => 'country', - ), - ) - ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertEquals( - array( - array( - 'code' => 'US', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test getting Shipping Zone Locations with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_get_locations_invalid_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1/locations' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test Shipping Zone Locations update endpoint. - * - * @since 3.5.0 - */ - public function test_update_locations() { - $zone = $this->create_shipping_zone( 'Test Zone' ); - - $request = new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ); - $request->add_header( 'Content-Type', 'application/json' ); - $request->set_body( - json_encode( - array( - array( - 'code' => 'UK', - 'type' => 'country', - ), - array( - 'code' => 'US', // test that locations missing "type" treated as country. - ), - array( - 'code' => 'SW1A0AA', - 'type' => 'postcode', - ), - array( - 'type' => 'continent', // test that locations missing "code" aren't saved - ), - ) - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - $this->assertEquals( - array( - array( - 'code' => 'UK', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - array( - 'code' => 'US', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - array( - 'code' => 'SW1A0AA', - 'type' => 'postcode', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test updating Shipping Zone Locations with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_update_locations_invalid_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'PUT', '/wc/v4/shipping/zones/1/locations' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting all Shipping Zone Methods and getting a single Shipping Zone Method. - * - * @since 3.5.0 - */ - public function test_get_methods() { - // Create a shipping method and make sure it's in the response - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - - $settings = array(); - $method->init_instance_settings(); - foreach ( $method->get_instance_form_fields() as $id => $field ) { - $data = array( - 'id' => $id, - 'label' => $field['title'], - 'description' => ( empty( $field['description'] ) ? '' : $field['description'] ), - 'type' => $field['type'], - 'value' => $method->instance_settings[ $id ], - 'default' => ( empty( $field['default'] ) ? '' : $field['default'] ), - 'tip' => ( empty( $field['description'] ) ? '' : $field['description'] ), - 'placeholder' => ( empty( $field['placeholder'] ) ? '' : $field['placeholder'] ), - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods' ) ); - $data = $response->get_data(); - $expected = array( - 'id' => $instance_id, - 'instance_id' => $instance_id, - 'title' => $method->instance_settings['title'], - 'order' => $method->method_order, - 'enabled' => ( 'yes' === $method->enabled ), - 'method_id' => $method->id, - 'method_title' => $method->method_title, - 'method_description' => $method->method_description, - 'settings' => $settings, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v4/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertContains( $expected, $data ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $expected, $data ); - } - - /** - * Test getting all Shipping Zone Methods with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_get_methods_invalid_zone_id() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1/methods' ) ); - - $this->assertEquals( 404, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/1/methods/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single Shipping Zone Method with a bad ID. - * - * @since 3.5.0 - */ - public function test_get_methods_invalid_method_id() { - $zone = $this->create_shipping_zone( 'Zone 1' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a Shipping Zone Method. - * - * @since 3.5.0 - */ - public function test_update_methods() { - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - - // Test defaults - $request = new WP_REST_Request( 'GET', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '0', $data['settings']['cost']['value'] ); - - // Update a single value - $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 5, - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '5', $data['settings']['cost']['value'] ); - - // Test multiple settings - $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 10, - 'tax_status' => 'none', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'none', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '10', $data['settings']['cost']['value'] ); - - // Test bogus - $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 10, - 'tax_status' => 'this_is_not_a_valid_option', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // Test other parameters - $this->assertTrue( $data['enabled'] ); - $this->assertEquals( 1, $data['order'] ); - - $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertFalse( $data['enabled'] ); - $this->assertEquals( 2, $data['order'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '10', $data['settings']['cost']['value'] ); - } - - /** - * Test creating a Shipping Zone Method. - * - * @since 3.5.0 - */ - public function test_create_method() { - $zone = $this->create_shipping_zone( 'Zone 1' ); - $request = new WP_REST_Request( 'POST', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods' ); - $request->set_body_params( - array( - 'method_id' => 'flat_rate', - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertFalse( $data['enabled'] ); - $this->assertEquals( 2, $data['order'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '0', $data['settings']['cost']['value'] ); - } - - /** - * Test deleting a Shipping Zone Method. - * - * @since 3.5.0 - */ - public function test_delete_method() { - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - $request = new WP_REST_Request( 'DELETE', '/wc/v4/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } -} diff --git a/unit-tests/Tests/Version4/SystemStatus.php b/unit-tests/Tests/Version4/SystemStatus.php deleted file mode 100644 index b4932e9b880..00000000000 --- a/unit-tests/Tests/Version4/SystemStatus.php +++ /dev/null @@ -1,459 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - - // Callback used by WP_HTTP_TestCase to decide whether to perform HTTP requests or to provide a mocked response. - $this->http_responder = array( $this, 'mock_http_responses' ); - } - - /** - * Test route registration. - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v4/system_status', $routes ); - $this->assertArrayHasKey( '/wc/v4/system_status/tools', $routes ); - $this->assertArrayHasKey( '/wc/v4/system_status/tools/(?P[\w-]+)', $routes ); - } - - /** - * Test to make sure system status cannot be accessed without valid creds - * - * @since 3.5.0 - */ - public function test_get_system_status_info_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure root properties are present. - * (environment, theme, database, etc). - * - * @since 3.5.0 - */ - public function test_get_system_status_info_returns_root_properties() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'environment', $data ); - $this->assertArrayHasKey( 'database', $data ); - $this->assertArrayHasKey( 'active_plugins', $data ); - $this->assertArrayHasKey( 'theme', $data ); - $this->assertArrayHasKey( 'settings', $data ); - $this->assertArrayHasKey( 'security', $data ); - $this->assertArrayHasKey( 'pages', $data ); - } - - /** - * Test to make sure environment response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_environment() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - $data = $response->get_data(); - $environment = (array) $data['environment']; - - // Make sure all expected data is present. - $this->assertEquals( 32, count( $environment ) ); - - // Test some responses to make sure they match up. - $this->assertEquals( get_option( 'home' ), $environment['home_url'] ); - $this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] ); - $this->assertEquals( WC()->version, $environment['version'] ); - } - - /** - * Test to make sure database response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_database() { - global $wpdb; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - $data = $response->get_data(); - $database = (array) $data['database']; - - $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); - $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); - $this->assertEquals( \WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); - $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], wc_print_r( $database, true ) ); - $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], wc_print_r( $database, true ) ); - } - - /** - * Test to make sure active plugins response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_active_plugins() { - $actual_plugins = array( 'hello.php' ); - update_option( 'active_plugins', $actual_plugins ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - update_option( 'active_plugins', array() ); - - $data = $response->get_data(); - $plugins = (array) $data['active_plugins']; - - $this->assertEquals( 1, count( $plugins ) ); - $this->assertEquals( 'Hello Dolly', $plugins[0]['name'] ); - } - - /** - * Test to make sure theme response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_theme() { - $active_theme = wp_get_theme(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - $data = $response->get_data(); - $theme = (array) $data['theme']; - - $this->assertEquals( 13, count( $theme ) ); - $this->assertEquals( $active_theme->Name, $theme['name'] ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar - } - - /** - * Test to make sure settings response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_settings() { - $term_response = array(); - $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); - foreach ( $terms as $term ) { - $term_response[ $term->slug ] = strtolower( $term->name ); - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - $data = $response->get_data(); - $settings = (array) $data['settings']; - - $this->assertEquals( 12, count( $settings ) ); - $this->assertEquals( ( 'yes' === get_option( 'woocommerce_api_enabled' ) ), $settings['api_enabled'] ); - $this->assertEquals( get_woocommerce_currency(), $settings['currency'] ); - $this->assertEquals( $term_response, $settings['taxonomies'] ); - } - - /** - * Test to make sure security response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_security() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - $data = $response->get_data(); - $settings = (array) $data['security']; - - $this->assertEquals( 2, count( $settings ) ); - $this->assertEquals( 'https' === substr( wc_get_page_permalink( 'shop' ), 0, 5 ), $settings['secure_connection'] ); - $this->assertEquals( ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), $settings['hide_errors'] ); - } - - /** - * Test to make sure pages response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_pages() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status' ) ); - $data = $response->get_data(); - $pages = $data['pages']; - $this->assertEquals( 5, count( $pages ) ); - } - - /** - * Test system status schema. - * - * @since 3.5.0 - */ - public function test_system_status_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/system_status' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 10, count( $properties ) ); - $this->assertArrayHasKey( 'environment', $properties ); - $this->assertArrayHasKey( 'database', $properties ); - $this->assertArrayHasKey( 'active_plugins', $properties ); - $this->assertArrayHasKey( 'theme', $properties ); - $this->assertArrayHasKey( 'settings', $properties ); - $this->assertArrayHasKey( 'security', $properties ); - $this->assertArrayHasKey( 'pages', $properties ); - } - - /** - * Test to make sure get_items (all tools) response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_tools() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => 'regenerate_thumbnails', - 'name' => 'Regenerate shop thumbnails', - 'action' => 'Regenerate', - 'description' => 'This will regenerate all shop thumbnails to match your theme and/or image settings.', - '_links' => array( - 'item' => array( - array( - 'href' => rest_url( '/wc/v4/system_status/tools/regenerate_thumbnails' ), - 'embeddable' => 1, - ), - ), - ), - ), - $data - ); - - $query_params = array( - '_fields' => 'id,name,nonexisting', - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/system_status/tools' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => 'regenerate_thumbnails', - 'name' => 'Regenerate shop thumbnails', - ), - $data - ); - foreach ( $data as $item ) { - // Fields that are not requested are not returned in response. - $this->assertArrayNotHasKey( 'action', $item ); - $this->assertArrayNotHasKey( 'description', $item ); - // Links are part of data in collections, so excluded if not explicitly requested. - $this->assertArrayNotHasKey( '_links', $item ); - // Non existing field is ignored. - $this->assertArrayNotHasKey( 'nonexisting', $item ); - } - - // Links are part of data, not links in collections. - $links = $response->get_links(); - $this->assertEquals( 0, count( $links ) ); - } - - /** - * Test to make sure system status tools cannot be accessed without valid creds - * - * @since 3.5.0 - */ - public function test_get_system_status_tools_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure we can load a single tool correctly. - * - * @since 3.5.0 - */ - public function test_get_system_tool() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools/recount_terms' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertEquals( 'Term counts', $data['name'] ); - $this->assertEquals( 'Recount terms', $data['action'] ); - $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); - - // Test for _fields query parameter. - $query_params = array( - '_fields' => 'id,name,nonexisting', - ); - $request = new WP_REST_Request( 'GET', '/wc/v4/system_status/tools/recount_terms' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertEquals( 'Term counts', $data['name'] ); - $this->assertArrayNotHasKey( 'action', $data ); - $this->assertArrayNotHasKey( 'description', $data ); - // Links are part of links, not data in single items. - $this->assertArrayNotHasKey( '_links', $data ); - - // Links are part of links, not data in single item response. - $links = $response->get_links(); - $this->assertEquals( 1, count( $links ) ); - } - - /** - * Test to make sure a single system status toolscannot be accessed without valid creds. - * - * @since 3.5.0 - */ - public function test_get_system_status_tool_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v4/system_status/tools/recount_terms' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure we can RUN a tool correctly. - * - * @since 3.5.0 - */ - public function test_execute_system_tool() { - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v4/system_status/tools/recount_terms' ) ); - $data = $response->get_data(); - - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertEquals( 'Term counts', $data['name'] ); - $this->assertEquals( 'Recount terms', $data['action'] ); - $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); - $this->assertTrue( $data['success'] ); - $this->assertEquals( 1, did_action( 'woocommerce_rest_insert_system_status_tool' ) ); - - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v4/system_status/tools/not_a_real_tool' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // Test _fields for execute system tool request. - $query_params = array( - '_fields' => 'id,success,nonexisting', - ); - $request = new WP_REST_Request( 'PUT', '/wc/v4/system_status/tools/recount_terms' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertTrue( $data['success'] ); - - // Fields that are not requested are not returned in response. - $this->assertArrayNotHasKey( 'action', $data ); - $this->assertArrayNotHasKey( 'name', $data ); - $this->assertArrayNotHasKey( 'description', $data ); - // Links are part of links, not data in single item response. - $this->assertArrayNotHasKey( '_links', $data ); - // Non existing field is ignored. - $this->assertArrayNotHasKey( 'nonexisting', $data ); - - // Links are part of links, not data in single item response. - $links = $response->get_links(); - $this->assertEquals( 1, count( $links ) ); - } - - /** - * Test to make sure a tool cannot be run without valid creds. - * - * @since 3.5.0 - */ - public function test_execute_system_status_tool_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v4/system_status/tools/recount_terms' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test system status schema. - * - * @since 3.5.0 - */ - public function test_system_status_tool_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v4/system_status/tools' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 6, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'action', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'success', $properties ); - $this->assertArrayHasKey( 'message', $properties ); - } - - /** - * Provides a mocked response for external requests. - * This way it is not necessary to perform a regular request to an external server which would - * significantly slow down the tests. - * - * This function is called by WP_HTTP_TestCase::http_request_listner(). - * - * @param array $request Request arguments. - * @param string $url URL of the request. - * - * @return array|false mocked response or false to let WP perform a regular request. - */ - protected function mock_http_responses( $request, $url ) { - $mocked_response = false; - - if ( in_array( $url, array( 'https://www.paypal.com/cgi-bin/webscr', 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=0' ), true ) ) { - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } elseif ( 'https://api.wordpress.org/themes/info/1.0/' === $url ) { - $mocked_response = array( - 'body' => 'O:8:"stdClass":12:{s:4:"name";s:7:"Default";s:4:"slug";s:7:"default";s:7:"version";s:5:"1.7.2";s:11:"preview_url";s:29:"https://wp-themes.com/default";s:6:"author";s:15:"wordpressdotorg";s:14:"screenshot_url";s:61:"//ts.w.org/wp-content/themes/default/screenshot.png?ver=1.7.2";s:6:"rating";d:100;s:11:"num_ratings";s:1:"3";s:10:"downloaded";i:296618;s:12:"last_updated";s:10:"2010-06-14";s:8:"homepage";s:37:"https://wordpress.org/themes/default/";s:13:"download_link";s:55:"https://downloads.wordpress.org/theme/default.1.7.2.zip";}', - 'response' => array( 'code' => 200 ), - ); - } - - return $mocked_response; - } -} diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 474529f1cc1..7753c7d5c97 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.1.0-dev + * Version: 1.0.0 * Requires PHP: 5.6 * License: GPLv3 * From 53fccbbf7d0c5095d6c9980fbd940aada4414e73 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 25 Jun 2019 16:20:26 +0100 Subject: [PATCH 182/440] Fix paths --- .gitignore | 2 +- .travis.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 77f4d76fe9c..b19a8d1f0ae 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,7 @@ Thumbs.db # Unit tests /tmp -/tests/bin/tmp +/unit-tests/bin/tmp # Logs /logs diff --git a/.travis.yml b/.travis.yml index 38f92b14e2c..31fac7a6447 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,8 +20,8 @@ before_script: - composer install - composer global require "phpunit/phpunit=4.8.*|6.5.*" - composer require woocommerce/woocommerce-sniffs - - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION + - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION script: - - bash tests/bin/phpunit.sh - - bash tests/bin/phpcs.sh + - bash unit-tests/bin/phpunit.sh + - bash unit-tests/bin/phpcs.sh From 4ba989a07e4dc76d262e41a58fb90ff0c2a22da1 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 26 Jun 2019 15:26:58 +0100 Subject: [PATCH 183/440] Changes from master --- .../Version2/class-wc-rest-customers-v2-controller.php | 2 +- src/Controllers/Version3/class-wc-rest-controller.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php index bc72be9664e..05986657e8d 100644 --- a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php @@ -133,7 +133,7 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/src/Controllers/Version3/class-wc-rest-controller.php b/src/Controllers/Version3/class-wc-rest-controller.php index 4fa75d21259..57c4040e433 100644 --- a/src/Controllers/Version3/class-wc-rest-controller.php +++ b/src/Controllers/Version3/class-wc-rest-controller.php @@ -132,6 +132,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { // Get the request params. $items = array_filter( $request->get_params() ); + $query = $request->get_query_params(); $response = array(); // Check batch limit. @@ -156,6 +157,10 @@ abstract class WC_REST_Controller extends WP_REST_Controller { // Set request parameters. $_item->set_body_params( $item ); + + // Set query (GET) parameters. + $_item->set_query_params( $query ); + $_response = $this->create_item( $_item ); if ( is_wp_error( $_response ) ) { From 1d0bd12a4664f7ba943c520297a470d3a21e9f30 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 26 Jun 2019 15:28:56 +0100 Subject: [PATCH 184/440] Moved hook like in master v3 --- .../class-wc-rest-crud-controller.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Controllers/Version3/class-wc-rest-crud-controller.php b/src/Controllers/Version3/class-wc-rest-crud-controller.php index 1c66e9bbd20..76447c2e9fc 100644 --- a/src/Controllers/Version3/class-wc-rest-crud-controller.php +++ b/src/Controllers/Version3/class-wc-rest-crud-controller.php @@ -196,6 +196,15 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { try { $this->update_additional_fields_for_object( $object, $request ); + + /** + * Fires after a single object is created or updated via the REST API. + * + * @param WC_Data $object Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating object, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); } catch ( WC_Data_Exception $e ) { $object->delete(); return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); @@ -204,15 +213,6 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } - /** - * Fires after a single object is created or updated via the REST API. - * - * @param WC_Data $object Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating object, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); - $request->set_param( 'context', 'edit' ); $response = $this->prepare_object_for_response( $object, $request ); $response = rest_ensure_response( $response ); @@ -243,21 +243,21 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { try { $this->update_additional_fields_for_object( $object, $request ); + + /** + * Fires after a single object is created or updated via the REST API. + * + * @param WC_Data $object Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating object, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); } catch ( WC_Data_Exception $e ) { return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); } catch ( WC_REST_Exception $e ) { return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); } - /** - * Fires after a single object is created or updated via the REST API. - * - * @param WC_Data $object Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating object, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); - $request->set_param( 'context', 'edit' ); $response = $this->prepare_object_for_response( $object, $request ); return rest_ensure_response( $response ); From 72c5a6687d52cc1d9672c279de1a1eeb66f3ab4e Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 8 Jul 2019 15:00:49 -0300 Subject: [PATCH 185/440] Fixed PHP notices when DB receives "ENGINE" instead of "engine" --- .../Version2/class-wc-rest-system-status-v2-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 64e7093fb12..25705f72854 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -700,7 +700,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { $wpdb->prepare( "SELECT table_name AS 'name', - engine, + engine AS 'engine', round( ( data_length / 1024 / 1024 ), 2 ) 'data', round( ( index_length / 1024 / 1024 ), 2 ) 'index' FROM information_schema.TABLES From 83da0a228384c9f438f43889ea319344215fe206 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 8 Jul 2019 18:21:06 -0300 Subject: [PATCH 186/440] Reflect new changes from https://github.com/woocommerce/woocommerce/pull/23093 --- ...lass-wc-rest-tax-classes-v1-controller.php | 61 +++---------------- 1 file changed, 9 insertions(+), 52 deletions(-) diff --git a/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php index 365d0c440f8..5a7206fb6a6 100644 --- a/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php @@ -158,37 +158,18 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { } /** - * Create a single tax. + * Create a single tax class. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|WP_REST_Response */ public function create_item( $request ) { - $exists = false; - $classes = WC_Tax::get_tax_classes(); - $tax_class = array( - 'slug' => sanitize_title( $request['name'] ), - 'name' => $request['name'], - ); + $tax_class = WC_Tax::create_tax_class( $request['name'] ); - // Check if class exists. - foreach ( $classes as $key => $class ) { - if ( sanitize_title( $class ) === $tax_class['slug'] ) { - $exists = true; - break; - } + if ( is_wp_error( $tax_class ) ) { + return new WP_Error( 'woocommerce_rest_' . $tax_class->get_error_code(), $tax_class->get_error_message(), array( 'status' => 400 ) ); } - // Return error if tax class already exists. - if ( $exists ) { - return new WP_Error( 'woocommerce_rest_tax_class_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - // Add the new class. - $classes[] = $tax_class['name']; - - update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); - $this->update_additional_fields_for_object( $tax_class, $request ); /** @@ -225,40 +206,16 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); } - $tax_class = array( - 'slug' => sanitize_title( $request['slug'] ), - 'name' => '', - ); - $classes = WC_Tax::get_tax_classes(); - $deleted = false; - - foreach ( $classes as $key => $class ) { - if ( sanitize_title( $class ) === $tax_class['slug'] ) { - $tax_class['name'] = $class; - unset( $classes[ $key ] ); - $deleted = true; - break; - } - } + $tax_class = WC_Tax::get_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); + $deleted = WC_Tax::delete_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); if ( ! $deleted ) { return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); } - update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) ); - - // Delete tax rate locations locations from the selected class. - $wpdb->query( $wpdb->prepare( " - DELETE locations.* - FROM {$wpdb->prefix}woocommerce_tax_rate_locations AS locations - INNER JOIN - {$wpdb->prefix}woocommerce_tax_rates AS rates - ON rates.tax_rate_id = locations.tax_rate_id - WHERE rates.tax_rate_class = '%s' - ", $tax_class['slug'] ) ); - - // Delete tax rates in the selected class. - $wpdb->delete( $wpdb->prefix . 'woocommerce_tax_rates', array( 'tax_rate_class' => $tax_class['slug'] ), array( '%s' ) ); + if ( is_wp_error( $deleted ) ) { + return new WP_Error( 'woocommerce_rest_' . $deleted->get_error_code(), $deleted->get_error_message(), array( 'status' => 400 ) ); + } $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $tax_class, $request ); From 5170d9f296dd67a38b1faba8b45f27b3104deb49 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 10 Jul 2019 11:04:05 +0100 Subject: [PATCH 187/440] Update tests --- unit-tests/Tests/Version2/settings.php | 8 ++++---- unit-tests/Tests/Version3/settings.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/unit-tests/Tests/Version2/settings.php b/unit-tests/Tests/Version2/settings.php index 3debe1b5272..ff6b36a0492 100644 --- a/unit-tests/Tests/Version2/settings.php +++ b/unit-tests/Tests/Version2/settings.php @@ -546,10 +546,10 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { array( 'id' => 'subject', 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'description' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', 'type' => 'text', 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'tip' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', 'value' => '', ), $setting @@ -569,10 +569,10 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { array( 'id' => 'subject', 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'description' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', 'type' => 'text', 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'tip' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', 'value' => 'This is my subject', ), $setting diff --git a/unit-tests/Tests/Version3/settings.php b/unit-tests/Tests/Version3/settings.php index d78e2faef9b..e77b69ee888 100644 --- a/unit-tests/Tests/Version3/settings.php +++ b/unit-tests/Tests/Version3/settings.php @@ -547,10 +547,10 @@ class Settings extends WC_REST_Unit_Test_Case { array( 'id' => 'subject', 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'description' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', 'type' => 'text', 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'tip' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', 'value' => '', 'group_id' => 'email_new_order', ), @@ -571,10 +571,10 @@ class Settings extends WC_REST_Unit_Test_Case { array( 'id' => 'subject', 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'description' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', 'type' => 'text', 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {order_date}, {order_number}', + 'tip' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', 'value' => 'This is my subject', 'group_id' => 'email_new_order', ), From 1b3ea5eef13afb15aef68dd5aff4b44052ff1fdf Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 10 Jul 2019 11:11:48 +0100 Subject: [PATCH 188/440] Version --- src/Package.php | 2 +- woocommerce-rest-api.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Package.php b/src/Package.php index ec3cc6474d2..16b036e13b6 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.0'; + const VERSION = '1.0.2'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 7753c7d5c97..041ba9d66bc 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.0 + * Version: 1.0.2 * Requires PHP: 5.6 * License: GPLv3 * From 7d9babf1c25890c32df3edb28b8351732640f5ce Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 16 Jul 2019 10:50:01 -0300 Subject: [PATCH 189/440] Fix: check if DB_NAME is defined before using it Port of https://github.com/woocommerce/woocommerce-rest-api/pull/3 for v2 and v3 --- ...ss-wc-rest-system-status-v2-controller.php | 149 +++++++++--------- 1 file changed, 78 insertions(+), 71 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 25705f72854..22acc2e5aa4 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -696,80 +696,87 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { public function get_database_info() { global $wpdb; - $database_table_information = $wpdb->get_results( - $wpdb->prepare( - "SELECT - table_name AS 'name', - engine AS 'engine', - round( ( data_length / 1024 / 1024 ), 2 ) 'data', - round( ( index_length / 1024 / 1024 ), 2 ) 'index' - FROM information_schema.TABLES - WHERE table_schema = %s - ORDER BY name ASC;", - DB_NAME - ) - ); + $tables = array(); + $database_size = array(); - // WC Core tables to check existence of. - $core_tables = apply_filters( - 'woocommerce_database_tables', - array( - 'woocommerce_sessions', - 'woocommerce_api_keys', - 'woocommerce_attribute_taxonomies', - 'woocommerce_downloadable_product_permissions', - 'woocommerce_order_items', - 'woocommerce_order_itemmeta', - 'woocommerce_tax_rates', - 'woocommerce_tax_rate_locations', - 'woocommerce_shipping_zones', - 'woocommerce_shipping_zone_locations', - 'woocommerce_shipping_zone_methods', - 'woocommerce_payment_tokens', - 'woocommerce_payment_tokenmeta', - 'woocommerce_log', - ) - ); - - /** - * Adding the prefix to the tables array, for backwards compatibility. - * - * If we changed the tables above to include the prefix, then any filters against that table could break. - */ - $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); - - /** - * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. - * - * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. - */ - $tables = array( - 'woocommerce' => array_fill_keys( $core_tables, false ), - 'other' => array(), - ); - - $database_size = array( - 'data' => 0, - 'index' => 0, - ); - - $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); - $global_tables = $wpdb->tables( 'global', true ); - foreach ( $database_table_information as $table ) { - // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. - if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { - continue; - } - $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce' : 'other'; - - $tables[ $table_type ][ $table->name ] = array( - 'data' => $table->data, - 'index' => $table->index, - 'engine' => $table->engine, + // It is not possible to get the database name from some classes that replace wpdb (e.g., HyperDB) + // and that is why this if condition is needed. + if ( defined( 'DB_NAME' ) ) { + $database_table_information = $wpdb->get_results( + $wpdb->prepare( + "SELECT + table_name AS 'name', + engine AS 'engine', + round( ( data_length / 1024 / 1024 ), 2 ) 'data', + round( ( index_length / 1024 / 1024 ), 2 ) 'index' + FROM information_schema.TABLES + WHERE table_schema = %s + ORDER BY name ASC;", + DB_NAME + ) ); - $database_size['data'] += $table->data; - $database_size['index'] += $table->index; + // WC Core tables to check existence of. + $core_tables = apply_filters( + 'woocommerce_database_tables', + array( + 'woocommerce_sessions', + 'woocommerce_api_keys', + 'woocommerce_attribute_taxonomies', + 'woocommerce_downloadable_product_permissions', + 'woocommerce_order_items', + 'woocommerce_order_itemmeta', + 'woocommerce_tax_rates', + 'woocommerce_tax_rate_locations', + 'woocommerce_shipping_zones', + 'woocommerce_shipping_zone_locations', + 'woocommerce_shipping_zone_methods', + 'woocommerce_payment_tokens', + 'woocommerce_payment_tokenmeta', + 'woocommerce_log', + ) + ); + + /** + * Adding the prefix to the tables array, for backwards compatibility. + * + * If we changed the tables above to include the prefix, then any filters against that table could break. + */ + $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); + + /** + * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. + * + * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. + */ + $tables = array( + 'woocommerce' => array_fill_keys( $core_tables, false ), + 'other' => array(), + ); + + $database_size = array( + 'data' => 0, + 'index' => 0, + ); + + $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); + $global_tables = $wpdb->tables( 'global', true ); + foreach ( $database_table_information as $table ) { + // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. + if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { + continue; + } + $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce' : 'other'; + + $tables[ $table_type ][ $table->name ] = array( + 'data' => $table->data, + 'index' => $table->index, + 'engine' => $table->engine, + ); + + $database_size['data'] += $table->data; + $database_size['index'] += $table->index; + } } // Return all database info. Described by JSON Schema. From 0b1c1dd42205488542aeabc5a14068dad532f9f0 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 31 Jul 2019 15:58:22 -0300 Subject: [PATCH 190/440] Fixed date_created and date_created_gmt for customers v2 --- .../Version2/class-wc-rest-customers-v2-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php index 05986657e8d..29d4e07d2e2 100644 --- a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php @@ -38,7 +38,7 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { // Format date values. foreach ( $format_date as $key ) { - $datetime = $data[ $key ]; + $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); } From 613502e57dda6094b8156e4a5f276cdcb76d2523 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 5 Dec 2019 21:58:57 -0300 Subject: [PATCH 191/440] Fixed WooCommerce 3.9 support --- .../class-wc-rest-system-status-tools-v2-controller.php | 7 ++++++- unit-tests/Helpers/ProductHelper.php | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 37394960d2a..325f551d935 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -516,7 +516,12 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { case 'delete_taxes': $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); - WC_Cache_Helper::incr_cache_prefix( 'taxes' ); + + if ( method_exists( 'WC_Cache_Helper', 'invalidate_cache_group' ) ) { + WC_Cache_Helper::invalidate_cache_group( 'taxes' ); + } else { + WC_Cache_Helper::incr_cache_prefix( 'taxes' ); + } $message = __( 'Tax rates successfully deleted', 'woocommerce-rest-api' ); break; diff --git a/unit-tests/Helpers/ProductHelper.php b/unit-tests/Helpers/ProductHelper.php index 5c7fffa4dd8..78d4333610e 100644 --- a/unit-tests/Helpers/ProductHelper.php +++ b/unit-tests/Helpers/ProductHelper.php @@ -179,7 +179,11 @@ class ProductHelper { // Make sure caches are clean. \delete_transient( 'wc_attribute_taxonomies' ); - WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' ); + if ( method_exists( '\WC_Cache_Helper', 'invalidate_cache_group' ) ) { + \WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + } else { + \WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' ); + } // These are exported as labels, so convert the label to a name if possible first. $attribute_labels = \wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name' ); From 59a3bc7525eccd23f21f64ab8c467501b17b0838 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Fri, 19 Jul 2019 11:09:55 -0300 Subject: [PATCH 192/440] Use WP_UnitTestCase::assertWPError() instead of WC_Unit_Test_Case::assertIsWPError() See https://github.com/woocommerce/woocommerce/pull/24207 --- unit-tests/Tests/Version2/settings.php | 8 ++++---- unit-tests/Tests/Version3/functions.php | 6 +++--- unit-tests/Tests/Version3/settings.php | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/unit-tests/Tests/Version2/settings.php b/unit-tests/Tests/Version2/settings.php index ff6b36a0492..98d58c80dfc 100644 --- a/unit-tests/Tests/Version2/settings.php +++ b/unit-tests/Tests/Version2/settings.php @@ -163,7 +163,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { // test route callback receiving an empty group id $result = $this->endpoint->get_group_settings( '' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); // test getting a group that does not exist $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/not-real' ) ); @@ -344,7 +344,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_get_setting_empty_setting_id() { $result = $this->endpoint->get_setting( 'test', '' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); } /** @@ -355,7 +355,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_get_setting_invalid_setting_id() { $result = $this->endpoint->get_setting( 'test', 'invalid' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); } /** @@ -379,7 +379,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $result = $controller->get_setting( 'test', 'woocommerce_shop_page_display' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); } /** diff --git a/unit-tests/Tests/Version3/functions.php b/unit-tests/Tests/Version3/functions.php index 8707d3ec54f..3f6f96404de 100644 --- a/unit-tests/Tests/Version3/functions.php +++ b/unit-tests/Tests/Version3/functions.php @@ -71,7 +71,7 @@ class WC_Tests_API_Functions extends WC_Unit_Test_Case { $expected_error_message = 'Error getting remote image http://somedomain.com/nonexistent-image.png. Error: Not found.'; $result = wc_rest_upload_image_from_url( 'http://somedomain.com/nonexistent-image.png' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); $this->assertEquals( $expected_error_message, $result->get_error_message() ); } @@ -85,14 +85,14 @@ class WC_Tests_API_Functions extends WC_Unit_Test_Case { $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-1.png' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); $this->assertEquals( $expected_error_message, $result->get_error_message() ); // unsupported mime type. $expected_error_message = 'Invalid image: Sorry, this file type is not permitted for security reasons.'; $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-2.png' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); $this->assertEquals( $expected_error_message, $result->get_error_message() ); } diff --git a/unit-tests/Tests/Version3/settings.php b/unit-tests/Tests/Version3/settings.php index e77b69ee888..48d5934af37 100644 --- a/unit-tests/Tests/Version3/settings.php +++ b/unit-tests/Tests/Version3/settings.php @@ -164,7 +164,7 @@ class Settings extends WC_REST_Unit_Test_Case { // test route callback receiving an empty group id $result = $this->endpoint->get_group_settings( '' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); // test getting a group that does not exist $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/not-real' ) ); @@ -345,7 +345,7 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_get_setting_empty_setting_id() { $result = $this->endpoint->get_setting( 'test', '' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); } /** @@ -356,7 +356,7 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_get_setting_invalid_setting_id() { $result = $this->endpoint->get_setting( 'test', 'invalid' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); } /** @@ -380,7 +380,7 @@ class Settings extends WC_REST_Unit_Test_Case { $result = $controller->get_setting( 'test', 'woocommerce_shop_page_display' ); - $this->assertIsWPError( $result ); + $this->assertWPError( $result ); } /** From 7d8f8163b6646b5ef779c40fc597f43c30ae0f60 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 1 Aug 2019 16:52:52 +0100 Subject: [PATCH 193/440] filter empty objects from results before loop --- src/Controllers/Version3/class-wc-rest-crud-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version3/class-wc-rest-crud-controller.php b/src/Controllers/Version3/class-wc-rest-crud-controller.php index 76447c2e9fc..ec9eb34b793 100644 --- a/src/Controllers/Version3/class-wc-rest-crud-controller.php +++ b/src/Controllers/Version3/class-wc-rest-crud-controller.php @@ -337,7 +337,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { } return array( - 'objects' => array_map( array( $this, 'get_object' ), $result ), + 'objects' => array_filter( array_map( array( $this, 'get_object' ), $result ) ), 'total' => (int) $total_posts, 'pages' => (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ), ); From 8b7b919cca021b66f95bea384b863bc92477af16 Mon Sep 17 00:00:00 2001 From: Nikhil Chaudhary <54429476+nikhil-webkul@users.noreply.github.com> Date: Fri, 30 Aug 2019 11:40:06 +0530 Subject: [PATCH 194/440] Update class-wc-rest-system-status-v2-controller.php Added the total post count that is need on the Woocommerce System Status tab. --- .../class-wc-rest-system-status-v2-controller.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 22acc2e5aa4..00c9b413770 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -553,6 +553,15 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'type' => 'string', ), ), + 'post_type_counts' => array( + 'description' => __('Total post count.', 'woocommerce'), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), ), ); @@ -575,6 +584,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'settings' => $this->get_settings(), 'security' => $this->get_security_info(), 'pages' => $this->get_pages(), + 'post_type_counts' => $this->get_post_type_counts(), ); } From 3e4274acbe59283a3e11712ee265929ea98261ab Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 5 Dec 2019 22:22:19 -0300 Subject: [PATCH 195/440] Fixed coding standards --- ...class-wc-rest-system-status-v2-controller.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 00c9b413770..e103cd4c97c 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -554,14 +554,14 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'post_type_counts' => array( - 'description' => __('Total post count.', 'woocommerce'), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), + 'description' => __( 'Total post count.', 'woocommerce-rest-api' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), ), ); From ff7cd27886d8294a736fe900b9f244562a920155 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 5 Dec 2019 22:24:49 -0300 Subject: [PATCH 196/440] Fixed unit tests --- unit-tests/Tests/Version2/system-status.php | 2 +- unit-tests/Tests/Version3/system-status.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unit-tests/Tests/Version2/system-status.php b/unit-tests/Tests/Version2/system-status.php index dc66d1f2740..9359c260291 100644 --- a/unit-tests/Tests/Version2/system-status.php +++ b/unit-tests/Tests/Version2/system-status.php @@ -207,7 +207,7 @@ class WC_Tests_REST_System_Status_V2 extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 9, count( $properties ) ); + $this->assertEquals( 10, count( $properties ) ); $this->assertArrayHasKey( 'environment', $properties ); $this->assertArrayHasKey( 'database', $properties ); $this->assertArrayHasKey( 'active_plugins', $properties ); diff --git a/unit-tests/Tests/Version3/system-status.php b/unit-tests/Tests/Version3/system-status.php index 9b8a9e86345..d6afb7b79d5 100644 --- a/unit-tests/Tests/Version3/system-status.php +++ b/unit-tests/Tests/Version3/system-status.php @@ -210,7 +210,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 9, count( $properties ) ); + $this->assertEquals( 10, count( $properties ) ); $this->assertArrayHasKey( 'environment', $properties ); $this->assertArrayHasKey( 'database', $properties ); $this->assertArrayHasKey( 'active_plugins', $properties ); From 066719a585df396764e21e0cd82fe170f9ee21cf Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 5 Dec 2019 22:31:34 -0300 Subject: [PATCH 197/440] Fixed unit tests and updated sniffs --- .travis.yml | 1 - composer.json | 4 +- composer.lock | 273 +++++++++++++++++++++++++------------------------- 3 files changed, 138 insertions(+), 140 deletions(-) diff --git a/.travis.yml b/.travis.yml index 31fac7a6447..c907c8983a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,6 @@ before_script: - phpenv config-rm xdebug.ini - composer install - composer global require "phpunit/phpunit=4.8.*|6.5.*" - - composer require woocommerce/woocommerce-sniffs - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION script: diff --git a/composer.json b/composer.json index 4dad153c7dd..556ad45b570 100644 --- a/composer.json +++ b/composer.json @@ -7,11 +7,11 @@ "prefer-stable": true, "minimum-stability": "dev", "require": { - "automattic/jetpack-autoloader": "1.2.0" + "automattic/jetpack-autoloader": "^1.2.0" }, "require-dev": { "phpunit/phpunit": "6.5.14", - "woocommerce/woocommerce-sniffs": "0.0.6" + "woocommerce/woocommerce-sniffs": "0.0.9" }, "scripts": { "post-install-cmd": [ diff --git a/composer.lock b/composer.lock index 32e9fe5d083..8fbba808a1f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "751413f93c1471f67dbcdbc9dd05c134", + "content-hash": "2959ea86936fa65d0ea8f25e4f0e7fdb", "packages": [ { "name": "automattic/jetpack-autoloader", - "version": "v1.1.0", + "version": "v1.3.5", "source": { "type": "git", "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "cf08e893a481e71feec6e61164efff0eeee98ccd" + "reference": "efa1cec37282cf60efaf57724ae2532c7c21bf94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/cf08e893a481e71feec6e61164efff0eeee98ccd", - "reference": "cf08e893a481e71feec6e61164efff0eeee98ccd", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/efa1cec37282cf60efaf57724ae2532c7c21bf94", + "reference": "efa1cec37282cf60efaf57724ae2532c7c21bf94", "shasum": "" }, "require": { @@ -40,7 +40,7 @@ "GPL-2.0-or-later" ], "description": "Creates a custom autoloader for a plugin or theme.", - "time": "2019-06-17T13:03:00+00:00" + "time": "2019-11-25T12:37:57+00:00" } ], "packages-dev": [ @@ -112,16 +112,16 @@ }, { "name": "doctrine/instantiator", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "a2c590166b2133a4633738648b6b064edae0814a" + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", - "reference": "a2c590166b2133a4633738648b6b064edae0814a", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", "shasum": "" }, "require": { @@ -164,20 +164,20 @@ "constructor", "instantiate" ], - "time": "2019-03-17T17:37:11+00:00" + "time": "2019-10-21T16:45:58+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.9.1", + "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", "shasum": "" }, "require": { @@ -212,7 +212,7 @@ "object", "object graph" ], - "time": "2019-04-07T13:18:21+00:00" + "time": "2019-08-09T12:45:53+00:00" }, { "name": "phar-io/manifest", @@ -318,16 +318,16 @@ }, { "name": "phpcompatibility/php-compatibility", - "version": "9.1.1", + "version": "9.3.4", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c" + "reference": "1f37659196e4f3113ea506a7efba201c52303bf1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/2b63c5d284ab8857f7b1d5c240ddb507a6b2293c", - "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/1f37659196e4f3113ea506a7efba201c52303bf1", + "reference": "1f37659196e4f3113ea506a7efba201c52303bf1", "shasum": "" }, "require": { @@ -341,7 +341,7 @@ "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." }, "type": "phpcodesniffer-standard", @@ -350,10 +350,6 @@ "LGPL-3.0-or-later" ], "authors": [ - { - "name": "Contributors", - "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" - }, { "name": "Wim Godden", "homepage": "https://github.com/wimg", @@ -363,6 +359,10 @@ "name": "Juliette Reinders Folmer", "homepage": "https://github.com/jrfnl", "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" } ], "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", @@ -372,30 +372,32 @@ "phpcs", "standards" ], - "time": "2018-12-30T23:16:27+00:00" + "time": "2019-11-15T04:12:02+00:00" }, { "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.0.1", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "9160de79fcd683b5c99e9c4133728d91529753ea" + "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/9160de79fcd683b5c99e9c4133728d91529753ea", - "reference": "9160de79fcd683b5c99e9c4133728d91529753ea", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/b862bc32f7e860d0b164b199bd995e690b4b191c", + "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c", "shasum": "" }, "require": { "phpcompatibility/php-compatibility": "^9.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4" + "dealerdirect/phpcodesniffer-composer-installer": "^0.5", + "paragonie/random_compat": "dev-master", + "paragonie/sodium_compat": "dev-master" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." }, "type": "phpcodesniffer-standard", @@ -422,20 +424,20 @@ "polyfill", "standards" ], - "time": "2018-12-16T19:10:44+00:00" + "time": "2019-11-04T15:17:54+00:00" }, { "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd" + "reference": "41bef18ba688af638b7310666db28e1ea9158b2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/cb303f0067cd5b366a41d4fb0e254fb40ff02efd", - "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/41bef18ba688af638b7310666db28e1ea9158b2f", + "reference": "41bef18ba688af638b7310666db28e1ea9158b2f", "shasum": "" }, "require": { @@ -443,10 +445,10 @@ "phpcompatibility/phpcompatibility-paragonie": "^1.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3" + "dealerdirect/phpcodesniffer-composer-installer": "^0.5" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." }, "type": "phpcodesniffer-standard", @@ -472,39 +474,37 @@ "standards", "wordpress" ], - "time": "2018-10-07T18:31:37+00:00" + "time": "2019-08-28T14:22:28+00:00" }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "~6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -526,30 +526,30 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2018-08-07T13:53:10+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.1", + "version": "4.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", "shasum": "" }, "require": { "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", + "doctrine/instantiator": "^1.0.5", "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4" }, @@ -577,41 +577,40 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-04-30T17:48:53+00:00" + "time": "2019-09-12T14:27:41+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -624,26 +623,27 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpspec/prophecy", - "version": "1.8.1", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76" + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76", - "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, @@ -687,7 +687,7 @@ "spy", "stub" ], - "time": "2019-06-13T12:50:23+00:00" + "time": "2019-10-03T11:07:50+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1295,16 +1295,16 @@ }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", "shasum": "" }, "require": { @@ -1331,6 +1331,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1339,17 +1343,13 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -1358,7 +1358,7 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2019-09-14T09:02:43+00:00" }, { "name": "sebastian/global-state", @@ -1643,16 +1643,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.4.2", + "version": "3.5.3", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8" + "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", - "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", + "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", "shasum": "" }, "require": { @@ -1690,20 +1690,20 @@ "phpcs", "standards" ], - "time": "2019-04-10T23:49:02+00:00" + "time": "2019-12-04T04:46:47+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.11.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "82ebae02209c21113908c229e9883c419720738a" + "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", - "reference": "82ebae02209c21113908c229e9883c419720738a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", + "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", "shasum": "" }, "require": { @@ -1715,7 +1715,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -1731,13 +1731,13 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - }, { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", @@ -1748,7 +1748,7 @@ "polyfill", "portable" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "theseer/tokenizer", @@ -1792,32 +1792,29 @@ }, { "name": "webmozart/assert", - "version": "1.4.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", + "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", "shasum": "" }, "require": { "php": "^5.3.3 || ^7.0", "symfony/polyfill-ctype": "^1.8" }, + "conflict": { + "vimeo/psalm": "<3.6.0" + }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -1839,27 +1836,27 @@ "check", "validate" ], - "time": "2018-12-25T11:19:39+00:00" + "time": "2019-11-24T13:36:37+00:00" }, { "name": "woocommerce/woocommerce-sniffs", - "version": "0.0.6", + "version": "0.0.9", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-sniffs.git", - "reference": "a3032bdddd60c71d1330f591e1a9128e115f81ee" + "reference": "7677a84e9a355fe1e088f704090be891e7a6d427" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/a3032bdddd60c71d1330f591e1a9128e115f81ee", - "reference": "a3032bdddd60c71d1330f591e1a9128e115f81ee", + "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/7677a84e9a355fe1e088f704090be891e7a6d427", + "reference": "7677a84e9a355fe1e088f704090be891e7a6d427", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", + "dealerdirect/phpcodesniffer-composer-installer": "0.5.0", "php": ">=7.0", - "phpcompatibility/phpcompatibility-wp": "2.0.0", - "wp-coding-standards/wpcs": "^1.2" + "phpcompatibility/phpcompatibility-wp": "2.1.0", + "wp-coding-standards/wpcs": "2.2.0" }, "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", @@ -1879,31 +1876,33 @@ "woocommerce", "wordpress" ], - "time": "2019-03-11T15:30:23+00:00" + "time": "2019-11-11T15:48:34+00:00" }, { "name": "wp-coding-standards/wpcs", - "version": "1.2.1", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git", - "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c" + "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", + "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c", - "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c", + "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/f90e8692ce97b693633db7ab20bfa78d930f536a", + "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a", "shasum": "" }, "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" + "php": ">=5.4", + "squizlabs/php_codesniffer": "^3.3.1" }, "require-dev": { - "phpcompatibility/php-compatibility": "^9.0" + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", + "phpcompatibility/php-compatibility": "^9.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." }, "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", @@ -1913,7 +1912,7 @@ "authors": [ { "name": "Contributors", - "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors" + "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" } ], "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", @@ -1922,7 +1921,7 @@ "standards", "wordpress" ], - "time": "2018-12-18T09:43:51+00:00" + "time": "2019-11-11T12:34:03+00:00" } ], "aliases": [], From 8d2eb27637184add937e5bbd6b13b486b70da355 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 5 Dec 2019 22:44:20 -0300 Subject: [PATCH 198/440] Version 1.0.4 --- src/Package.php | 2 +- woocommerce-rest-api.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Package.php b/src/Package.php index 16b036e13b6..27df27b0ada 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.2'; + const VERSION = '1.0.4'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 041ba9d66bc..a59ed03dcc7 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.2 + * Version: 1.0.4 * Requires PHP: 5.6 * License: GPLv3 * From 1d5e1715d6780bea7bdb7dc343012661a40038d3 Mon Sep 17 00:00:00 2001 From: Csaba Maulis Date: Thu, 12 Dec 2019 09:26:18 +0800 Subject: [PATCH 199/440] Fix Products Controller images property type --- .../Version1/class-wc-rest-products-v1-controller.php | 2 +- src/Controllers/Version3/class-wc-rest-products-controller.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controllers/Version1/class-wc-rest-products-v1-controller.php b/src/Controllers/Version1/class-wc-rest-products-v1-controller.php index 73cd14ea769..bf8629b027d 100644 --- a/src/Controllers/Version1/class-wc-rest-products-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-products-v1-controller.php @@ -2146,7 +2146,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), 'images' => array( 'description' => __( 'List of images.', 'woocommerce-rest-api' ), - 'type' => 'object', + 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', diff --git a/src/Controllers/Version3/class-wc-rest-products-controller.php b/src/Controllers/Version3/class-wc-rest-products-controller.php index 5dcc4cb5e9a..a6401bf6d91 100644 --- a/src/Controllers/Version3/class-wc-rest-products-controller.php +++ b/src/Controllers/Version3/class-wc-rest-products-controller.php @@ -1122,7 +1122,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), 'images' => array( 'description' => __( 'List of images.', 'woocommerce-rest-api' ), - 'type' => 'object', + 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', From 28e046c33e635f5b317b24682871d5fd44343e07 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 17 Dec 2019 11:01:56 -0300 Subject: [PATCH 200/440] Make product_id non mandatory while updating a line_item in orders endpoint --- .../Version2/class-wc-rest-orders-v2-controller.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php index b073f04c5a1..8b7811c9f6f 100644 --- a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -374,7 +374,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( isset( $request['customer'] ) ) { if ( ! empty( $args['meta_query'] ) ) { - $args['meta_query'] = array(); // WPCS: slow query ok. + $args['meta_query'] = array(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query } $args['meta_query'][] = array( @@ -590,16 +590,19 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { * Gets the product ID from the SKU or posted ID. * * @throws WC_REST_Exception When SKU or ID is not valid. - * @param array $posted Request data. + * @param array $posted Request data. + * @param WC_Product|bool $product Product data. * @return int */ - protected function get_product_id( $posted ) { + protected function get_product_id( $posted, $product ) { if ( ! empty( $posted['sku'] ) ) { $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['product_id']; } elseif ( ! empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['variation_id']; + } elseif ( $product && 0 < $product->get_id() ) { + return $product->get_id(); } else { throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); } @@ -660,7 +663,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { */ protected function prepare_line_items( $posted, $action = 'create', $item = null ) { $item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - $product = wc_get_product( $this->get_product_id( $posted ) ); + $product = wc_get_product( $this->get_product_id( $posted, $item->get_product() ) ); if ( $product !== $item->get_product() ) { $item->set_product( $product ); From 48fb4433acedcaf8db244cdb8defd6f15b85244e Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 18 Dec 2019 13:25:01 -0300 Subject: [PATCH 201/440] Allow edit line items without passing an product ID again --- .../class-wc-rest-orders-v1-controller.php | 14 ++++++++------ .../class-wc-rest-orders-v2-controller.php | 12 ++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php b/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php index 34570cda3d7..7ea86c16542 100644 --- a/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php @@ -605,18 +605,20 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { /** * Gets the product ID from the SKU or posted ID. * - * @param array $posted Request data - * + * @throws WC_REST_Exception When SKU or ID is not valid. + * @param array $posted Request data. + * @param string $action 'create' to add line item or 'update' to update it. * @return int - * @throws WC_REST_Exception */ - protected function get_product_id( $posted ) { + protected function get_product_id( $posted, $action = 'create' ) { if ( ! empty( $posted['sku'] ) ) { $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['product_id']; } elseif ( ! empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['variation_id']; + } elseif ( 'update' === $action ) { + $product_id = 0; } else { throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); } @@ -658,9 +660,9 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { */ protected function prepare_line_items( $posted, $action = 'create' ) { $item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ); - $product = wc_get_product( $this->get_product_id( $posted ) ); + $product = wc_get_product( $this->get_product_id( $posted, $item->get_product() ) ); - if ( $product !== $item->get_product() ) { + if ( $product && $product !== $item->get_product() ) { $item->set_product( $product ); if ( 'create' === $action ) { diff --git a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php index 8b7811c9f6f..66b19fbe528 100644 --- a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -591,18 +591,18 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { * * @throws WC_REST_Exception When SKU or ID is not valid. * @param array $posted Request data. - * @param WC_Product|bool $product Product data. + * @param string $action 'create' to add line item or 'update' to update it. * @return int */ - protected function get_product_id( $posted, $product ) { + protected function get_product_id( $posted, $action = 'create' ) { if ( ! empty( $posted['sku'] ) ) { $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['product_id']; } elseif ( ! empty( $posted['variation_id'] ) ) { $product_id = (int) $posted['variation_id']; - } elseif ( $product && 0 < $product->get_id() ) { - return $product->get_id(); + } elseif ( 'update' === $action ) { + $product_id = 0; } else { throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); } @@ -663,9 +663,9 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { */ protected function prepare_line_items( $posted, $action = 'create', $item = null ) { $item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - $product = wc_get_product( $this->get_product_id( $posted, $item->get_product() ) ); + $product = wc_get_product( $this->get_product_id( $posted, $action ) ); - if ( $product !== $item->get_product() ) { + if ( $product && $product !== $item->get_product() ) { $item->set_product( $product ); if ( 'create' === $action ) { From 218f1b1edb408916da8d48a183cf0fc1748edbdf Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 18 Dec 2019 13:26:28 -0300 Subject: [PATCH 202/440] Fixed prepare_line_items for v1 --- src/Controllers/Version1/class-wc-rest-orders-v1-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php b/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php index 7ea86c16542..502bc2eeb29 100644 --- a/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php @@ -660,7 +660,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { */ protected function prepare_line_items( $posted, $action = 'create' ) { $item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ); - $product = wc_get_product( $this->get_product_id( $posted, $item->get_product() ) ); + $product = wc_get_product( $this->get_product_id( $posted, $action ) ); if ( $product && $product !== $item->get_product() ) { $item->set_product( $product ); From b0da8ca633a223ad1deda107808c723a2b14a59b Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 18 Dec 2019 14:36:52 -0300 Subject: [PATCH 203/440] Included unit tests --- unit-tests/Tests/Version2/orders.php | 73 ++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/unit-tests/Tests/Version2/orders.php b/unit-tests/Tests/Version2/orders.php index 9a1d5422d15..7846b6dd1da 100644 --- a/unit-tests/Tests/Version2/orders.php +++ b/unit-tests/Tests/Version2/orders.php @@ -339,8 +339,32 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { ), ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Tests create an order with an invalid product. + * + * @since 3.9.0 + */ + public function test_create_order_with_invalid_product() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); + $request->set_body_params( + array( + 'line_items' => array( + array( + 'quantity' => 2, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); $data = $response->get_data(); + $this->assertEquals( 'woocommerce_rest_required_product_reference', $data['code'] ); $this->assertEquals( 400, $response->get_status() ); } @@ -411,6 +435,55 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { $this->assertTrue( empty( $data['fee_lines'] ) ); } + /** + * Tests updating an order after deleting a product. + * + * @since 3.9.0 + */ + public function test_update_order_after_delete_product() { + wp_set_current_user( $this->user ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); + $product->delete( true ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); + $line_items = $order->get_items( 'line_item' ); + $item = current( $line_items ); + + $request->set_body_params( + array( + 'line_items' => array( + array( + 'id' => $item->get_id(), + 'quantity' => 10, + ), + ), + ) + ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $expected = array( + 'id' => 1, + 'name' => 'Dummy Product', + 'product_id' => 0, + 'variation_id' => 0, + 'quantity' => 10, + 'tax_class' => '', + 'subtotal' => '40.00', + 'subtotal_tax' => '0.00', + 'total' => '40.00', + 'total_tax' => '0.00', + 'taxes' => array(), + 'meta_data' => array(), + 'sku' => null, + 'price' => 4, + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $expected, $data['line_items'][0] ); + } + /** * Tests updating an order and adding a coupon. * From 3e0e9fee77b651e3d9d3f0e915ae87fb38e4c993 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 18 Dec 2019 14:42:03 -0300 Subject: [PATCH 204/440] Included tests for v3 --- unit-tests/Tests/Version3/orders.php | 73 ++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/unit-tests/Tests/Version3/orders.php b/unit-tests/Tests/Version3/orders.php index d537f68eb55..976059d40b4 100644 --- a/unit-tests/Tests/Version3/orders.php +++ b/unit-tests/Tests/Version3/orders.php @@ -343,8 +343,32 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { ), ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Tests create an order with an invalid product. + * + * @since 3.9.0 + */ + public function test_create_order_with_invalid_product() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); + $request->set_body_params( + array( + 'line_items' => array( + array( + 'quantity' => 2, + ), + ), + ) + ); + $response = $this->server->dispatch( $request ); $data = $response->get_data(); + $this->assertEquals( 'woocommerce_rest_required_product_reference', $data['code'] ); $this->assertEquals( 400, $response->get_status() ); } @@ -415,6 +439,55 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { $this->assertTrue( empty( $data['fee_lines'] ) ); } + /** + * Tests updating an order after deleting a product. + * + * @since 3.9.0 + */ + public function test_update_order_after_delete_product() { + wp_set_current_user( $this->user ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); + $product->delete( true ); + + $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); + $line_items = $order->get_items( 'line_item' ); + $item = current( $line_items ); + + $request->set_body_params( + array( + 'line_items' => array( + array( + 'id' => $item->get_id(), + 'quantity' => 10, + ), + ), + ) + ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $expected = array( + 'id' => 1, + 'name' => 'Dummy Product', + 'product_id' => 0, + 'variation_id' => 0, + 'quantity' => 10, + 'tax_class' => '', + 'subtotal' => '40.00', + 'subtotal_tax' => '0.00', + 'total' => '40.00', + 'total_tax' => '0.00', + 'taxes' => array(), + 'meta_data' => array(), + 'sku' => null, + 'price' => 4, + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $expected, $data['line_items'][0] ); + } + /** * Tests updating an order and adding a coupon. * From 5a509591e749fa81389830687711bb36acc4bb3d Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 18 Dec 2019 15:43:23 -0300 Subject: [PATCH 205/440] Fixed unit tests --- unit-tests/Tests/Version2/orders.php | 2 +- unit-tests/Tests/Version3/orders.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unit-tests/Tests/Version2/orders.php b/unit-tests/Tests/Version2/orders.php index 7846b6dd1da..1837fc252d8 100644 --- a/unit-tests/Tests/Version2/orders.php +++ b/unit-tests/Tests/Version2/orders.php @@ -464,7 +464,7 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $expected = array( - 'id' => 1, + 'id' => $item->get_id(), 'name' => 'Dummy Product', 'product_id' => 0, 'variation_id' => 0, diff --git a/unit-tests/Tests/Version3/orders.php b/unit-tests/Tests/Version3/orders.php index 976059d40b4..e0419e643df 100644 --- a/unit-tests/Tests/Version3/orders.php +++ b/unit-tests/Tests/Version3/orders.php @@ -468,7 +468,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $expected = array( - 'id' => 1, + 'id' => $item->get_id(), 'name' => 'Dummy Product', 'product_id' => 0, 'variation_id' => 0, From 0704f6d02310ff21dbc0319ba3fb59bf9665b3cd Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 18 Dec 2019 13:38:10 -0800 Subject: [PATCH 206/440] Added support for filtering products and variations by their menu_order --- .../class-wc-rest-products-v2-controller.php | 2 ++ .../Tests/Version2/product-variations.php | 18 ++++++++++++++++++ .../Tests/Version3/product-variations.php | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php index 97c4ec0a716..d6942fc2826 100644 --- a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php @@ -2104,6 +2104,8 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { public function get_collection_params() { $params = parent::get_collection_params(); + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'menu_order' ) ); + $params['slug'] = array( 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), 'type' => 'string', diff --git a/unit-tests/Tests/Version2/product-variations.php b/unit-tests/Tests/Version2/product-variations.php index c936bd3e69d..9c7efae4451 100644 --- a/unit-tests/Tests/Version2/product-variations.php +++ b/unit-tests/Tests/Version2/product-variations.php @@ -49,6 +49,24 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); } + /** + * Test getting variations with an orderby clause. + * + * @since 3.9.0 + */ + public function test_get_variations_with_orderby() { + wp_set_current_user( $this->user ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $request = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ); + $request->set_query_params( array( 'orderby' => 'menu_order' ) ); + $response = $this->server->dispatch( $request ); + $variations = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $variations ) ); + $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]['sku'] ); + $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); + } + /** * Test getting variations without permission. * diff --git a/unit-tests/Tests/Version3/product-variations.php b/unit-tests/Tests/Version3/product-variations.php index 2539995dde0..5c1c313cf20 100644 --- a/unit-tests/Tests/Version3/product-variations.php +++ b/unit-tests/Tests/Version3/product-variations.php @@ -49,6 +49,24 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); } + /** + * Test getting variations with an orderby clause. + * + * @since 3.9.0 + */ + public function test_get_variations_with_orderby() { + wp_set_current_user( $this->user ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); + $request = new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ); + $request->set_query_params( array( 'orderby' => 'menu_order' ) ); + $response = $this->server->dispatch( $request ); + $variations = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $variations ) ); + $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]['sku'] ); + $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); + } + /** * Test getting variations without permission. * From 3be425631faefa61ab8b81011ae8a422b9bfca35 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 18 Dec 2019 19:20:59 -0300 Subject: [PATCH 207/440] Version 1.0.5 --- src/Package.php | 2 +- woocommerce-rest-api.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Package.php b/src/Package.php index 27df27b0ada..1b3bba9a289 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.4'; + const VERSION = '1.0.5'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index a59ed03dcc7..383528d51b9 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.4 + * Version: 1.0.5 * Requires PHP: 5.6 * License: GPLv3 * From d139b35344d0b71b50c3789ac36b4fb223d38ff5 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 19 Dec 2019 13:54:01 -0300 Subject: [PATCH 208/440] Test the correct orders endpoint --- unit-tests/Tests/Version3/orders.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unit-tests/Tests/Version3/orders.php b/unit-tests/Tests/Version3/orders.php index e0419e643df..d778ba0a39d 100644 --- a/unit-tests/Tests/Version3/orders.php +++ b/unit-tests/Tests/Version3/orders.php @@ -355,7 +355,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { public function test_create_order_with_invalid_product() { wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); + $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); $request->set_body_params( array( 'line_items' => array( @@ -450,7 +450,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); $product->delete( true ); - $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); + $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); $line_items = $order->get_items( 'line_item' ); $item = current( $line_items ); From ae9948edef873c46e9b67685dc54c5a9a8f987d7 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 19 Dec 2019 13:18:23 -0300 Subject: [PATCH 209/440] Allow set instance_id for Order's shipping_lines --- src/Controllers/Version2/class-wc-rest-orders-v2-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php index 66b19fbe528..a9422aec274 100644 --- a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -700,7 +700,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { } } - $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); + $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total', 'instance_id' ), $posted ); $this->maybe_set_item_meta_data( $item, $posted ); return $item; From b8763fd3e43de9139e5342d3f6760522f2db0b3a Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 15 Jan 2020 20:09:00 -0300 Subject: [PATCH 210/440] Added unit tests for instance_id --- unit-tests/Tests/Version2/orders.php | 15 ++++++++++++++- unit-tests/Tests/Version3/orders.php | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/unit-tests/Tests/Version2/orders.php b/unit-tests/Tests/Version2/orders.php index 1837fc252d8..e80fbab5fb8 100644 --- a/unit-tests/Tests/Version2/orders.php +++ b/unit-tests/Tests/Version2/orders.php @@ -175,7 +175,8 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { array( 'method_id' => 'flat_rate', 'method_title' => 'Flat rate', - 'total' => '10', + 'total' => '10.00', + 'instance_id' => '1', ), ), ) @@ -208,6 +209,18 @@ class WC_Tests_API_Orders_V2 extends WC_REST_Unit_Test_Case { $this->assertEquals( $order->get_shipping_country(), $data['shipping']['country'] ); $this->assertEquals( 1, count( $data['line_items'] ) ); $this->assertEquals( 1, count( $data['shipping_lines'] ) ); + $shipping = current( $order->get_items( 'shipping' ) ); + $expected = array( + 'id' => $shipping->get_id(), + 'method_title' => $shipping->get_method_title(), + 'method_id' => $shipping->get_method_id(), + 'instance_id' => $shipping->get_instance_id(), + 'total' => wc_format_decimal( $shipping->get_total(), '' ), + 'total_tax' => wc_format_decimal( $shipping->get_total_tax(), '' ), + 'taxes' => array(), + 'meta_data' => $shipping->get_meta_data(), + ); + $this->assertEquals( $expected, $data['shipping_lines'][0] ); } /** diff --git a/unit-tests/Tests/Version3/orders.php b/unit-tests/Tests/Version3/orders.php index d778ba0a39d..eb7b057c9e6 100644 --- a/unit-tests/Tests/Version3/orders.php +++ b/unit-tests/Tests/Version3/orders.php @@ -179,7 +179,8 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { array( 'method_id' => 'flat_rate', 'method_title' => 'Flat rate', - 'total' => '10', + 'total' => '10.00', + 'instance_id' => '1', ), ), ) @@ -212,6 +213,18 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { $this->assertEquals( $order->get_shipping_country(), $data['shipping']['country'] ); $this->assertEquals( 1, count( $data['line_items'] ) ); $this->assertEquals( 1, count( $data['shipping_lines'] ) ); + $shipping = current( $order->get_items( 'shipping' ) ); + $expected = array( + 'id' => $shipping->get_id(), + 'method_title' => $shipping->get_method_title(), + 'method_id' => $shipping->get_method_id(), + 'instance_id' => $shipping->get_instance_id(), + 'total' => wc_format_decimal( $shipping->get_total(), '' ), + 'total_tax' => wc_format_decimal( $shipping->get_total_tax(), '' ), + 'taxes' => array(), + 'meta_data' => $shipping->get_meta_data(), + ); + $this->assertEquals( $expected, $data['shipping_lines'][0] ); } /** From 361326d7f0020489e2ba4e6c3bf353c977ca7119 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 19 Dec 2019 12:29:23 -0300 Subject: [PATCH 211/440] Fixed type numeric type on products and variations schema --- ...class-wc-rest-product-variations-controller.php | 14 +++++++------- .../Version3/class-wc-rest-products-controller.php | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Controllers/Version3/class-wc-rest-product-variations-controller.php b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php index 0477e818df9..8aaa1c08e37 100644 --- a/src/Controllers/Version3/class-wc-rest-product-variations-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php @@ -441,18 +441,18 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ), 'price' => array( 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( @@ -595,7 +595,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V 'weight' => array( /* translators: %s: weight unit */ 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( @@ -606,19 +606,19 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V 'length' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), ), diff --git a/src/Controllers/Version3/class-wc-rest-products-controller.php b/src/Controllers/Version3/class-wc-rest-products-controller.php index a6401bf6d91..2de987aaa3b 100644 --- a/src/Controllers/Version3/class-wc-rest-products-controller.php +++ b/src/Controllers/Version3/class-wc-rest-products-controller.php @@ -786,18 +786,18 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), 'price' => array( 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( @@ -962,7 +962,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'weight' => array( /* translators: %s: weight unit */ 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( @@ -973,19 +973,19 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'length' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', + 'type' => 'number', 'context' => array( 'view', 'edit' ), ), ), From b4125269a381b785fe87cfe8072bd1fcda51bb91 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 7 Jan 2020 15:50:35 -0300 Subject: [PATCH 212/440] Updated WC_REST_Controller::get_fields_for_response() --- .../Version3/class-wc-rest-controller.php | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/Controllers/Version3/class-wc-rest-controller.php b/src/Controllers/Version3/class-wc-rest-controller.php index 57c4040e433..5ee0bc41122 100644 --- a/src/Controllers/Version3/class-wc-rest-controller.php +++ b/src/Controllers/Version3/class-wc-rest-controller.php @@ -434,30 +434,43 @@ abstract class WC_REST_Controller extends WP_REST_Controller { /** * Gets an array of fields to be included on the response. + * * Included fields are based on item schema and `_fields=` request argument. - * Introduced to support WordPress 4.9.6 changes. + * Updated from WordPress 5.3, included into this class to support old versions. * * @since 3.5.0 * @param WP_REST_Request $request Full details about the request. * @return array Fields to be included in the response. */ public function get_fields_for_response( $request ) { - $schema = $this->get_item_schema(); - $fields = isset( $schema['properties'] ) ? array_keys( $schema['properties'] ) : array(); + $schema = $this->get_item_schema(); + $properties = isset( $schema['properties'] ) ? $schema['properties'] : array(); $additional_fields = $this->get_additional_fields(); foreach ( $additional_fields as $field_name => $field_options ) { // For back-compat, include any field with an empty schema // because it won't be present in $this->get_item_schema(). if ( is_null( $field_options['schema'] ) ) { - $fields[] = $field_name; + $properties[ $field_name ] = $field_options; } } + // Exclude fields that specify a different context than the request context. + $context = $request['context']; + if ( $context ) { + foreach ( $properties as $name => $options ) { + if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) { + unset( $properties[ $name ] ); + } + } + } + + $fields = array_keys( $properties ); + if ( ! isset( $request['_fields'] ) ) { return $fields; } - $requested_fields = is_array( $request['_fields'] ) ? $request['_fields'] : preg_split( '/[\s,]+/', $request['_fields'] ); + $requested_fields = wp_parse_list( $request['_fields'] ); if ( 0 === count( $requested_fields ) ) { return $fields; } @@ -467,6 +480,24 @@ abstract class WC_REST_Controller extends WP_REST_Controller { if ( in_array( 'id', $fields, true ) ) { $requested_fields[] = 'id'; } - return array_intersect( $fields, $requested_fields ); + // Return the list of all requested fields which appear in the schema. + return array_reduce( + $requested_fields, + function( $response_fields, $field ) use ( $fields ) { + if ( in_array( $field, $fields, true ) ) { + $response_fields[] = $field; + return $response_fields; + } + // Check for nested fields if $field is not a direct match. + $nested_fields = explode( '.', $field ); + // A nested field is included so long as its top-level property is + // present in the schema. + if ( in_array( $nested_fields[0], $fields, true ) ) { + $response_fields[] = $field; + } + return $response_fields; + }, + array() + ); } } From 4342ae2b6fe1d102e57659c54e71a7f6c48d6d03 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 7 Jan 2020 15:51:16 -0300 Subject: [PATCH 213/440] Prevent wp_remote_post or wp_remote_get to trigger when not necessary --- ...ss-wc-rest-system-status-v2-controller.php | 88 +++++++++++-------- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index e103cd4c97c..d439c5d500b 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -72,16 +72,11 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { */ public function get_items( $request ) { $schema = $this->get_item_schema(); - $mappings = $this->get_item_mappings(); + $fields = $this->get_fields_for_response( $request ); + $mappings = $this->get_item_mappings( $fields ); $response = array(); foreach ( $mappings as $section => $values ) { - foreach ( $values as $key => $value ) { - if ( isset( $schema['properties'][ $section ]['properties'][ $key ]['type'] ) ) { - settype( $values[ $key ], $schema['properties'][ $section ]['properties'][ $key ]['type'] ); - } - } - settype( $values, $schema['properties'][ $section ]['type'] ); $response[ $section ] = $values; } @@ -571,11 +566,12 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { /** * Return an array of sections and the data associated with each. * + * @param array $fields List of fields to be included on the response. * @return array */ - public function get_item_mappings() { + public function get_item_mappings( $fields ) { return array( - 'environment' => $this->get_environment_info(), + 'environment' => $this->get_environment_info( $fields ), 'database' => $this->get_database_info(), 'active_plugins' => $this->get_active_plugins(), 'inactive_plugins' => $this->get_inactive_plugins(), @@ -592,11 +588,23 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { * Get array of environment information. Includes thing like software * versions, and various server settings. * + * @param array $fields List of fields to be included on the response. * @return array */ - public function get_environment_info() { + public function get_environment_info( $fields ) { global $wpdb; + $exclude = array(); + foreach ( $fields as $field ) { + $values = explode( '.', $field ); + + if ( 'environment' !== $values[0] || empty( $values[1] ) ) { + continue; + } + + $exclude[] = $values[1]; + } + // Figure out cURL version, if installed. $curl_version = ''; if ( function_exists( 'curl_version' ) ) { @@ -613,40 +621,48 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { } // Test POST requests. - $post_response_code = get_transient( 'woocommerce_test_remote_post' ); + $post_response_successful = null; + $post_response_code = null; + if ( empty( $exclude ) || 0 < count( array_intersect( array( 'remote_post_successful', 'remote_post_response' ), $exclude ) ) ) { + $post_response_code = get_transient( 'woocommerce_test_remote_post' ); - if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { - $response = wp_safe_remote_post( - 'https://www.paypal.com/cgi-bin/webscr', - array( - 'timeout' => 10, - 'user-agent' => 'WooCommerce/' . WC()->version, - 'httpversion' => '1.1', - 'body' => array( - 'cmd' => '_notify-validate', - ), - ) - ); - if ( ! is_wp_error( $response ) ) { - $post_response_code = $response['response']['code']; + if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { + $response = wp_safe_remote_post( + 'https://www.paypal.com/cgi-bin/webscr', + array( + 'timeout' => 10, + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', + 'body' => array( + 'cmd' => '_notify-validate', + ), + ) + ); + if ( ! is_wp_error( $response ) ) { + $post_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); } - set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); - } - $post_response_successful = ! is_wp_error( $post_response_code ) && $post_response_code >= 200 && $post_response_code < 300; + $post_response_successful = ! is_wp_error( $post_response_code ) && $post_response_code >= 200 && $post_response_code < 300; + } // Test GET requests. - $get_response_code = get_transient( 'woocommerce_test_remote_get' ); + $get_response_successful = null; + $get_response_code = null; + if ( empty( $exclude ) || 0 < count( array_intersect( array( 'remote_get_successful', 'remote_get_response' ), $exclude ) ) ) { + $get_response_code = get_transient( 'woocommerce_test_remote_get' ); - if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { - $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); - if ( ! is_wp_error( $response ) ) { - $get_response_code = $response['response']['code']; + if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { + $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); + if ( ! is_wp_error( $response ) ) { + $get_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); } - set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); - } - $get_response_successful = ! is_wp_error( $get_response_code ) && $get_response_code >= 200 && $get_response_code < 300; + $get_response_successful = ! is_wp_error( $get_response_code ) && $get_response_code >= 200 && $get_response_code < 300; + } $database_version = wc_get_server_database_version(); From bc0acf60b8c130dd5c9821517ecc84536140fef8 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 7 Jan 2020 16:09:59 -0300 Subject: [PATCH 214/440] Improved logic to only try remote requests if necessary --- ...ss-wc-rest-system-status-v2-controller.php | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index d439c5d500b..b30ce69e169 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -594,15 +594,22 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { public function get_environment_info( $fields ) { global $wpdb; - $exclude = array(); - foreach ( $fields as $field ) { - $values = explode( '.', $field ); + $enable_remote_post = false; + $enable_remote_get = false; + if ( in_array( 'environment', $fields, true ) ) { + $exclude = array(); + foreach ( $fields as $field ) { + $values = explode( '.', $field ); - if ( 'environment' !== $values[0] || empty( $values[1] ) ) { - continue; + if ( 'environment' !== $values[0] || empty( $values[1] ) ) { + continue; + } + + $exclude[] = $values[1]; } - $exclude[] = $values[1]; + $enable_remote_post = 0 <= count( array_intersect( array( 'remote_post_successful', 'remote_post_response' ), $exclude ) ); + $enable_remote_get = 0 <= count( array_intersect( array( 'remote_get_successful', 'remote_get_response' ), $exclude ) ); } // Figure out cURL version, if installed. @@ -623,7 +630,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { // Test POST requests. $post_response_successful = null; $post_response_code = null; - if ( empty( $exclude ) || 0 < count( array_intersect( array( 'remote_post_successful', 'remote_post_response' ), $exclude ) ) ) { + if ( $enable_remote_post ) { $post_response_code = get_transient( 'woocommerce_test_remote_post' ); if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { @@ -650,7 +657,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { // Test GET requests. $get_response_successful = null; $get_response_code = null; - if ( empty( $exclude ) || 0 < count( array_intersect( array( 'remote_get_successful', 'remote_get_response' ), $exclude ) ) ) { + if ( $enable_remote_get ) { $get_response_code = get_transient( 'woocommerce_test_remote_get' ); if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { From 0cfbc27a27a387090b79fbc8ff3073f15bb11935 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 8 Jan 2020 15:06:53 -0300 Subject: [PATCH 215/440] Simplify and speedup WC_Tests_REST_System_Status tests This implements two changes to WC_Tests_REST_System_Status test class: - It simplifies the tests by setting the user in the setUp method instead of in each test. - Improves the performance of the tests by creating a new admin user only once when the class is instantiated instead of once for every single test that is executed. --- unit-tests/Tests/Version3/system-status.php | 45 +++++++++++---------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/unit-tests/Tests/Version3/system-status.php b/unit-tests/Tests/Version3/system-status.php index d6afb7b79d5..ead97dd1c77 100644 --- a/unit-tests/Tests/Version3/system-status.php +++ b/unit-tests/Tests/Version3/system-status.php @@ -14,16 +14,34 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { /** - * Setup our test server. + * User variable. + * + * @var WP_User */ - public function setUp() { - parent::setUp(); - $this->endpoint = new WC_REST_System_Status_Controller(); - $this->user = $this->factory->user->create( + protected static $user; + + /** + * Setup once before running tests. + * + * @param object $factory Factory object. + */ + public static function wpSetUpBeforeClass( $factory ) { + self::$user = $factory->user->create( array( 'role' => 'administrator', ) ); + } + + /** + * Setup our test server. + */ + public function setUp() { + parent::setUp(); + + wp_set_current_user( self::$user ); + + $this->endpoint = new WC_REST_System_Status_Controller(); // Callback used by WP_HTTP_TestCase to decide whether to perform HTTP requests or to provide a mocked response. $this->http_responder = array( $this, 'mock_http_responses' ); @@ -57,7 +75,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_returns_root_properties() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); $data = $response->get_data(); @@ -76,7 +93,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_environment() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); $data = $response->get_data(); $environment = (array) $data['environment']; @@ -97,7 +113,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { */ public function test_get_system_status_info_database() { global $wpdb; - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); $data = $response->get_data(); $database = (array) $data['database']; @@ -115,8 +130,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_active_plugins() { - wp_set_current_user( $this->user ); - $actual_plugins = array( 'hello.php' ); update_option( 'active_plugins', $actual_plugins ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); @@ -135,7 +148,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_theme() { - wp_set_current_user( $this->user ); $active_theme = wp_get_theme(); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); @@ -152,8 +164,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_settings() { - wp_set_current_user( $this->user ); - $term_response = array(); $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); foreach ( $terms as $term ) { @@ -176,8 +186,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_security() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); $data = $response->get_data(); $settings = (array) $data['security']; @@ -193,7 +201,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_status_info_pages() { - wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); $data = $response->get_data(); $pages = $data['pages']; @@ -226,8 +233,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_tools() { - wp_set_current_user( $this->user ); - $tools_controller = new WC_REST_System_Status_Tools_Controller(); $raw_tools = $tools_controller->get_tools(); @@ -303,8 +308,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_get_system_tool() { - wp_set_current_user( $this->user ); - $tools_controller = new WC_REST_System_Status_Tools_Controller(); $raw_tools = $tools_controller->get_tools(); $raw_tool = $raw_tools['recount_terms']; @@ -359,8 +362,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 3.5.0 */ public function test_execute_system_tool() { - wp_set_current_user( $this->user ); - $tools_controller = new WC_REST_System_Status_Tools_Controller(); $raw_tools = $tools_controller->get_tools(); $raw_tool = $raw_tools['recount_terms']; From 64f09329dd29fb871fbd741c77a3f7d591401e58 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Wed, 8 Jan 2020 15:33:42 -0300 Subject: [PATCH 216/440] Add unit test to test filtering by field when getting system status --- unit-tests/Tests/Version3/system-status.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/unit-tests/Tests/Version3/system-status.php b/unit-tests/Tests/Version3/system-status.php index ead97dd1c77..52da1e6c165 100644 --- a/unit-tests/Tests/Version3/system-status.php +++ b/unit-tests/Tests/Version3/system-status.php @@ -106,6 +106,26 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $this->assertEquals( WC()->version, $environment['version'] ); } + /** + * Test to make sure that it is possible to filter + * the environment fields returned in the response. + */ + public function test_get_system_status_info_environment_filtered_by_field() { + $expected_data = array( + 'environment' => array( + 'version' => WC()->version + ) + ); + + $request = new WP_REST_Request( 'GET', '/wc/v3/system_status' ); + $request->set_query_params( array( '_fields' => 'environment.version' ) ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( $expected_data, $data ); + } + /** * Test to make sure database response is correct. * From 7eded142c797f138a2b7b8899f59cda04adc71cc Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 9 Jan 2020 17:23:29 -0300 Subject: [PATCH 217/440] Remove extra loop --- .../class-wc-rest-system-status-v2-controller.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index b30ce69e169..7f4dcb93355 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -74,13 +74,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { $schema = $this->get_item_schema(); $fields = $this->get_fields_for_response( $request ); $mappings = $this->get_item_mappings( $fields ); - $response = array(); - - foreach ( $mappings as $section => $values ) { - $response[ $section ] = $values; - } - - $response = $this->prepare_item_for_response( $response, $request ); + $response = $this->prepare_item_for_response( $mappings, $request ); return rest_ensure_response( $response ); } From 19b7e278ace5f96afafc4a8176e47cb32c52dc8d Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 9 Jan 2020 17:25:10 -0300 Subject: [PATCH 218/440] Fixed schema --- .../Version2/class-wc-rest-system-status-v2-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 7f4dcb93355..7296cbcda38 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -110,7 +110,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'context' => array( 'view' ), 'readonly' => true, ), - 'wc_version' => array( + 'version' => array( 'description' => __( 'WooCommerce version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), From 06ec2fd9c6192112a24a21e4db3432db72df8578 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 9 Jan 2020 17:31:47 -0300 Subject: [PATCH 219/440] Set correct type --- .../Version2/class-wc-rest-system-status-v2-controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 7296cbcda38..73c76b3c04c 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -684,8 +684,8 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '', 'php_version' => phpversion(), 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), - 'php_max_execution_time' => ini_get( 'max_execution_time' ), - 'php_max_input_vars' => ini_get( 'max_input_vars' ), + 'php_max_execution_time' => (int) ini_get( 'max_execution_time' ), + 'php_max_input_vars' => (int) ini_get( 'max_input_vars' ), 'curl_version' => $curl_version, 'suhosin_installed' => extension_loaded( 'suhosin' ), 'max_upload_size' => wp_max_upload_size(), From d133875e5dfea1958b499911304aa4346be92132 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 9 Jan 2020 17:48:58 -0300 Subject: [PATCH 220/440] Keep backwards compatibility --- ...ss-wc-rest-system-status-v2-controller.php | 89 ++++++++++++++----- 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 73c76b3c04c..85aa67816e0 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -73,7 +73,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { public function get_items( $request ) { $schema = $this->get_item_schema(); $fields = $this->get_fields_for_response( $request ); - $mappings = $this->get_item_mappings( $fields ); + $mappings = $this->get_item_mappings_per_fields( $fields ); $response = $this->prepare_item_for_response( $mappings, $request ); return rest_ensure_response( $response ); @@ -560,12 +560,35 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { /** * Return an array of sections and the data associated with each. * + * @deprecated 3.9.0 * @param array $fields List of fields to be included on the response. * @return array */ - public function get_item_mappings( $fields ) { + public function get_item_mappings() { return array( - 'environment' => $this->get_environment_info( $fields ), + 'environment' => $this->get_environment_info(), + 'database' => $this->get_database_info(), + 'active_plugins' => $this->get_active_plugins(), + 'inactive_plugins' => $this->get_inactive_plugins(), + 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(), + 'theme' => $this->get_theme_info(), + 'settings' => $this->get_settings(), + 'security' => $this->get_security_info(), + 'pages' => $this->get_pages(), + 'post_type_counts' => $this->get_post_type_counts(), + ); + } + + /** + * Return an array of sections and the data associated with each. + * + * @since 3.9.0 + * @param array $fields List of fields to be included on the response. + * @return array + */ + public function get_item_mappings_per_fields( $fields ) { + return array( + 'environment' => $this->get_environment_info_per_fields( $fields ), 'database' => $this->get_database_info(), 'active_plugins' => $this->get_active_plugins(), 'inactive_plugins' => $this->get_inactive_plugins(), @@ -578,6 +601,45 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ); } + /** + * Get array of environment information. Includes thing like software + * versions, and various server settings. + * + * @deprecated 3.9.0 + * @return array + */ + public function get_environment_info() { + return $this->get_environment_info_per_fields( array( 'environment' ) ); + } + + /** + * Check if field item exists. + * + * @since 3.9.0 + * @param string $section Fields section. + * @param array $items List of items to check for. + * @param array $fields List of fields to be included on the response. + * @return bool + */ + private function check_if_field_item_exists( $section, $items, $fields ) { + if ( ! in_array( $section, $fields, true ) ) { + return false; + } + + $exclude = array(); + foreach ( $fields as $field ) { + $values = explode( '.', $field ); + + if ( $section !== $values[0] || empty( $values[1] ) ) { + continue; + } + + $exclude[] = $values[1]; + } + + return 0 <= count( array_intersect( $items, $exclude ) ); + } + /** * Get array of environment information. Includes thing like software * versions, and various server settings. @@ -585,26 +647,11 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { * @param array $fields List of fields to be included on the response. * @return array */ - public function get_environment_info( $fields ) { + public function get_environment_info_per_fields( $fields ) { global $wpdb; - $enable_remote_post = false; - $enable_remote_get = false; - if ( in_array( 'environment', $fields, true ) ) { - $exclude = array(); - foreach ( $fields as $field ) { - $values = explode( '.', $field ); - - if ( 'environment' !== $values[0] || empty( $values[1] ) ) { - continue; - } - - $exclude[] = $values[1]; - } - - $enable_remote_post = 0 <= count( array_intersect( array( 'remote_post_successful', 'remote_post_response' ), $exclude ) ); - $enable_remote_get = 0 <= count( array_intersect( array( 'remote_get_successful', 'remote_get_response' ), $exclude ) ); - } + $enable_remote_post = $this->check_if_field_item_exists( 'environment', array( 'remote_post_successful', 'remote_post_response' ), $fields ); + $enable_remote_get = $this->check_if_field_item_exists( 'environment', array( 'remote_post_successful', 'remote_post_response' ), $fields ); // Figure out cURL version, if installed. $curl_version = ''; From c55b49194ba5b3bf81c2c1b5d87b84511ab8e3f3 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 9 Jan 2020 17:52:13 -0300 Subject: [PATCH 221/440] Fixed coding standards --- ...ss-wc-rest-system-status-v2-controller.php | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 85aa67816e0..3ec63f62be2 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -90,7 +90,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'title' => 'system_status', 'type' => 'object', 'properties' => array( - 'environment' => array( + 'environment' => array( 'description' => __( 'Environment.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), @@ -110,7 +110,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'context' => array( 'view' ), 'readonly' => true, ), - 'version' => array( + 'version' => array( 'description' => __( 'WooCommerce version.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), @@ -218,7 +218,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'context' => array( 'view' ), 'readonly' => true, ), - 'mysql_version_string' => array( + 'mysql_version_string' => array( 'description' => __( 'MySQL version string.', 'woocommerce-rest-api' ), 'type' => 'string', 'context' => array( 'view' ), @@ -286,7 +286,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), ), - 'database' => array( + 'database' => array( 'description' => __( 'Database.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), @@ -321,7 +321,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), ), - 'active_plugins' => array( + 'active_plugins' => array( 'description' => __( 'Active plugins.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), @@ -330,7 +330,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'type' => 'string', ), ), - 'inactive_plugins' => array( + 'inactive_plugins' => array( 'description' => __( 'Inactive plugins.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), @@ -348,7 +348,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'type' => 'string', ), ), - 'theme' => array( + 'theme' => array( 'description' => __( 'Theme.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), @@ -433,7 +433,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), ), - 'settings' => array( + 'settings' => array( 'description' => __( 'Settings.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), @@ -513,7 +513,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), ), - 'security' => array( + 'security' => array( 'description' => __( 'Security.', 'woocommerce-rest-api' ), 'type' => 'object', 'context' => array( 'view' ), @@ -533,7 +533,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), ), - 'pages' => array( + 'pages' => array( 'description' => __( 'WooCommerce pages.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), @@ -542,7 +542,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'type' => 'string', ), ), - 'post_type_counts' => array( + 'post_type_counts' => array( 'description' => __( 'Total post count.', 'woocommerce-rest-api' ), 'type' => 'array', 'context' => array( 'view' ), @@ -561,7 +561,6 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { * Return an array of sections and the data associated with each. * * @deprecated 3.9.0 - * @param array $fields List of fields to be included on the response. * @return array */ public function get_item_mappings() { @@ -665,7 +664,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { // WP memory limit. $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); if ( function_exists( 'memory_get_usage' ) ) { - $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); + $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } // Test POST requests. @@ -720,7 +719,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'site_url' => get_option( 'siteurl' ), 'version' => WC()->version, 'log_directory' => WC_LOG_DIR, - 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), + 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen 'wp_version' => get_bloginfo( 'version' ), 'wp_multisite' => is_multisite(), 'wp_memory_limit' => $wp_memory_limit, @@ -840,7 +839,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { continue; } - $table_type = in_array( $table->name, $core_tables ) ? 'woocommerce' : 'other'; + $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; $tables[ $table_type ][ $table->name ] = array( 'data' => $table->data, @@ -1129,7 +1128,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'thousand_separator' => wc_get_price_thousand_separator(), 'decimal_separator' => wc_get_price_decimal_separator(), 'number_of_decimals' => wc_get_price_decimals(), - 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ), + 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ), true ), 'taxonomies' => $term_response, 'product_visibility_terms' => $product_visibility_terms, 'woocommerce_com_connected' => $woo_com_connected, From 4ea0e73909ac463e31af2e16203c79bb4bf8f272 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 13 Jan 2020 21:17:42 -0300 Subject: [PATCH 222/440] Fixed logic and removed old variable --- .../Version2/class-wc-rest-system-status-v2-controller.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 3ec63f62be2..99d9cdb3b3c 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -71,7 +71,6 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { * @return WP_Error|WP_REST_Response */ public function get_items( $request ) { - $schema = $this->get_item_schema(); $fields = $this->get_fields_for_response( $request ); $mappings = $this->get_item_mappings_per_fields( $fields ); $response = $this->prepare_item_for_response( $mappings, $request ); @@ -650,7 +649,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { global $wpdb; $enable_remote_post = $this->check_if_field_item_exists( 'environment', array( 'remote_post_successful', 'remote_post_response' ), $fields ); - $enable_remote_get = $this->check_if_field_item_exists( 'environment', array( 'remote_post_successful', 'remote_post_response' ), $fields ); + $enable_remote_get = $this->check_if_field_item_exists( 'environment', array( 'remote_get_successful', 'remote_get_response' ), $fields ); // Figure out cURL version, if installed. $curl_version = ''; From 10f55dbff48350437b9e4b9abda79422f3746d32 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 9 Jan 2020 15:22:08 -0300 Subject: [PATCH 223/440] Fix unit test suite in the Travis build jobs This commit fixes a problem in the script that configures the environment to run the unit tests in the Travis build jobs. The script was not running `composer install` in the WooCommerce directory, leaving it installation incomplete and thus the tests were failing. To fix this problem, this commit adds a call to `composer install` right after WooCommerce is downloaded in the setup script (`unit-tests/bin/install.sh`). --- unit-tests/bin/install.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh index 0b6747fc8a3..8ab83ff1a13 100755 --- a/unit-tests/bin/install.sh +++ b/unit-tests/bin/install.sh @@ -181,6 +181,9 @@ install_deps() { git clone --depth 1 https://github.com/woocommerce/woocommerce.git + cd "woocommerce" + composer install + cd "$WP_CORE_DIR" php wp-cli.phar plugin activate woocommerce From e325eafc9aeaa7ca151d0cacc16d461010c6df4f Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Fri, 10 Jan 2020 15:23:17 -0300 Subject: [PATCH 224/440] Remove image after unit tests to make sure they pass on Travis The test WC_Tests_API_Functions::test_wc_rest_upload_image_from_url_should_download_image_and_return_array() was failing on Travis with the error below due images being kept on accros different tests. To fix this problem, this commit makes sure that every test that creates an image, removes it after the assertions. ``` 1) WC_Tests_API_Functions::test_wc_rest_upload_image_from_url_should_download_image_and_return_array Failed asserting that two arrays are equal. --- Expected +++ Actual @@ @@ Array ( - 'file' => '/tmp/wordpress/wp-content/uploads/2020/01/Dr1Bczxq4q.png' - 'url' => 'http://example.org/wp-content/uploads/2020/01/Dr1Bczxq4q.png' + 'file' => '/tmp/wordpress/wp-content/uploads/2020/01/Dr1Bczxq4q-3.png' + 'url' => 'http://example.org/wp-content/uploads/2020/01/Dr1Bczxq4q-3.png' /home/travis/build/woocommerce/woocommerce-rest-api/unit-tests/Tests/Version3/functions.php:113 ``` (https://travis-ci.org/woocommerce/woocommerce-rest-api/jobs/634921426#L719) --- unit-tests/Tests/Version2/product-variations.php | 4 ++++ unit-tests/Tests/Version2/products.php | 1 + unit-tests/Tests/Version3/product-variations.php | 4 ++++ unit-tests/Tests/Version3/products.php | 1 + 4 files changed, 10 insertions(+) diff --git a/unit-tests/Tests/Version2/product-variations.php b/unit-tests/Tests/Version2/product-variations.php index 9c7efae4451..22a53d4d829 100644 --- a/unit-tests/Tests/Version2/product-variations.php +++ b/unit-tests/Tests/Version2/product-variations.php @@ -214,6 +214,8 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { $this->assertEquals( 'medium', $variation['attributes'][0]['option'], print_r( $variation, true ) ); $this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'], print_r( $variation, true ) ); $this->assertContains( 'test upload image', $variation['image']['alt'], print_r( $variation, true ) ); + + wp_delete_attachment( $variation['image']['id'], true ); } /** @@ -376,6 +378,8 @@ class Product_Variations_API_V2 extends WC_REST_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 2, count( $data ) ); + + wp_delete_attachment( $data[1]['image']['id'], true ); } /** diff --git a/unit-tests/Tests/Version2/products.php b/unit-tests/Tests/Version2/products.php index 165110cad3b..ea67735ae4e 100644 --- a/unit-tests/Tests/Version2/products.php +++ b/unit-tests/Tests/Version2/products.php @@ -196,6 +196,7 @@ class Products_API_V2 extends WC_REST_Unit_Test_Case { $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); $product->delete( true ); + wp_delete_attachment( $data['images'][0]['id'], true ); // test variable product (variations are tested in product-variations.php). $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); diff --git a/unit-tests/Tests/Version3/product-variations.php b/unit-tests/Tests/Version3/product-variations.php index 5c1c313cf20..98bfda23c6b 100644 --- a/unit-tests/Tests/Version3/product-variations.php +++ b/unit-tests/Tests/Version3/product-variations.php @@ -214,6 +214,8 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { $this->assertEquals( 'medium', $variation['attributes'][0]['option'], print_r( $variation, true ) ); $this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'], print_r( $variation, true ) ); $this->assertContains( 'test upload image', $variation['image']['alt'], print_r( $variation, true ) ); + + wp_delete_attachment( $variation['image']['id'], true ); } /** @@ -378,6 +380,8 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 2, count( $data ) ); + + wp_delete_attachment( $data[1]['image']['id'], true ); } /** diff --git a/unit-tests/Tests/Version3/products.php b/unit-tests/Tests/Version3/products.php index 7da09a9c136..10f876d07ee 100644 --- a/unit-tests/Tests/Version3/products.php +++ b/unit-tests/Tests/Version3/products.php @@ -199,6 +199,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); $product->delete( true ); + wp_delete_attachment( $data['images'][0]['id'], true ); // test variable product (variations are tested in product-variations.php). $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); From ea36caf17eed52b5a641b8e4a5fe0481d91840fe Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 13 Jan 2020 21:38:36 -0300 Subject: [PATCH 225/440] Removed MaxMind from System Status --- .../Version2/class-wc-rest-system-status-v2-controller.php | 2 +- unit-tests/Tests/Version2/system-status.php | 1 - unit-tests/Tests/Version3/system-status.php | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 99d9cdb3b3c..448f30f0725 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -855,7 +855,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { return array( 'wc_database_version' => get_option( 'woocommerce_db_version' ), 'database_prefix' => $wpdb->prefix, - 'maxmind_geoip_database' => WC_Geolocation::get_local_database_path(), + 'maxmind_geoip_database' => '', 'database_tables' => $tables, 'database_size' => $database_size, ); diff --git a/unit-tests/Tests/Version2/system-status.php b/unit-tests/Tests/Version2/system-status.php index 9359c260291..cb359b0630b 100644 --- a/unit-tests/Tests/Version2/system-status.php +++ b/unit-tests/Tests/Version2/system-status.php @@ -101,7 +101,6 @@ class WC_Tests_REST_System_Status_V2 extends WC_REST_Unit_Test_Case { $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); - $this->assertEquals( WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], print_r( $database, true ) ); $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], print_r( $database, true ) ); } diff --git a/unit-tests/Tests/Version3/system-status.php b/unit-tests/Tests/Version3/system-status.php index 52da1e6c165..cdf30aedaef 100644 --- a/unit-tests/Tests/Version3/system-status.php +++ b/unit-tests/Tests/Version3/system-status.php @@ -139,7 +139,6 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); - $this->assertEquals( WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], wc_print_r( $database, true ) ); $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], wc_print_r( $database, true ) ); } From 43b9f9f07d73efcc70da87403f5882275bf944a8 Mon Sep 17 00:00:00 2001 From: Siriwat Uamngamsup Date: Wed, 15 Jan 2020 14:02:29 +0700 Subject: [PATCH 226/440] Fixed wrong route path for shipping zone api --- .../Version2/class-wc-rest-shipping-zones-v2-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php index d3abcf9ff46..cd8a6b75ccf 100644 --- a/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php @@ -48,7 +48,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro ); register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d-]+)', array( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), From 78ccf4d4c6bafbc841182b68aa863e7b0caa37c8 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 15 Jan 2020 20:29:39 -0300 Subject: [PATCH 227/440] Version 1.0.6 --- README.md | 2 +- src/Package.php | 2 +- woocommerce-rest-api.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fbc4faf622f..9a2eff0a244 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ This package is [hosted on Packagist](https://packagist.org/packages/woocommerce ```json "require": { - "woocommerce/woocommerce-rest-api": "1.0.0" + "woocommerce/woocommerce-rest-api": "1.0" }, ``` diff --git a/src/Package.php b/src/Package.php index 1b3bba9a289..ce9f83edfec 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.5'; + const VERSION = '1.0.6'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 383528d51b9..c59a8259cd9 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.5 + * Version: 1.0.6 * Requires PHP: 5.6 * License: GPLv3 * From e949c82339077fabe74220d7c01162f50d2da864 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Fri, 24 Jan 2020 17:15:55 -0300 Subject: [PATCH 228/440] Added pre-commit hook --- package-lock.json | 1618 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 31 + 2 files changed, 1649 insertions(+) create mode 100644 package-lock.json create mode 100644 package.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..b1506082765 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1618 @@ +{ + "name": "woocommerce-rest-api", + "version": "1.0.5", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.5.0.tgz", + "integrity": "sha512-Onhn+z72D2O2Pb2ql2xukJ55rglumsVo1H6Fmyi8mlU9SvKdBk/pUSUAiBY/d9bAOF7VVWajX3sths/+g6ZiAQ==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + } + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "del": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", + "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", + "dev": true, + "requires": { + "globby": "^10.0.1", + "graceful-fs": "^4.2.2", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.1", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", + "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^3.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "fast-glob": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", + "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" + } + }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "husky": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.0.10.tgz", + "integrity": "sha512-Ptm4k2DqOwxeK/kzu5RaJmNRoGvESrgDXObFcZ8aJZcyXyMBHhM2FqZj6zYKdetadmP3wCwxEHCBuB9xGlRp8A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "ci-info": "^2.0.0", + "cosmiconfig": "^6.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "^1.1.0" + } + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz", + "integrity": "sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "commander": "^2.20.0", + "cosmiconfig": "^5.2.1", + "debug": "^4.1.1", + "dedent": "^0.7.0", + "del": "^5.0.0", + "execa": "^2.0.3", + "listr": "^0.14.3", + "log-symbols": "^3.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.1.1", + "string-argv": "^0.3.0", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "dev": true, + "requires": { + "@samverschueren/stream-to-observable": "^0.3.0", + "is-observable": "^1.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" + }, + "dependencies": { + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", + "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yaml": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", + "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.6.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000000..c3842219a49 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "woocommerce-rest-api", + "title": "WooCommerce REST API", + "version": "1.0.5", + "homepage": "https://woocommerce.com/", + "repository": { + "type": "git", + "url": "https://github.com/woocommerce/woocommerce-rest-api.git" + }, + "license": "GPL-3.0+", + "main": "Gruntfile.js", + "devDependencies": { + "husky": "4.0.10", + "lint-staged": "9.5.0" + }, + "engines": { + "node": ">=10.15.0", + "npm": ">=6.4.1" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.php": [ + "php -d display_errors=1 -l", + "composer run-script phpcs-pre-commit" + ] + } +} From 1ca43e200255bc92701174d006259722bca4bc56 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 23 Jan 2020 10:58:33 -0300 Subject: [PATCH 229/440] Revert "Fixed type numeric type on products and variations schema" --- ...class-wc-rest-product-variations-controller.php | 14 +++++++------- .../Version3/class-wc-rest-products-controller.php | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Controllers/Version3/class-wc-rest-product-variations-controller.php b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php index 8aaa1c08e37..0477e818df9 100644 --- a/src/Controllers/Version3/class-wc-rest-product-variations-controller.php +++ b/src/Controllers/Version3/class-wc-rest-product-variations-controller.php @@ -441,18 +441,18 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ), 'price' => array( 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( @@ -595,7 +595,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V 'weight' => array( /* translators: %s: weight unit */ 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( @@ -606,19 +606,19 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V 'length' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), diff --git a/src/Controllers/Version3/class-wc-rest-products-controller.php b/src/Controllers/Version3/class-wc-rest-products-controller.php index 2de987aaa3b..a6401bf6d91 100644 --- a/src/Controllers/Version3/class-wc-rest-products-controller.php +++ b/src/Controllers/Version3/class-wc-rest-products-controller.php @@ -786,18 +786,18 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), 'price' => array( 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( @@ -962,7 +962,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'weight' => array( /* translators: %s: weight unit */ 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( @@ -973,19 +973,19 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'length' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'number', + 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), From 35e3f65dbda0536a27ce0488ffc757c55281054d Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 28 Jan 2020 18:03:37 -0300 Subject: [PATCH 230/440] Version 1.0.7 --- src/Package.php | 2 +- woocommerce-rest-api.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Package.php b/src/Package.php index ce9f83edfec..e524c51bcef 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.6'; + const VERSION = '1.0.7'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index c59a8259cd9..296dac73707 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.6 + * Version: 1.0.7 * Requires PHP: 5.6 * License: GPLv3 * From 49162ec26a25bd0c6efc0f3452b113cdfff0a823 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 28 Jan 2020 18:04:51 -0300 Subject: [PATCH 231/440] Added missing composer scripts --- composer.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/composer.json b/composer.json index 556ad45b570..cfacbd52c0b 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,18 @@ ], "post-update-cmd": [ "composer dump-autoload" + ], + "test": [ + "phpunit" + ], + "phpcs": [ + "phpcs -s -p" + ], + "phpcs-pre-commit": [ + "phpcs -s -p -n" + ], + "phpcbf": [ + "phpcbf -p" ] }, "autoload": { From 9da21bc84127eeb4e5a0daeae6c202fbff1e2c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Demarle?= Date: Sun, 12 Apr 2020 17:50:55 +0200 Subject: [PATCH 232/440] Add filter for products to reserve stock --- src/Checkout/Helpers/ReserveStock.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Checkout/Helpers/ReserveStock.php b/src/Checkout/Helpers/ReserveStock.php index b882cf83906..4976d523240 100644 --- a/src/Checkout/Helpers/ReserveStock.php +++ b/src/Checkout/Helpers/ReserveStock.php @@ -76,6 +76,17 @@ final class ReserveStock { $rows[ $managed_by_id ] = isset( $rows[ $managed_by_id ] ) ? $rows[ $managed_by_id ] + $item->get_quantity() : $item->get_quantity(); } + /** + * Filter: woocommerce_reserve_stock_for_products + * Allows to filter the product ids and the quantity to reserve stock. + * + * @since @since 4.1.0 + * @param array $rows An array with ordered product id as key and quantity as value. + * @param \WC_Order $order Order object. + * @param int $minutes How long to reserve stock in minutes. + */ + $rows = apply_filters( 'woocommerce_reserve_stock_for_products', $rows, $order, $minutes ); + if ( ! empty( $rows ) ) { foreach ( $rows as $product_id => $quantity ) { $this->reserve_stock_for_product( $product_id, $quantity, $order, $minutes ); From 2a70859888104a923c3f516d4a5929ffd1f8f398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Demarle?= Date: Sun, 12 Apr 2020 18:03:54 +0200 Subject: [PATCH 233/440] Remove extra @since --- src/Checkout/Helpers/ReserveStock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Checkout/Helpers/ReserveStock.php b/src/Checkout/Helpers/ReserveStock.php index 4976d523240..86395f1a8d9 100644 --- a/src/Checkout/Helpers/ReserveStock.php +++ b/src/Checkout/Helpers/ReserveStock.php @@ -80,7 +80,7 @@ final class ReserveStock { * Filter: woocommerce_reserve_stock_for_products * Allows to filter the product ids and the quantity to reserve stock. * - * @since @since 4.1.0 + * @since 4.1.0 * @param array $rows An array with ordered product id as key and quantity as value. * @param \WC_Order $order Order object. * @param int $minutes How long to reserve stock in minutes. From 6fa5977579fc2943710cbc9e729ee27aefaf95d4 Mon Sep 17 00:00:00 2001 From: Kevin Ruscoe Date: Sat, 9 May 2020 12:03:43 +0100 Subject: [PATCH 234/440] Add filters Adds woocommerce_cart_product_cannot_add_another_message, woocommerce_cart_product_out_of_stock_message, woocommerce_cart_product_not_enough_stock_message --- includes/class-wc-cart.php | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index 17378bfbf1b..ab757e9f093 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -1040,7 +1040,16 @@ class WC_Cart extends WC_Legacy_Cart { if ( $found_in_cart ) { /* translators: %s: product name */ - throw new Exception( sprintf( '%s %s', wc_get_cart_url(), __( 'View cart', 'woocommerce' ), sprintf( __( 'You cannot add another "%s" to your cart.', 'woocommerce' ), $product_data->get_name() ) ) ); + $message = sprintf( __( 'You cannot add another "%s" to your cart.', 'woocommerce' ), $product_data->get_name() ); + /** + * Filters message about more than 1 product being added to cart. + * + * @param string $message Message. + * @param WC_Product $product_data Product data. + */ + $message = apply_filters( 'woocommerce_cart_product_cannot_add_another_message', $message, $product_data ); + + throw new Exception( sprintf( '%s %s', wc_get_cart_url(), __( 'View cart', 'woocommerce' ), $message ) ); } } @@ -1060,12 +1069,32 @@ class WC_Cart extends WC_Legacy_Cart { // Stock check - only check if we're managing stock and backorders are not allowed. if ( ! $product_data->is_in_stock() ) { /* translators: %s: product name */ - throw new Exception( sprintf( __( 'You cannot add "%s" to the cart because the product is out of stock.', 'woocommerce' ), $product_data->get_name() ) ); + $message = sprintf( __( 'You cannot add "%s" to the cart because the product is out of stock.', 'woocommerce' ), $product_data->get_name() ); + /** + * Filters message about product being out of stock. + * + * @param string $message Message. + * @param WC_Product $product_data Product data. + */ + $message = apply_filters( 'woocommerce_cart_product_out_of_stock_message', $message, $product_data ); + throw new Exception( $message ); } if ( ! $product_data->has_enough_stock( $quantity ) ) { + $stock_quantity = $product_data->get_stock_quantity(); + /* translators: 1: product name 2: quantity in stock */ - throw new Exception( sprintf( __( 'You cannot add that amount of "%1$s" to the cart because there is not enough stock (%2$s remaining).', 'woocommerce' ), $product_data->get_name(), wc_format_stock_quantity_for_display( $product_data->get_stock_quantity(), $product_data ) ) ); + $message = sprintf( __( 'You cannot add that amount of "%1$s" to the cart because there is not enough stock (%2$s remaining).', 'woocommerce' ), $product_data->get_name(), wc_format_stock_quantity_for_display( $stock_quantity, $product_data ) ); + /** + * Filters message about product not having enough stock. + * + * @param string $message Message. + * @param WC_Product $product_data Product data. + * @param int $stock_quantity Quantity remaining. + */ + $message = apply_filters( 'woocommerce_cart_product_not_enough_stock_message', $message, $product_data, $stock_quantity ); + + throw new Exception( $message ); } // Stock check - this time accounting for whats already in-cart. From ec1e0b11105cb3a559c9f2d805cedd2192d6c110 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 7 May 2020 23:07:15 +0530 Subject: [PATCH 235/440] Add unit test for trash status for products --- unit-tests/Tests/Version3/products.php | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/unit-tests/Tests/Version3/products.php b/unit-tests/Tests/Version3/products.php index 10f876d07ee..22351897134 100644 --- a/unit-tests/Tests/Version3/products.php +++ b/unit-tests/Tests/Version3/products.php @@ -58,6 +58,59 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $this->assertEquals( 'DUMMY EXTERNAL SKU', $products[1]['sku'] ); } + /** + * Test getting trashed products. + */ + public function test_get_trashed_products() { + wp_set_current_user( $this->user ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $data_store = WC_Data_Store::load( 'product' ); + $data_store->delete( $product ); + $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); + $request->set_query_params( array( 'status' => 'trash' ) ); + $response = $this->server->dispatch( $request ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $products ) ); + $this->assertEquals( $product->get_name(), $products[0]['name'] ); + $this->assertEquals( $product->get_id(), $products[0]['id'] ); + } + + /** + * Trashed products should not be returned by default. + */ + public function test_get_trashed_products_not_returned_by_default() { + wp_set_current_user( $this->user ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $data_store = WC_Data_Store::load( 'product' ); + $data_store->delete( $product ); + + $response = $this->server->dispatch( + new WP_REST_Request( 'GET', '/wc/v3/products' ) + ); + $products = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 0, count( $products ) ); + } + + /** + * Trashed product can be fetched directly. + */ + public function test_get_trashed_products_returned_by_id() { + wp_set_current_user( $this->user ); + $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); + $data_store = WC_Data_Store::load( 'product' ); + $data_store->delete( $product ); + + $response = $this->server->dispatch( + new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) + ); + + $this->assertEquals( 200, $response->get_status() ); + } + /** * Test getting products without permission. * From 57b59271bf6c0e6a58b10fde9a7cddd88fd14b15 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 7 May 2020 23:07:35 +0530 Subject: [PATCH 236/440] Change file path in response to change in core --- unit-tests/Bootstrap.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php index d4658968ce8..b10c7f8eae5 100755 --- a/unit-tests/Bootstrap.php +++ b/unit-tests/Bootstrap.php @@ -113,11 +113,11 @@ class Bootstrap { require_once $this->wp_tests_dir . '/includes/bootstrap.php'; // WooCommerce Core Testing Framework. - require_once $this->wc_tests_dir . '/framework/class-wc-unit-test-factory.php'; - require_once $this->wc_tests_dir . '/framework/vendor/class-wp-test-spy-rest-server.php'; - require_once $this->wc_tests_dir . '/includes/wp-http-testcase.php'; - require_once $this->wc_tests_dir . '/framework/class-wc-unit-test-case.php'; - require_once $this->wc_tests_dir . '/framework/class-wc-rest-unit-test-case.php'; + require_once $this->wc_tests_dir . '/legacy/framework/class-wc-unit-test-factory.php'; + require_once $this->wc_tests_dir . '/legacy/framework/vendor/class-wp-test-spy-rest-server.php'; + require_once $this->wc_tests_dir . '/legacy/includes/wp-http-testcase.php'; + require_once $this->wc_tests_dir . '/legacy/framework/class-wc-unit-test-case.php'; + require_once $this->wc_tests_dir . '/legacy/framework/class-wc-rest-unit-test-case.php'; require_once $this->tests_dir . '/Helpers/AdminNotesHelper.php'; require_once $this->tests_dir . '/Helpers/CouponHelper.php'; From f4e093d52816d3743c36b9b89638dbb45b712935 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Fri, 8 May 2020 03:20:32 +0530 Subject: [PATCH 237/440] Fix unit test --- unit-tests/Tests/Version3/functions.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/unit-tests/Tests/Version3/functions.php b/unit-tests/Tests/Version3/functions.php index 3f6f96404de..88522c341d7 100644 --- a/unit-tests/Tests/Version3/functions.php +++ b/unit-tests/Tests/Version3/functions.php @@ -82,7 +82,11 @@ class WC_Tests_API_Functions extends WC_Unit_Test_Case { */ public function test_wc_rest_upload_image_from_url_should_return_error_when_invalid_image_is_passed() { // empty file. - $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; + if ( version_compare( get_bloginfo( 'version' ), '5.4-alpha', '>=' ) ) { + $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini file or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; + } else { + $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; + } $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-1.png' ); $this->assertWPError( $result ); From 02aa89614e6b8fcb01a79faf47d05dfd8b0d38d4 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Fri, 8 May 2020 03:35:25 +0530 Subject: [PATCH 238/440] Applied coding standards --- .../Version2/class-wc-rest-products-v2-controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php index d6942fc2826..a274c88fa3b 100644 --- a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php @@ -419,9 +419,9 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { $images[] = array( 'id' => 0, 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), // Default to now. - 'date_created_gmt' => wc_rest_prepare_date_response( current_time( 'timestamp', true ) ), // Default to now. + 'date_created_gmt' => wc_rest_prepare_date_response( time() ), // Default to now. 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( current_time( 'timestamp', true ) ), + 'date_modified_gmt' => wc_rest_prepare_date_response( time() ), 'src' => wc_placeholder_img_src(), 'name' => __( 'Placeholder', 'woocommerce-rest-api' ), 'alt' => __( 'Placeholder', 'woocommerce-rest-api' ), From 569e656459aba212d9c90a415df6e344161ac01a Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Mon, 11 May 2020 14:31:58 +0530 Subject: [PATCH 239/440] Rephrase the test so that is more resilient and error-prone --- unit-tests/Tests/Version3/functions.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/unit-tests/Tests/Version3/functions.php b/unit-tests/Tests/Version3/functions.php index 88522c341d7..3b3b27eb5c9 100644 --- a/unit-tests/Tests/Version3/functions.php +++ b/unit-tests/Tests/Version3/functions.php @@ -82,15 +82,11 @@ class WC_Tests_API_Functions extends WC_Unit_Test_Case { */ public function test_wc_rest_upload_image_from_url_should_return_error_when_invalid_image_is_passed() { // empty file. - if ( version_compare( get_bloginfo( 'version' ), '5.4-alpha', '>=' ) ) { - $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini file or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; - } else { - $expected_error_message = 'Invalid image: File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.'; - } + $expected_error_message = 'Invalid image: File is empty.'; $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-1.png' ); $this->assertWPError( $result ); - $this->assertEquals( $expected_error_message, $result->get_error_message() ); + $this->assertStringStartsWith( $expected_error_message, $result->get_error_message() ); // unsupported mime type. $expected_error_message = 'Invalid image: Sorry, this file type is not permitted for security reasons.'; From f7eab9db6e3991360bff54b8e4ffdbd95c82880a Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 7 May 2020 23:06:33 +0530 Subject: [PATCH 240/440] Enable support trash status for products when its passed --- .../Version2/class-wc-rest-products-v2-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php index a274c88fa3b..f38ecb7dfb9 100644 --- a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php @@ -2115,7 +2115,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'default' => 'any', 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), 'type' => 'string', - 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), + 'enum' => array_merge( array( 'any', 'future', 'trash' ), array_keys( get_post_statuses() ) ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); From c792dfb192e4e274fda0520beeef1619f155cfa1 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo Date: Thu, 16 Jan 2020 14:23:01 -0300 Subject: [PATCH 241/440] Fix unit tests to match new tested method behavior This commit updates two unit tests that were failing (https://travis-ci.org/woocommerce/woocommerce-rest-api/jobs/637678251#L707), after the behavior of the method WC_REST_Shipping_Zones_V2_Controller::register_routes() changed in PR #104. --- unit-tests/Tests/Version2/shipping-zones.php | 2 +- unit-tests/Tests/Version3/shipping-zones.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unit-tests/Tests/Version2/shipping-zones.php b/unit-tests/Tests/Version2/shipping-zones.php index c6e2c4a102e..1d9ea5368d3 100644 --- a/unit-tests/Tests/Version2/shipping-zones.php +++ b/unit-tests/Tests/Version2/shipping-zones.php @@ -55,7 +55,7 @@ class WC_Tests_API_Shipping_Zones_V2 extends WC_REST_Unit_Test_Case { public function test_register_routes() { $routes = $this->server->get_routes(); $this->assertArrayHasKey( '/wc/v2/shipping/zones', $routes ); - $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)', $routes ); $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/locations', $routes ); $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/methods', $routes ); $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/methods/(?P[\d]+)', $routes ); diff --git a/unit-tests/Tests/Version3/shipping-zones.php b/unit-tests/Tests/Version3/shipping-zones.php index 580391d1b33..a735357b41f 100644 --- a/unit-tests/Tests/Version3/shipping-zones.php +++ b/unit-tests/Tests/Version3/shipping-zones.php @@ -57,7 +57,7 @@ class WC_Tests_API_Shipping_Zones extends WC_REST_Unit_Test_Case { public function test_register_routes() { $routes = $this->server->get_routes(); $this->assertArrayHasKey( '/wc/v3/shipping/zones', $routes ); - $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)', $routes ); $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/locations', $routes ); $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/methods', $routes ); $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/methods/(?P[\d]+)', $routes ); From 7c9fd1ab0c2b7b1c0892cd35ed231a2ef358d86c Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Mon, 11 May 2020 17:37:14 +0530 Subject: [PATCH 242/440] Version update and min requirement bump --- package.json | 2 +- src/Package.php | 2 +- woocommerce-rest-api.php | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c3842219a49..54554e3a408 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "woocommerce-rest-api", "title": "WooCommerce REST API", - "version": "1.0.5", + "version": "1.0.8", "homepage": "https://woocommerce.com/", "repository": { "type": "git", diff --git a/src/Package.php b/src/Package.php index e524c51bcef..13c5ff30588 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.7'; + const VERSION = '1.0.8'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 296dac73707..10b7ea38a29 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,8 +5,8 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.7 - * Requires PHP: 5.6 + * Version: 1.0.8 + * Requires PHP: 7.0 * License: GPLv3 * * @package Automattic/WooCommerce/RestApi @@ -15,7 +15,7 @@ defined( 'ABSPATH' ) || exit; -if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) { +if ( version_compare( PHP_VERSION, '7.0.0', '<' ) ) { return; } From e11141f577e04de7c92ae7297b56acb09417140f Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Fri, 27 Mar 2020 09:55:20 -0700 Subject: [PATCH 243/440] Added files that should be ignored on export to .gitattributes --- .gitattributes | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitattributes b/.gitattributes index b5d3da03cbb..03e96f3a100 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,3 +5,8 @@ /vendor export-ignore /README.md export-ignore /readme.txt export-ignore +/composer.* export-ignore +/package.json export-ignore +/package-lock.json export-ignore +/renovate.json export-ignore +/unit-tests export-ignore From 88e72cd11274db503ff0120e066eff9edf859d7f Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Mon, 11 May 2020 23:43:31 +0530 Subject: [PATCH 244/440] Add tool for verifying database table --- ...rest-system-status-tools-v2-controller.php | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 325f551d935..b592acf3341 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -200,6 +200,16 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), ); + if ( method_exists( 'WC_Install', 'verify_base_tables' ) ) { + $tools['verify_db_tables'] = array( + 'name' => __( 'Verify base database tables', 'woocommerce-rest-api' ), + 'button' => __( 'Verify database', 'woocommerce-rest-api' ), + 'desc' => sprintf( + __( 'Verify if all base database tables are present.', 'woocommerce-rest-api' ) + ), + ); + } + // Jetpack does the image resizing heavy lifting so you don't have to. if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) { @@ -538,6 +548,22 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce-rest-api' ); break; + case 'verify_db_tables': + if ( ! method_exists( 'WC_Install', 'verify_base_tables' ) ) { + $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce' ); + $ran = false; + break; + } + $missing_tables = WC_Install::verify_base_tables(); + if ( 0 === count( $missing_tables ) ) { + $message = __( 'Database verified successfully.', 'woocommerce-rest-api' ); + } else { + $message = __( 'Verifying database... One or more tables are still missing: ', 'woocommerce-rest-api' ); + $message .= implode( ', ', $missing_tables ); + $ran = false; + } + break; + default: $tools = $this->get_tools(); if ( isset( $tools[ $tool ]['callback'] ) ) { From 8caf5a2b4f54bb44acf8704942ca6d6d36f24e2b Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 12 May 2020 17:20:28 +0530 Subject: [PATCH 245/440] Applied coding standards --- .../class-wc-rest-system-status-tools-v2-controller.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index b592acf3341..dda3931e02f 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -210,7 +210,6 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ); } - // Jetpack does the image resizing heavy lifting so you don't have to. if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) { unset( $tools['regenerate_thumbnails'] ); @@ -469,7 +468,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )", - date( 'Y-m-d', current_time( 'timestamp' ) ) + gmdate( 'Y-m-d', current_time( 'timestamp' ) ) ) ) ); @@ -550,7 +549,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { case 'verify_db_tables': if ( ! method_exists( 'WC_Install', 'verify_base_tables' ) ) { - $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce' ); + $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce-rest-api' ); $ran = false; break; } From 9c5b72a57234a8180f8fefa5c4ae5cc8729775d4 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 12 May 2020 18:12:45 +0530 Subject: [PATCH 246/440] Also add classmap for v4 to fix fatal on status page in master --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cfacbd52c0b..af77f3e2baf 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ "classmap": [ "src/Controllers/Version1", "src/Controllers/Version2", - "src/Controllers/Version3" + "src/Controllers/Version3", + "src/Controllers/Version4" ], "psr-4": { "Automattic\\WooCommerce\\RestApi\\": "src" From c23300c7cbb1ede55a96728da0500983de3372e1 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Wed, 27 May 2020 00:07:13 +0530 Subject: [PATCH 247/440] Also try to update table structure when verifying DB --- .../class-wc-rest-system-status-tools-v2-controller.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index dda3931e02f..31af6604073 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -553,7 +553,8 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $ran = false; break; } - $missing_tables = WC_Install::verify_base_tables(); + // Try to manually create table again. + $missing_tables = WC_Install::verify_base_tables( true, true ); if ( 0 === count( $missing_tables ) ) { $message = __( 'Database verified successfully.', 'woocommerce-rest-api' ); } else { From 865028556a07bb94f88d0a43e967ddd02b5ae60e Mon Sep 17 00:00:00 2001 From: Ron Rennick Date: Fri, 12 Jun 2020 05:25:55 -0300 Subject: [PATCH 248/440] add clear template cache tool --- ...-rest-system-status-tools-v2-controller.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 31af6604073..321a02b688d 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -167,6 +167,15 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce-rest-api' ) ), ), + 'clear_template_cache' => array( + 'name' => __( 'Clear template cache', 'woocommerce-rest-api' ), + 'button' => __( 'Clear', 'woocommerce-rest-api' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce-rest-api' ), + __( 'This tool will empty the template cache.', 'woocommerce-rest-api' ) + ), + ), 'install_pages' => array( 'name' => __( 'Create default WooCommerce pages', 'woocommerce-rest-api' ), 'button' => __( 'Create pages', 'woocommerce-rest-api' ), @@ -215,6 +224,10 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { unset( $tools['regenerate_thumbnails'] ); } + if ( ! function_exists( 'wc_clear_template_cache' ) ) { + unset( $tools['clear_template_cache'] ); + } + return apply_filters( 'woocommerce_debug_tools', $tools ); } @@ -564,6 +577,11 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { } break; + case 'clear_template_cache': + wc_clear_template_cache(); + $message = __( 'Template cache cleared.', 'woocommerce-rest-api' ); + break; + default: $tools = $this->get_tools(); if ( isset( $tools[ $tool ]['callback'] ) ) { From 84b96bfa3eaf4438ccb65624de0d728d24b4e0a6 Mon Sep 17 00:00:00 2001 From: Ron Rennick Date: Mon, 15 Jun 2020 13:15:31 -0300 Subject: [PATCH 249/440] add cache clearing unsupported message --- .../class-wc-rest-system-status-tools-v2-controller.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 321a02b688d..9efd82143d3 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -578,8 +578,12 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { break; case 'clear_template_cache': - wc_clear_template_cache(); - $message = __( 'Template cache cleared.', 'woocommerce-rest-api' ); + if ( function_exists( 'wc_clear_template_cache' ) ) { + wc_clear_template_cache(); + $message = __( 'Template cache cleared.', 'woocommerce-rest-api' ); + } else { + $message = __( 'The active version of WooCommerce does not support template cache clearing.', 'woocommerce-rest-api' ); + } break; default: From 3d205dbd4ab0cc2b40ee77fee1c067b2d5219174 Mon Sep 17 00:00:00 2001 From: Ron Rennick Date: Mon, 15 Jun 2020 13:17:32 -0300 Subject: [PATCH 250/440] fix merge conflits --- ...s-wc-rest-system-status-tools-v2-controller.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 9efd82143d3..3894451dab4 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -583,6 +583,20 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $message = __( 'Template cache cleared.', 'woocommerce-rest-api' ); } else { $message = __( 'The active version of WooCommerce does not support template cache clearing.', 'woocommerce-rest-api' ); + case 'verify_db_tables': + if ( ! method_exists( 'WC_Install', 'verify_base_tables' ) ) { + $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce-rest-api' ); + $ran = false; + break; + } + // Try to manually create table again. + $missing_tables = WC_Install::verify_base_tables( true, true ); + if ( 0 === count( $missing_tables ) ) { + $message = __( 'Database verified successfully.', 'woocommerce-rest-api' ); + } else { + $message = __( 'Verifying database... One or more tables are still missing: ', 'woocommerce-rest-api' ); + $message .= implode( ', ', $missing_tables ); + $ran = false; } break; From 5df976e1aad17082ed23e5eb214181c5a0101c4e Mon Sep 17 00:00:00 2001 From: Ron Rennick Date: Mon, 15 Jun 2020 13:30:35 -0300 Subject: [PATCH 251/440] restore code accidentally removed in master merge --- .../class-wc-rest-system-status-tools-v2-controller.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 3894451dab4..27da82cdbc1 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -583,6 +583,9 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $message = __( 'Template cache cleared.', 'woocommerce-rest-api' ); } else { $message = __( 'The active version of WooCommerce does not support template cache clearing.', 'woocommerce-rest-api' ); + } + break; + case 'verify_db_tables': if ( ! method_exists( 'WC_Install', 'verify_base_tables' ) ) { $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce-rest-api' ); From 42e73b90805baa627c795d20c9c5849d132089e1 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Mon, 15 Jun 2020 23:50:00 +0530 Subject: [PATCH 252/440] Unset flag to indidcate that tool did not ran. --- .../Version2/class-wc-rest-system-status-tools-v2-controller.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 27da82cdbc1..94e5f6cbe74 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -583,6 +583,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $message = __( 'Template cache cleared.', 'woocommerce-rest-api' ); } else { $message = __( 'The active version of WooCommerce does not support template cache clearing.', 'woocommerce-rest-api' ); + $ran = false; } break; From 49d1bfae5757bb4f4c4956405661ff21820763f4 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 16 Jun 2020 00:06:42 +0530 Subject: [PATCH 253/440] Fix incorrect cherry-pick code --- ...c-rest-system-status-tools-v2-controller.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index 94e5f6cbe74..a418b35844b 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -560,23 +560,6 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce-rest-api' ); break; - case 'verify_db_tables': - if ( ! method_exists( 'WC_Install', 'verify_base_tables' ) ) { - $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce-rest-api' ); - $ran = false; - break; - } - // Try to manually create table again. - $missing_tables = WC_Install::verify_base_tables( true, true ); - if ( 0 === count( $missing_tables ) ) { - $message = __( 'Database verified successfully.', 'woocommerce-rest-api' ); - } else { - $message = __( 'Verifying database... One or more tables are still missing: ', 'woocommerce-rest-api' ); - $message .= implode( ', ', $missing_tables ); - $ran = false; - } - break; - case 'clear_template_cache': if ( function_exists( 'wc_clear_template_cache' ) ) { wc_clear_template_cache(); From 8843b43357828f42368b5cb8cd687c8d6c6db89d Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 16 Jun 2020 00:09:32 +0530 Subject: [PATCH 254/440] Version bump to 1.0.9 --- package.json | 2 +- src/Package.php | 2 +- woocommerce-rest-api.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 54554e3a408..62c460acf6e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "woocommerce-rest-api", "title": "WooCommerce REST API", - "version": "1.0.8", + "version": "1.0.9", "homepage": "https://woocommerce.com/", "repository": { "type": "git", diff --git a/src/Package.php b/src/Package.php index 13c5ff30588..151c7fdf835 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.8'; + const VERSION = '1.0.9'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index 10b7ea38a29..d8caf7d9ed1 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.8 + * Version: 1.0.9 * Requires PHP: 7.0 * License: GPLv3 * From ee76869a50a8be6dd4a0418d694588d688ec1389 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 16 Jun 2020 00:53:34 +0530 Subject: [PATCH 255/440] Revert "Added files that should be ignored on export to .gitattributes" This reverts commit e11141f577e04de7c92ae7297b56acb09417140f. --- .gitattributes | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitattributes b/.gitattributes index 03e96f3a100..b5d3da03cbb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,8 +5,3 @@ /vendor export-ignore /README.md export-ignore /readme.txt export-ignore -/composer.* export-ignore -/package.json export-ignore -/package-lock.json export-ignore -/renovate.json export-ignore -/unit-tests export-ignore From 895c7a4874834422f04a18c30cc71f030e9e5a0e Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 16 Jun 2020 15:17:34 +0530 Subject: [PATCH 256/440] Revert "Also add classmap for v4 to fix fatal on status page in master" This reverts commit 3e709b92b5375248318c8e221821773de0d8b642. --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index af77f3e2baf..cfacbd52c0b 100644 --- a/composer.json +++ b/composer.json @@ -37,8 +37,7 @@ "classmap": [ "src/Controllers/Version1", "src/Controllers/Version2", - "src/Controllers/Version3", - "src/Controllers/Version4" + "src/Controllers/Version3" ], "psr-4": { "Automattic\\WooCommerce\\RestApi\\": "src" From fdcb116b4f5b699b942c01b46fd863c7da8b4b7c Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 16 Jun 2020 15:21:51 +0530 Subject: [PATCH 257/440] Version bump to 1.0.10 --- package.json | 2 +- src/Package.php | 2 +- woocommerce-rest-api.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 62c460acf6e..2d17f61330a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "woocommerce-rest-api", "title": "WooCommerce REST API", - "version": "1.0.9", + "version": "1.0.10", "homepage": "https://woocommerce.com/", "repository": { "type": "git", diff --git a/src/Package.php b/src/Package.php index 151c7fdf835..e2b421d066c 100644 --- a/src/Package.php +++ b/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.9'; + const VERSION = '1.0.10'; /** * Init the package - load the REST API Server class. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php index d8caf7d9ed1..075a160c555 100644 --- a/woocommerce-rest-api.php +++ b/woocommerce-rest-api.php @@ -5,7 +5,7 @@ * Description: The WooCommerce core REST API, installed as a feature plugin for development and testing purposes. Requires WooCommerce 3.7+ and PHP 5.3+. * Author: Automattic * Author URI: https://woocommerce.com - * Version: 1.0.9 + * Version: 1.0.10 * Requires PHP: 7.0 * License: GPLv3 * From 1418b68910600968ae6ada9380d9a2df3177ef30 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Sat, 6 Jun 2020 16:44:44 -0700 Subject: [PATCH 258/440] Initial configuration for e2e-factories package --- package-lock.json | 1233 ++++--- package.json | 10 +- tests/e2e/factories/.eslintrc.js | 17 + tests/e2e/factories/.gitignore | 17 + tests/e2e/factories/jest.config.js | 4 + tests/e2e/factories/package-lock.json | 4803 +++++++++++++++++++++++++ tests/e2e/factories/package.json | 30 + tests/e2e/factories/src/index.ts | 0 tests/e2e/factories/tsconfig.json | 13 + 9 files changed, 5528 insertions(+), 599 deletions(-) create mode 100644 tests/e2e/factories/.eslintrc.js create mode 100644 tests/e2e/factories/.gitignore create mode 100644 tests/e2e/factories/jest.config.js create mode 100644 tests/e2e/factories/package-lock.json create mode 100644 tests/e2e/factories/package.json create mode 100644 tests/e2e/factories/src/index.ts create mode 100644 tests/e2e/factories/tsconfig.json diff --git a/package-lock.json b/package-lock.json index 0d7f48c60b9..01f5749240a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "woocommerce", - "version": "4.1.0", + "version": "4.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2760,6 +2760,24 @@ "regenerator-runtime": "^0.13.2" } }, + "@babel/runtime-corejs3": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.2.tgz", + "integrity": "sha512-+a2M/u7r15o3dV1NEizr9bRi+KUVnrs/qYxF0Z06DAPx/4VCWaz1WA7EcbE+uqGgt39lp5akWGmHsTseIkHkHg==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, "@babel/template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", @@ -4614,6 +4632,12 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -4748,6 +4772,104 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.1.0.tgz", + "integrity": "sha512-D52KwdgkjYc+fmTZKW7CZpH5ZBJREJKZXRrveMiRCmlzZ+Rw9wRVJ1JAmHQ9b/+Ehy1ZeaylofDB9wwXUt83wg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "3.1.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz", + "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz", + "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@typescript-eslint/experimental-utils": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.26.0.tgz", @@ -4771,6 +4893,97 @@ } } }, + "@typescript-eslint/parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.1.0.tgz", + "integrity": "sha512-NcDSJK8qTA2tPfyGiPes9HtVKLbksmuYjlgGAUs7Ld2K0swdWibnCq9IJx9kJN8JJdgUJSorFiGaPHBgH81F/Q==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "3.1.0", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz", + "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz", + "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@typescript-eslint/typescript-estree": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.26.0.tgz", @@ -5056,6 +5269,49 @@ } } }, + "@wordpress/eslint-plugin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-6.1.0.tgz", + "integrity": "sha512-nxn/nxpXkgVsfT76OZAgAyHkc8qr64iJBO3Ytg004a7Db8N8y6qjjMhY6jSUDHExKelLh9FP1tPgWH+cnUV1/Q==", + "dev": true, + "requires": { + "@wordpress/prettier-config": "^0.2.0", + "babel-eslint": "^10.1.0", + "eslint-config-prettier": "^6.10.1", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-jsdoc": "^22.1.0", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-react": "^7.19.0", + "eslint-plugin-react-hooks": "^3.0.0", + "globals": "^12.0.0", + "prettier": "npm:wp-prettier@1.19.1", + "requireindex": "^1.2.0" + }, + "dependencies": { + "eslint-plugin-react-hooks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-3.0.0.tgz", + "integrity": "sha512-EjxTHxjLKIBWFgDJdhKKzLh5q+vjTFrqNZX36uIxWS4OfyXe5DawqPj3U5qeJ1ngLwatjzQnmR0Lz0J0YH3kxw==", + "dev": true + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "prettier": { + "version": "npm:wp-prettier@1.19.1", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-1.19.1.tgz", + "integrity": "sha512-mqAC2r1NDmRjG+z3KCJ/i61tycKlmADIjxnDhQab+KBxSAGbF/W7/zwB2guy/ypIeKrrftNsIYkNZZQKf3vJcg==", + "dev": true + } + } + }, "@wordpress/i18n": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.9.0.tgz", @@ -5115,6 +5371,12 @@ } } }, + "@wordpress/prettier-config": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-0.2.0.tgz", + "integrity": "sha512-v5H1dIDG9s2wASC8eah3hYRFuviPFNnflcAvHP7D7dOA6YPfPTCJDHeJ8CVKT+QBkNKkdueyYiR6YkxEVBj7iw==", + "dev": true + }, "@wordpress/url": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.12.0.tgz", @@ -5453,6 +5715,24 @@ } } }, + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -5483,6 +5763,17 @@ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -5575,6 +5866,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -5702,6 +5999,12 @@ "follow-redirects": "1.5.10" } }, + "axobject-query": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.2.tgz", + "integrity": "sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ==", + "dev": true + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -6578,12 +6881,6 @@ "inherits": "~2.0.0" } }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", @@ -7166,12 +7463,6 @@ "safe-buffer": "^5.0.1" } }, - "cjk-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cjk-regex/-/cjk-regex-1.0.2.tgz", - "integrity": "sha512-NwSMtwULPLk8Ka9DEUcoFXhMRnV/bpyKDnoyDiVw/Qy5przhvHTvXLcsKaOmx13o8J4XEsPVT1baoCUj5zQs3w==", - "dev": true - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -7477,6 +7768,12 @@ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true }, + "comment-parser": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.5.tgz", + "integrity": "sha512-iH9YA35ccw94nx5244GVkpyC9eVTsL71jZz6iz5w6RIf79JLF2AsXHXq9p6Oaohyl3sx5qSMnGsWUDFIAfWL4w==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -7599,6 +7896,12 @@ } } }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -7820,6 +8123,12 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -7829,12 +8138,6 @@ "assert-plus": "^1.0.0" } }, - "dashify": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz", - "integrity": "sha1-agdBWgHJH69KMuONnfunH2HLIP4=", - "dev": true - }, "data-urls": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", @@ -8233,42 +8536,6 @@ "safer-buffer": "^2.1.0" } }, - "editorconfig": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.14.2.tgz", - "integrity": "sha512-tghjvKwo1gakrhFiZWlbo5ILWAfnuOu1JFztW0li+vzbnInN0CMZuF4F0T/Pnn9UWpT7Mr1aFTWdHVuxiR9K9A==", - "dev": true, - "requires": { - "bluebird": "^3.0.5", - "commander": "^2.9.0", - "lru-cache": "^3.2.0", - "semver": "^5.1.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "lru-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", - "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", - "dev": true, - "requires": { - "pseudomap": "^1.0.1" - } - } - } - }, - "editorconfig-to-prettier": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.0.6.tgz", - "integrity": "sha512-Ysw+hBdwhPFruYmLapKRm7Or5XgMzhasbqu4AN07V2l/AkqpgooWm2xtTQPzTD6S0tq54A+WbSxNt6qmsO3hoA==", - "dev": true - }, "electron-to-chromium": { "version": "1.3.392", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.392.tgz", @@ -8561,6 +8828,23 @@ } } }, + "eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, "eslint-config-wpcalypso": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-config-wpcalypso/-/eslint-config-wpcalypso-5.0.0.tgz", @@ -8579,6 +8863,115 @@ "@typescript-eslint/experimental-utils": "^2.5.0" } }, + "eslint-plugin-jsdoc": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-22.2.0.tgz", + "integrity": "sha512-r8yRB6jGay9tJkx1BherKFtOkpDud086VZenUqZiZe0F7cD4OABhte0xcj3/7mXPuJbaou8WF3JzEtTdDnCzhA==", + "dev": true, + "requires": { + "comment-parser": "^0.7.2", + "debug": "^4.1.1", + "jsdoctypeparser": "^6.1.0", + "lodash": "^4.17.15", + "regextras": "^0.7.0", + "semver": "^6.3.0", + "spdx-expression-parse": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", + "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5", + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.1" + } + }, + "eslint-plugin-prettier": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz", + "integrity": "sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-react": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.0.tgz", + "integrity": "sha512-rqe1abd0vxMjmbPngo4NaYxTcR3Y4Hrmc/jg4T+sYz63yqlmJRknpEQfmWY+eDWPuMmix6iUIK+mv0zExjeLgA==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.3", + "object.entries": "^1.1.1", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.15.1", + "string.prototype.matchall": "^4.0.2", + "xregexp": "^4.3.0" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, "eslint-plugin-react-hooks": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.3.0.tgz", @@ -8951,6 +9344,12 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", @@ -8985,15 +9384,6 @@ "reusify": "^1.0.0" } }, - "fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "dev": true, - "requires": { - "format": "^0.2.0" - } - }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -9258,18 +9648,6 @@ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", - "dev": true - }, - "flow-parser": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.59.0.tgz", - "integrity": "sha1-9uvK5h/6GH5CCZnUDOCoAfObJjU=", - "dev": true - }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -9332,12 +9710,6 @@ "mime-types": "^2.1.12" } }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "dev": true - }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -10251,27 +10623,6 @@ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "globjoin": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", @@ -10312,15 +10663,6 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, - "graphql": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz", - "integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==", - "dev": true, - "requires": { - "iterall": "^1.1.0" - } - }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -11488,6 +11830,17 @@ } } }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + } + }, "interpret": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", @@ -11759,6 +12112,12 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-symbol": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", @@ -11981,12 +12340,6 @@ "handlebars": "^4.0.3" } }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", - "dev": true - }, "jest": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz", @@ -12616,15 +12969,6 @@ } } }, - "jest-docblock": { - "version": "21.3.0-beta.11", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.3.0-beta.11.tgz", - "integrity": "sha512-sxSwZUm7JyCO8dverup5g/OKJhjYRrBdgEdezIO1qAmMGWuza7ewovpfDmxp+JLvlm0i2WRFKUQNNIMGmPGTVg==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, "jest-each": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.1.0.tgz", @@ -12805,12 +13149,6 @@ } } }, - "jest-get-type": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", - "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", - "dev": true - }, "jest-haste-map": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", @@ -13795,18 +14133,6 @@ } } }, - "jest-validate": { - "version": "21.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.1.0.tgz", - "integrity": "sha512-xS0cyErNWpsLFlGkn/b87pk/Mv7J+mCTs8hQ4KmtOIIoM1sHYobXII8AtkoN8FC7E3+Ptxjo+/3xWk6LK1dKcw==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^21.0.2", - "leven": "^2.1.0", - "pretty-format": "^21.1.0" - } - }, "jest-watcher": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.1.0.tgz", @@ -13937,6 +14263,12 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "jsdoctypeparser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", + "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", + "dev": true + }, "jsdom": { "version": "15.2.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", @@ -14061,6 +14393,16 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.3.0.tgz", + "integrity": "sha512-3HNoc7nZ1hpZIKB3hJ7BlFRkzCx2BynRtfSwbkqZdpRdvAPsGMnzclPwrvDBS7/lalHTj21NwIeaEpysHBOudg==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "object.assign": "^4.1.0" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -14103,12 +14445,6 @@ "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", "dev": true }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, "levenary": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", @@ -14555,12 +14891,6 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", - "dev": true - }, "log-symbols": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", @@ -14818,15 +15148,6 @@ "unist-util-visit": "^1.1.0" } }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "memize": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/memize/-/memize-1.0.5.tgz", @@ -15649,6 +15970,56 @@ "object-keys": "^1.0.11" } }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } + } + }, + "object.fromentries": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", + "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "object.getownpropertydescriptors": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", @@ -15676,6 +16047,18 @@ } } }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -15946,15 +16329,6 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, - "parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -16006,21 +16380,6 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", @@ -16301,92 +16660,6 @@ "@babel/core": ">=7.2.2" } }, - "postcss-less": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-1.1.3.tgz", - "integrity": "sha512-WS0wsQxRm+kmN8wEYAGZ3t4lnoNfoyx9EJZrhiPR1K0lMHR0UNWnz52Ya5QRXChHtY75Ef+kDc05FpnBujebgw==", - "dev": true, - "requires": { - "postcss": "^5.2.16" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, "postcss-markdown": { "version": "0.36.0", "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", @@ -16451,48 +16724,6 @@ "postcss": "^7.0.21" } }, - "postcss-scss": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.2.tgz", - "integrity": "sha1-/0XPM1S4ee6JpOtoaA9GrJuxT5Q=", - "dev": true, - "requires": { - "postcss": "^6.0.3" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", - "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", - "dev": true, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "postcss-syntax": { "version": "0.36.2", "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", @@ -16505,17 +16736,6 @@ "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==", "dev": true }, - "postcss-values-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-1.3.1.tgz", - "integrity": "sha512-chFn9CnFAAUpQ3cwrxvVjKB8c0y6BfONv6eapndJoTXJ3h8fr1uAiue8lGP3rUIpBI2KgJGdgCVk9KNvXh0n6A==", - "dev": true, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -16523,163 +16743,18 @@ "dev": true }, "prettier": { - "version": "github:automattic/calypso-prettier#c56b42511ec98ba6d8f72b6c391e0a626e90f531", - "from": "github:automattic/calypso-prettier#c56b4251", + "version": "npm:wp-prettier@2.0.5", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.0.5.tgz", + "integrity": "sha512-5GCgdeevIXwR3cW4Qj5XWC5MO1iSCz8+IPn0mMw6awAt/PBiey8yyO7MhePRsaMqghJAhg6Q3QLYWSnUHWkG6A==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { - "babel-code-frame": "7.0.0-beta.3", - "babylon": "7.0.0-beta.34", - "camelcase": "4.1.0", - "chalk": "2.1.0", - "cjk-regex": "1.0.2", - "cosmiconfig": "3.1.0", - "dashify": "0.2.2", - "diff": "3.2.0", - "editorconfig": "0.14.2", - "editorconfig-to-prettier": "0.0.6", - "emoji-regex": "6.5.1", - "escape-string-regexp": "1.0.5", - "esutils": "2.0.2", - "flow-parser": "0.59.0", - "get-stream": "3.0.0", - "globby": "6.1.0", - "graphql": "0.10.5", - "ignore": "3.3.7", - "jest-docblock": "21.3.0-beta.11", - "jest-validate": "21.1.0", - "leven": "2.1.0", - "mem": "1.1.0", - "minimatch": "3.0.4", - "minimist": "1.2.0", - "parse5": "3.0.3", - "path-root": "0.1.1", - "postcss-less": "1.1.3", - "postcss-media-query-parser": "0.2.3", - "postcss-scss": "1.0.2", - "postcss-selector-parser": "2.2.3", - "postcss-values-parser": "1.3.1", - "remark-frontmatter": "1.1.0", - "remark-parse": "4.0.0", - "semver": "5.4.1", - "string-width": "2.1.1", - "typescript": "2.6.2", - "typescript-eslint-parser": "9.0.1", - "unicode-regex": "1.0.1", - "unified": "6.1.6" - }, - "dependencies": { - "babel-code-frame": { - "version": "7.0.0-beta.3", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-7.0.0-beta.3.tgz", - "integrity": "sha512-flMsJ9eSpShupt2Gwpka84DoMePvE4HlDObzdEc+1iNkacv3+NHlsJ7dMKmbnVA/AT22UhcGEBHwbJLoXWBO6Q==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^3.0.0" - } - }, - "babylon": { - "version": "7.0.0-beta.34", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.34.tgz", - "integrity": "sha512-ribEzWEhWKKjY+1FdKCryo+HiN/1idPjUB8vyR5Yf221MtGzCd5+7OwPvWvYHerHHC2eJLr6MhvumbTocXGY7Q==", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "cosmiconfig": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-3.1.0.tgz", - "integrity": "sha512-zedsBhLSbPBms+kE7AH4vHg6JsKDz6epSv2/+5XHs8ILHlgDciSJfSWf8sX9aQ52Jb7KI7VswUTsLpR/G0cr2Q==", - "dev": true, - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^3.0.0", - "require-from-string": "^2.0.1" - } - }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "emoji-regex": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", - "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "parse-json": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-3.0.0.tgz", - "integrity": "sha1-+m9HsY4jgm6tMvJj50TQ4ehH+xM=", - "dev": true, - "requires": { - "error-ex": "^1.3.1" - } - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } + "fast-diff": "^1.1.2" } }, "pretty-bytes": { @@ -16691,16 +16766,6 @@ "number-is-nan": "^1.0.0" } }, - "pretty-format": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", - "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" - } - }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -16741,6 +16806,17 @@ "sisteransi": "^1.0.3" } }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, "proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", @@ -18426,6 +18502,16 @@ "safe-regex": "^1.1.0" } }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -18446,6 +18532,12 @@ "unicode-match-property-value-ecmascript": "^1.2.0" } }, + "regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", + "dev": true + }, "regjsgen": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", @@ -18539,39 +18631,6 @@ } } }, - "remark-frontmatter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.1.0.tgz", - "integrity": "sha512-mLbYtwP9w1L9TA8dX+I/HyDF5lCpa0dmYvvW9Io+zUPpqEZ49QMKWb0hSpunpLVA+Squy0SowzSzjHVPbxWq1g==", - "dev": true, - "requires": { - "fault": "^1.0.1", - "xtend": "^4.0.1" - } - }, - "remark-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", - "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, "remark-stringify": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", @@ -18697,18 +18756,18 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "resolve": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", @@ -19385,11 +19444,15 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" + } }, "signal-exit": { "version": "3.0.2", @@ -19819,6 +19882,28 @@ } } }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } + } + }, "string.prototype.trimleft": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", @@ -21158,29 +21243,11 @@ } }, "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", "dev": true }, - "typescript-eslint-parser": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-9.0.1.tgz", - "integrity": "sha512-w1jqotvnhLtLukD9H3gQPAlbD0kLf7ZkoQGwiwSIshKIlzRL7i0OY9Y7VIdE1xtytZXThg678eomxMZ1rZXGVQ==", - "dev": true, - "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - } - } - }, "uglify-js": { "version": "3.5.11", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.11.tgz", @@ -21247,27 +21314,6 @@ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", "dev": true }, - "unicode-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-1.0.1.tgz", - "integrity": "sha1-+BngUBkdW5VhozmljdO5CV7ZSzU=", - "dev": true - }, - "unified": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.1.6.tgz", - "integrity": "sha512-pW2f82bCIo2ifuIGYcV12fL96kMMYgw7JKVEgh7ODlrM9rj6vXSY3BV+H6lCcv1ksxynFf582hwWLnA1qRFy4w==", - "dev": true, - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-function": "^1.0.4", - "x-is-string": "^0.1.0" - } - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -21605,18 +21651,6 @@ "extsprintf": "^1.2.0" } }, - "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", - "dev": true, - "requires": { - "is-buffer": "^1.1.4", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - }, "vfile-location": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.4.tgz", @@ -22432,12 +22466,6 @@ "async-limiter": "~1.0.0" } }, - "x-is-function": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz", - "integrity": "sha1-XSlNw9Joy90GJYDgxd93o5HR+h4=", - "dev": true - }, "x-is-string": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", @@ -22456,6 +22484,15 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "dev": true, + "requires": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index b57586e3d58..51a2ee8658f 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,11 @@ "@babel/preset-env": "7.9.0", "@babel/register": "7.9.0", "@jest/test-sequencer": "^25.0.0", + "@typescript-eslint/eslint-plugin": "3.1.0", + "@typescript-eslint/parser": "3.1.0", "@woocommerce/e2e-environment": "file:tests/e2e/env", "@wordpress/e2e-test-utils": "4.3.1", + "@wordpress/eslint-plugin": "6.1.0", "autoprefixer": "9.7.5", "babel-eslint": "10.1.0", "chai": "4.2.0", @@ -62,11 +65,12 @@ "lint-staged": "9.5.0", "mocha": "7.0.1", "node-sass": "4.13.0", - "prettier": "github:automattic/calypso-prettier#c56b4251", + "prettier": "npm:wp-prettier@^2.0.5", "puppeteer": "2.0.0", "puppeteer-utils": "github:Automattic/puppeteer-utils#0f3ec50", "stylelint": "12.0.1", "stylelint-config-wordpress": "16.0.0", + "typescript": "3.9.5", "webpack": "4.41.6", "webpack-cli": "3.3.11", "wp-textdomain": "^1.0.1" @@ -93,6 +97,10 @@ "*.js": [ "eslint --fix", "git add" + ], + "*.ts": [ + "eslint --fix", + "git add" ] }, "browserslist": [ diff --git a/tests/e2e/factories/.eslintrc.js b/tests/e2e/factories/.eslintrc.js new file mode 100644 index 00000000000..f1d8672afc1 --- /dev/null +++ b/tests/e2e/factories/.eslintrc.js @@ -0,0 +1,17 @@ +module.exports = { + parser: '@typescript-eslint/parser', + env: { + 'jest/globals': true + }, + ignorePatterns: [ + 'dist/', + 'node_modules/' + ], + rules: { + 'no-unused-vars': 'off', + }, + extends: [ + 'plugin:@wordpress/eslint-plugin/recommended', + 'plugin:jest/recommended' + ], +} diff --git a/tests/e2e/factories/.gitignore b/tests/e2e/factories/.gitignore new file mode 100644 index 00000000000..34dac168f2c --- /dev/null +++ b/tests/e2e/factories/.gitignore @@ -0,0 +1,17 @@ + +# Editors +project.xml +project.properties +/nbproject/private/ +.buildpath +.project +.settings* +.idea +.vscode +*.sublime-project +*.sublime-workspace +.sublimelinterrc + +# Build Artifacts +/node_modules/ +/dist/ diff --git a/tests/e2e/factories/jest.config.js b/tests/e2e/factories/jest.config.js new file mode 100644 index 00000000000..747559c9345 --- /dev/null +++ b/tests/e2e/factories/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'jsdom', +}; diff --git a/tests/e2e/factories/package-lock.json b/tests/e2e/factories/package-lock.json new file mode 100644 index 00000000000..d8190bc5df9 --- /dev/null +++ b/tests/e2e/factories/package-lock.json @@ -0,0 +1,4803 @@ +{ + "name": "@woocommerce/e2e-factories", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/core": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", + "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.2", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helpers": "^7.10.1", + "@babel/parser": "^7.10.2", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.2", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", + "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", + "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", + "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", + "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", + "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", + "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", + "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.1.tgz", + "integrity": "sha512-XyHIFa9kdrgJS91CUH+ccPVTnJShr8nLGc5bG2IhGXv5p1Rd+8BleGE5yzIg2Nc1QZAdHDa0Qp4m6066OL96Iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", + "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/traverse": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz", + "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/reporters": "^25.5.1", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^25.5.0", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-resolve-dependencies": "^25.5.4", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "jest-watcher": "^25.5.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "realpath-native": "^2.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + } + }, + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "dev": true, + "requires": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "dev": true, + "requires": { + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@types/babel__core": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", + "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", + "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz", + "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.1.tgz", + "integrity": "sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA==", + "dev": true, + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "@types/node": { + "version": "13.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz", + "integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "acorn": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "dev": true + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "dev": true, + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", + "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.2.tgz", + "integrity": "sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-25.5.4.tgz", + "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==", + "dev": true, + "requires": { + "@jest/core": "^25.5.4", + "import-local": "^3.0.2", + "jest-cli": "^25.5.4" + }, + "dependencies": { + "jest-cli": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz", + "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==", + "dev": true, + "requires": { + "@jest/core": "^25.5.4", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^25.5.4", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "prompts": "^2.0.1", + "realpath-native": "^2.0.0", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz", + "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "execa": "^3.2.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + } + }, + "jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", + "dev": true, + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" + } + }, + "jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "dev": true, + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "dev": true, + "requires": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "dev": true + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz", + "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-snapshot": "^25.5.1" + } + }, + "jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + } + }, + "jest-watcher": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz", + "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==", + "dev": true, + "requires": { + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "jest-util": "^25.5.0", + "string-length": "^3.1.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", + "shellwords": "^0.1.1", + "which": "^1.3.1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "dev": true, + "requires": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "requires": { + "xmlchars": "^2.1.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "ts-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.5.0.tgz", + "integrity": "sha512-govrjbOk1UEzcJ5cX5k8X8IUtFuP3lp3mrF3ZuKtCdAOQzdeCM7qualhb/U8s8SWFwEDutOqfF5PLkJ+oaYD4w==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "micromatch": "4.x", + "mkdirp": "0.x", + "semver": "6.x", + "yargs-parser": "18.x" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "dev": true + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/tests/e2e/factories/package.json b/tests/e2e/factories/package.json new file mode 100644 index 00000000000..7ebf5db34e8 --- /dev/null +++ b/tests/e2e/factories/package.json @@ -0,0 +1,30 @@ +{ + "name": "@woocommerce/e2e-factories", + "version": "0.1.0", + "author": "Automattic", + "description": "Factories for generating test data for use in WooCommerce End-To-End tests.", + "homepage": "https://github.com/woocommerce/woocommerce/tree/master/tests/e2e/factories/README.md", + "repository": { + "type": "git", + "url": "https://github.com/woocommerce/woocommerce.git" + }, + "keywords": [ + "woocommerce", + "e2e" + ], + "license": "GPL-3.0+", + "main": "dist/index.js", + "sideEffects": false, + "scripts": { + "build": "tsc", + "test": "jest" + }, + "dependencies": {}, + "devDependencies": { + "@types/jest": "25.2.1", + "@types/node": "13.13.5", + "jest": "25.5.4", + "ts-jest": "25.5.0", + "typescript": "3.8.3" + } +} diff --git a/tests/e2e/factories/src/index.ts b/tests/e2e/factories/src/index.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/e2e/factories/tsconfig.json b/tests/e2e/factories/tsconfig.json new file mode 100644 index 00000000000..7236f81e37b --- /dev/null +++ b/tests/e2e/factories/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "incremental": true, + "target": "es2015", + "module": "commonjs", + "types": [ "node", "jest" ], + "outDir": "dist", + "declaration": true, + "strict": true, + "esModuleInterop": true + }, + "include": [ "./src/**/*" ] +} From 7c7e17dcd0cc145e8bb2300ec38c54da129d2bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Demarle?= Date: Thu, 18 Jun 2020 14:12:00 +0200 Subject: [PATCH 259/440] add filter woocommerce_query_for_reserved_stock Remove previosuly proposed filter woocommerce_reserve_stock_for_products --- src/Checkout/Helpers/ReserveStock.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Checkout/Helpers/ReserveStock.php b/src/Checkout/Helpers/ReserveStock.php index 86395f1a8d9..25708b0f64d 100644 --- a/src/Checkout/Helpers/ReserveStock.php +++ b/src/Checkout/Helpers/ReserveStock.php @@ -76,17 +76,6 @@ final class ReserveStock { $rows[ $managed_by_id ] = isset( $rows[ $managed_by_id ] ) ? $rows[ $managed_by_id ] + $item->get_quantity() : $item->get_quantity(); } - /** - * Filter: woocommerce_reserve_stock_for_products - * Allows to filter the product ids and the quantity to reserve stock. - * - * @since 4.1.0 - * @param array $rows An array with ordered product id as key and quantity as value. - * @param \WC_Order $order Order object. - * @param int $minutes How long to reserve stock in minutes. - */ - $rows = apply_filters( 'woocommerce_reserve_stock_for_products', $rows, $order, $minutes ); - if ( ! empty( $rows ) ) { foreach ( $rows as $product_id => $quantity ) { $this->reserve_stock_for_product( $product_id, $quantity, $order, $minutes ); @@ -171,7 +160,7 @@ final class ReserveStock { */ private function get_query_for_reserved_stock( $product_id, $exclude_order_id = 0 ) { global $wpdb; - return $wpdb->prepare( + $query = $wpdb->prepare( " SELECT COALESCE( SUM( stock_table.`stock_quantity` ), 0 ) FROM $wpdb->wc_reserved_stock stock_table LEFT JOIN $wpdb->posts posts ON stock_table.`order_id` = posts.ID @@ -183,5 +172,16 @@ final class ReserveStock { $product_id, $exclude_order_id ); + + /** + * Filter: woocommerce_query_for_reserved_stock + * Allows to filter the query for getting reserved stock of a product. + * + * @since 4.3.0 + * @param string $query The query for getting reserved stock of a product. + * @param int $product_id Product ID. + * @param int $exclude_order_id Order to exclude from the results. + */ + return apply_filters( 'woocommerce_query_for_reserved_stock', $query, $product_id, $exclude_order_id ); } } From 5e15271f9588585460d952e63289809ef3c5b88b Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 18 Jun 2020 09:43:11 -0700 Subject: [PATCH 260/440] Excluded test files from the TypeScript build --- tests/e2e/factories/tsconfig.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/e2e/factories/tsconfig.json b/tests/e2e/factories/tsconfig.json index 7236f81e37b..60df497a1dd 100644 --- a/tests/e2e/factories/tsconfig.json +++ b/tests/e2e/factories/tsconfig.json @@ -9,5 +9,9 @@ "strict": true, "esModuleInterop": true }, - "include": [ "./src/**/*" ] + "include": [ "./src/**/*" ], + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts" + ] } From 9f1decd4c6e27efe9f7fe3dfc15704065777e753 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Fri, 19 Jun 2020 12:08:48 -0700 Subject: [PATCH 261/440] Added an interceptor to handle WooCommerce API authentication --- tests/e2e/factories/package-lock.json | 175 +++++++++++++++++- tests/e2e/factories/package.json | 11 +- .../src/http/api-auth-interceptor.spec.ts | 76 ++++++++ .../src/http/api-auth-interceptor.ts | 77 ++++++++ tests/e2e/factories/src/index.js | 0 tests/e2e/factories/tsconfig.build.json | 12 ++ tests/e2e/factories/tsconfig.json | 9 +- 7 files changed, 349 insertions(+), 11 deletions(-) create mode 100644 tests/e2e/factories/src/http/api-auth-interceptor.spec.ts create mode 100644 tests/e2e/factories/src/http/api-auth-interceptor.ts create mode 100644 tests/e2e/factories/src/index.js create mode 100644 tests/e2e/factories/tsconfig.build.json diff --git a/tests/e2e/factories/package-lock.json b/tests/e2e/factories/package-lock.json index d8190bc5df9..b2c8af6f674 100644 --- a/tests/e2e/factories/package-lock.json +++ b/tests/e2e/factories/package-lock.json @@ -711,6 +711,15 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/create-hmac": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/create-hmac/-/create-hmac-1.1.0.tgz", + "integrity": "sha512-BNYNdzdhOZZQWCOpwvIll3FSvgo3e55Y2M6s/jOY6TuOCwqt3cLmQsK4tSmJ5fayDot8EG4k3+hcZagfww9JlQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/graceful-fs": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", @@ -755,6 +764,15 @@ "pretty-format": "^25.2.1" } }, + "@types/moxios": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@types/moxios/-/moxios-0.4.9.tgz", + "integrity": "sha512-Sd1b24QRW2N194j2LEDPQAZK1h0TBtpN+2EIH+rERCgm38qm14JZwC7NlpE7n3jULhlCIPZBG8uNcbjF8KcCaQ==", + "dev": true, + "requires": { + "axios": "^0.19.0" + } + }, "@types/node": { "version": "13.13.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz", @@ -975,6 +993,14 @@ "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", "dev": true }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, "babel-jest": { "version": "25.5.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", @@ -1239,6 +1265,15 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -1363,6 +1398,31 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -1837,6 +1897,29 @@ "path-exists": "^4.0.0" } }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -2025,6 +2108,23 @@ } } }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", @@ -2101,8 +2201,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ip-regex": { "version": "2.1.0", @@ -3076,6 +3175,16 @@ "object-visit": "^1.0.0" } }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3158,6 +3267,12 @@ "minimist": "^1.2.5" } }, + "moxios": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/moxios/-/moxios-0.4.0.tgz", + "integrity": "sha1-/A2ixlR31yXKa5Z51YNw7QxS9Ts=", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3262,6 +3377,11 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "oauth-1.0a": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-2.2.6.tgz", + "integrity": "sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==" + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -3568,6 +3688,16 @@ "type-fest": "^0.8.1" } }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", @@ -3724,6 +3854,15 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -3733,8 +3872,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -3936,6 +4074,15 @@ } } }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -4276,6 +4423,21 @@ } } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -4578,6 +4740,11 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", diff --git a/tests/e2e/factories/package.json b/tests/e2e/factories/package.json index 7ebf5db34e8..a731c271a4b 100644 --- a/tests/e2e/factories/package.json +++ b/tests/e2e/factories/package.json @@ -16,14 +16,21 @@ "main": "dist/index.js", "sideEffects": false, "scripts": { - "build": "tsc", + "build": "tsc -p tsconfig.build.json", "test": "jest" }, - "dependencies": {}, + "dependencies": { + "axios": "0.19.2", + "create-hmac": "1.1.7", + "oauth-1.0a": "2.2.6" + }, "devDependencies": { + "@types/create-hmac": "1.1.0", "@types/jest": "25.2.1", + "@types/moxios": "0.4.9", "@types/node": "13.13.5", "jest": "25.5.4", + "moxios": "0.4.0", "ts-jest": "25.5.0", "typescript": "3.8.3" } diff --git a/tests/e2e/factories/src/http/api-auth-interceptor.spec.ts b/tests/e2e/factories/src/http/api-auth-interceptor.spec.ts new file mode 100644 index 00000000000..18bb0eb5a15 --- /dev/null +++ b/tests/e2e/factories/src/http/api-auth-interceptor.spec.ts @@ -0,0 +1,76 @@ +import axios, { AxiosInstance } from 'axios'; +import moxios from 'moxios'; +import { APIAuthInterceptor } from './api-auth-interceptor'; + +describe( 'APIAuthInterceptor', () => { + let apiAuthInterceptor: APIAuthInterceptor; + let axiosInstance: AxiosInstance; + + beforeEach( () => { + axiosInstance = axios.create(); + moxios.install( axiosInstance ); + apiAuthInterceptor = new APIAuthInterceptor( + axiosInstance, + 'consumer_key', + 'consumer_secret' + ); + apiAuthInterceptor.start(); + } ); + + afterEach( () => { + apiAuthInterceptor.stop(); + moxios.uninstall( axiosInstance ); + } ); + + it( 'should not run unless started', async () => { + moxios.stubRequest( 'https://api.test', { status: 200 } ); + + apiAuthInterceptor.stop(); + await axiosInstance.get( 'https://api.test' ); + + let request = moxios.requests.mostRecent(); + expect( request.headers ).not.toHaveProperty( 'Authorization' ); + + apiAuthInterceptor.start(); + await axiosInstance.get( 'https://api.test' ); + + request = moxios.requests.mostRecent(); + expect( request.headers ).toHaveProperty( 'Authorization' ); + } ); + + it( 'should use basic auth for HTTPS', async () => { + moxios.stubRequest( 'https://api.test', { status: 200 } ); + await axiosInstance.get( 'https://api.test' ); + + const request = moxios.requests.mostRecent(); + + expect( request.headers ).toHaveProperty( 'Authorization' ); + expect( request.headers.Authorization ).toEqual( + 'Basic ' + btoa( 'consumer_key:consumer_secret' ) + ); + } ); + + it( 'should use OAuth 1.0a for HTTP', async () => { + moxios.stubRequest( 'http://api.test', { status: 200 } ); + await axiosInstance.get( 'http://api.test' ); + + const request = moxios.requests.mostRecent(); + + expect( request.headers ).toHaveProperty( 'Authorization' ); + expect( request.headers.Authorization ).toMatch( /^OAuth / ); + const header = request.headers.Authorization; + + // We're going to assume that the oauth-1.0a package added the signature data correctly so we will + // focus on ensuring that the header looks roughly correct given what we readily know. + const oauthArgs: any = {}; + for ( const arg of header.matchAll( /([A-Za-z0-9_]+)="([^"]+)"/g ) ) { + oauthArgs[ arg[ 1 ] ] = arg[ 2 ]; + } + + expect( oauthArgs ).toMatchObject( { + oauth_consumer_key: 'consumer_key', + oauth_signature_method: 'HMAC-SHA256', + oauth_version: '1.0', + } ); + } ); +} ); diff --git a/tests/e2e/factories/src/http/api-auth-interceptor.ts b/tests/e2e/factories/src/http/api-auth-interceptor.ts new file mode 100644 index 00000000000..7a6ff2cc8a7 --- /dev/null +++ b/tests/e2e/factories/src/http/api-auth-interceptor.ts @@ -0,0 +1,77 @@ +import { AxiosInstance, AxiosRequestConfig } from 'axios'; +import createHmac from 'create-hmac'; +import OAuth from 'oauth-1.0a'; + +/** + * A utility class for managing the lifecycle of an authentication interceptor. + */ +export class APIAuthInterceptor { + private readonly client: AxiosInstance; + private interceptorID: number | null; + private oauth: OAuth; + + public constructor( + client: AxiosInstance, + consumerKey: string, + consumerSecret: string + ) { + this.client = client; + this.interceptorID = null; + this.oauth = new OAuth( { + consumer: { + key: consumerKey, + secret: consumerSecret, + }, + signature_method: 'HMAC-SHA256', + hash_function: ( base: any, key: any ) => { + return createHmac( 'sha256', key ) + .update( base ) + .digest( 'base64' ); + }, + } ); + } + + /** + * Starts adding WooCommerce API authentication details to requests made using the contained client. + */ + public start(): void { + if ( null === this.interceptorID ) { + this.interceptorID = this.client.interceptors.request.use( + ( request ) => this.handleRequest( request ) + ); + } + } + + /** + * Stops adding WooCommerce API authentication details to requests made using the contained client. + */ + public stop(): void { + if ( null !== this.interceptorID ) { + this.client.interceptors.request.eject( this.interceptorID ); + this.interceptorID = null; + } + } + + /** + * Adds WooCommerce API authentication details to the outgoing request. + * + * @param {AxiosRequestConfig} request + */ + protected handleRequest( request: AxiosRequestConfig ): AxiosRequestConfig { + if ( request.url!.startsWith( 'https' ) ) { + request.auth = { + username: this.oauth.consumer.key, + password: this.oauth.consumer.secret, + }; + } else { + request.headers.Authorization = this.oauth.toHeader( + this.oauth.authorize( { + url: request.url!, + method: request.method!, + } ) + ).Authorization; + } + + return request; + } +} diff --git a/tests/e2e/factories/src/index.js b/tests/e2e/factories/src/index.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/e2e/factories/tsconfig.build.json b/tests/e2e/factories/tsconfig.build.json new file mode 100644 index 00000000000..abc2742f81f --- /dev/null +++ b/tests/e2e/factories/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "incremental": true, + "noEmit": false + }, + "exclude": [ + "node_modules", + "**/*.spec.ts", + "**/*.test.ts" + ] +} diff --git a/tests/e2e/factories/tsconfig.json b/tests/e2e/factories/tsconfig.json index 60df497a1dd..0bb65499684 100644 --- a/tests/e2e/factories/tsconfig.json +++ b/tests/e2e/factories/tsconfig.json @@ -1,17 +1,16 @@ { "compilerOptions": { - "incremental": true, "target": "es2015", "module": "commonjs", - "types": [ "node", "jest" ], + "types": [ "node", "jest", "axios", "moxios", "create-hmac" ], "outDir": "dist", "declaration": true, "strict": true, - "esModuleInterop": true + "esModuleInterop": true, + "noEmit": true }, "include": [ "./src/**/*" ], "exclude": [ - "**/*.spec.ts", - "**/*.test.ts" + "node_modules" ] } From 2a3b1b37804c8a85ab93895ecb329aac4121f99b Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Sat, 20 Jun 2020 17:40:50 -0700 Subject: [PATCH 262/440] Adjusted the package to better support NPM distribution --- tests/e2e/factories/package.json | 9 +++++++++ tests/e2e/factories/tsconfig.build.json | 12 ------------ tests/e2e/factories/tsconfig.json | 6 +++--- 3 files changed, 12 insertions(+), 15 deletions(-) delete mode 100644 tests/e2e/factories/tsconfig.build.json diff --git a/tests/e2e/factories/package.json b/tests/e2e/factories/package.json index a731c271a4b..133406dea02 100644 --- a/tests/e2e/factories/package.json +++ b/tests/e2e/factories/package.json @@ -14,6 +14,15 @@ ], "license": "GPL-3.0+", "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "/dist/", + "!*.tsbuildinfo", + "!*.spec.js", + "!*.spec.d.ts", + "!*.test.js", + "!*.test.d.ts" + ], "sideEffects": false, "scripts": { "build": "tsc -p tsconfig.build.json", diff --git a/tests/e2e/factories/tsconfig.build.json b/tests/e2e/factories/tsconfig.build.json deleted file mode 100644 index abc2742f81f..00000000000 --- a/tests/e2e/factories/tsconfig.build.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "incremental": true, - "noEmit": false - }, - "exclude": [ - "node_modules", - "**/*.spec.ts", - "**/*.test.ts" - ] -} diff --git a/tests/e2e/factories/tsconfig.json b/tests/e2e/factories/tsconfig.json index 0bb65499684..092b080ffe2 100644 --- a/tests/e2e/factories/tsconfig.json +++ b/tests/e2e/factories/tsconfig.json @@ -1,13 +1,13 @@ { "compilerOptions": { - "target": "es2015", + "incremental": true, + "target": "es5", "module": "commonjs", "types": [ "node", "jest", "axios", "moxios", "create-hmac" ], "outDir": "dist", "declaration": true, "strict": true, - "esModuleInterop": true, - "noEmit": true + "esModuleInterop": true }, "include": [ "./src/**/*" ], "exclude": [ From dd74c3db459db6e2959d9c88d1c0dc8d0423a8b5 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Sat, 20 Jun 2020 18:46:59 -0700 Subject: [PATCH 263/440] Removed build artifact --- tests/e2e/factories/src/index.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/e2e/factories/src/index.js diff --git a/tests/e2e/factories/src/index.js b/tests/e2e/factories/src/index.js deleted file mode 100644 index e69de29bb2d..00000000000 From 323d06744cba2c18616468271b767c0dfc188591 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Mon, 22 Jun 2020 12:10:45 -0700 Subject: [PATCH 264/440] Adjusted the APIAuthInterceptor to be more explicitly Axios-specific --- tests/e2e/factories/.eslintignore | 8 ++++++++ tests/e2e/factories/.eslintrc.js | 3 +++ tests/e2e/factories/jest.config.js | 1 + .../{ => axios}/api-auth-interceptor.spec.ts | 18 ++++-------------- .../http/{ => axios}/api-auth-interceptor.ts | 5 +++-- 5 files changed, 19 insertions(+), 16 deletions(-) create mode 100644 tests/e2e/factories/.eslintignore rename tests/e2e/factories/src/http/{ => axios}/api-auth-interceptor.spec.ts (82%) rename tests/e2e/factories/src/http/{ => axios}/api-auth-interceptor.ts (88%) diff --git a/tests/e2e/factories/.eslintignore b/tests/e2e/factories/.eslintignore new file mode 100644 index 00000000000..25bd998eae8 --- /dev/null +++ b/tests/e2e/factories/.eslintignore @@ -0,0 +1,8 @@ +/dist/ +/node_modules +.eslintrc.js +.gitignore +jest.config.js +package.json +package-lock.json +tsconfig.json diff --git a/tests/e2e/factories/.eslintrc.js b/tests/e2e/factories/.eslintrc.js index f1d8672afc1..bfefabe0d83 100644 --- a/tests/e2e/factories/.eslintrc.js +++ b/tests/e2e/factories/.eslintrc.js @@ -14,4 +14,7 @@ module.exports = { 'plugin:@wordpress/eslint-plugin/recommended', 'plugin:jest/recommended' ], + overrides: [ + { "files": [ '**/*.ts' ] } + ] } diff --git a/tests/e2e/factories/jest.config.js b/tests/e2e/factories/jest.config.js index 747559c9345..208afea0cbf 100644 --- a/tests/e2e/factories/jest.config.js +++ b/tests/e2e/factories/jest.config.js @@ -1,4 +1,5 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'jsdom', + testPathIgnorePatterns: [ '/node_modules/', '/dist/' ], }; diff --git a/tests/e2e/factories/src/http/api-auth-interceptor.spec.ts b/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts similarity index 82% rename from tests/e2e/factories/src/http/api-auth-interceptor.spec.ts rename to tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts index 18bb0eb5a15..2792f931d0e 100644 --- a/tests/e2e/factories/src/http/api-auth-interceptor.spec.ts +++ b/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts @@ -56,21 +56,11 @@ describe( 'APIAuthInterceptor', () => { const request = moxios.requests.mostRecent(); - expect( request.headers ).toHaveProperty( 'Authorization' ); - expect( request.headers.Authorization ).toMatch( /^OAuth / ); - const header = request.headers.Authorization; - // We're going to assume that the oauth-1.0a package added the signature data correctly so we will // focus on ensuring that the header looks roughly correct given what we readily know. - const oauthArgs: any = {}; - for ( const arg of header.matchAll( /([A-Za-z0-9_]+)="([^"]+)"/g ) ) { - oauthArgs[ arg[ 1 ] ] = arg[ 2 ]; - } - - expect( oauthArgs ).toMatchObject( { - oauth_consumer_key: 'consumer_key', - oauth_signature_method: 'HMAC-SHA256', - oauth_version: '1.0', - } ); + expect( request.headers ).toHaveProperty( 'Authorization' ); + expect( request.headers.Authorization ).toMatch( + /^OAuth oauth_consumer_key="consumer_key".*oauth_signature_method="HMAC-SHA256".*oauth_version="1.0"/ + ); } ); } ); diff --git a/tests/e2e/factories/src/http/api-auth-interceptor.ts b/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts similarity index 88% rename from tests/e2e/factories/src/http/api-auth-interceptor.ts rename to tests/e2e/factories/src/http/axios/api-auth-interceptor.ts index 7a6ff2cc8a7..2b9f44b4a55 100644 --- a/tests/e2e/factories/src/http/api-auth-interceptor.ts +++ b/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts @@ -55,9 +55,10 @@ export class APIAuthInterceptor { /** * Adds WooCommerce API authentication details to the outgoing request. * - * @param {AxiosRequestConfig} request + * @param {AxiosRequestConfig} request The request that was intercepted. + * @return {AxiosRequestConfig} The request with the additional authorization headers. */ - protected handleRequest( request: AxiosRequestConfig ): AxiosRequestConfig { + private handleRequest( request: AxiosRequestConfig ): AxiosRequestConfig { if ( request.url!.startsWith( 'https' ) ) { request.auth = { username: this.oauth.consumer.key, From 031bb6593ff07d151fab2db302e196d09127541c Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 23 Jun 2020 11:53:00 -0700 Subject: [PATCH 265/440] Fixed the usage of baseURL with the APIAuthInterceptor --- .../http/axios/api-auth-interceptor.spec.ts | 22 ++++++++++++++++--- .../src/http/axios/api-auth-interceptor.ts | 5 +++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts b/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts index 2792f931d0e..f7722e0ccbf 100644 --- a/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts +++ b/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts @@ -23,7 +23,7 @@ describe( 'APIAuthInterceptor', () => { } ); it( 'should not run unless started', async () => { - moxios.stubRequest( 'https://api.test', { status: 200 } ); + moxios.stubOnce( 'GET', 'https://api.test', { status: 200 } ); apiAuthInterceptor.stop(); await axiosInstance.get( 'https://api.test' ); @@ -39,7 +39,7 @@ describe( 'APIAuthInterceptor', () => { } ); it( 'should use basic auth for HTTPS', async () => { - moxios.stubRequest( 'https://api.test', { status: 200 } ); + moxios.stubOnce( 'GET', 'https://api.test', { status: 200 } ); await axiosInstance.get( 'https://api.test' ); const request = moxios.requests.mostRecent(); @@ -51,7 +51,7 @@ describe( 'APIAuthInterceptor', () => { } ); it( 'should use OAuth 1.0a for HTTP', async () => { - moxios.stubRequest( 'http://api.test', { status: 200 } ); + moxios.stubOnce( 'GET', 'http://api.test', { status: 200 } ); await axiosInstance.get( 'http://api.test' ); const request = moxios.requests.mostRecent(); @@ -63,4 +63,20 @@ describe( 'APIAuthInterceptor', () => { /^OAuth oauth_consumer_key="consumer_key".*oauth_signature_method="HMAC-SHA256".*oauth_version="1.0"/ ); } ); + + it( 'should work with base URL', async () => { + moxios.stubOnce( 'GET', '/test', { status: 200 } ); + await axiosInstance.request( { + method: 'GET', + baseURL: 'https://api.test/', + url: '/test', + } ); + + const request = moxios.requests.mostRecent(); + + expect( request.headers ).toHaveProperty( 'Authorization' ); + expect( request.headers.Authorization ).toEqual( + 'Basic ' + btoa( 'consumer_key:consumer_secret' ) + ); + } ); } ); diff --git a/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts b/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts index 2b9f44b4a55..63e453e7e06 100644 --- a/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts +++ b/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts @@ -59,7 +59,8 @@ export class APIAuthInterceptor { * @return {AxiosRequestConfig} The request with the additional authorization headers. */ private handleRequest( request: AxiosRequestConfig ): AxiosRequestConfig { - if ( request.url!.startsWith( 'https' ) ) { + const url = request.baseURL || '' + request.url || ''; + if ( url.startsWith( 'https' ) ) { request.auth = { username: this.oauth.consumer.key, password: this.oauth.consumer.secret, @@ -67,7 +68,7 @@ export class APIAuthInterceptor { } else { request.headers.Authorization = this.oauth.toHeader( this.oauth.authorize( { - url: request.url!, + url, method: request.method!, } ) ).Authorization; From 9908a84d0e24e74f93fc21d8845f4ecc25cc1a53 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 23 Jun 2020 11:58:06 -0700 Subject: [PATCH 266/440] Added a service for interacting with the WordPress API We've hid the use of Axios behind a service so that we're able to easily mock it out in factories as well as handle the creation and configuration of the client. This will make it easier on consumers in that they won't have to worry about things like authentication when using the API. --- tests/e2e/factories/src/http/api-service.ts | 95 ++++++++++ .../src/http/axios/axios-api-service.spec.ts | 66 +++++++ .../src/http/axios/axios-api-service.ts | 178 ++++++++++++++++++ tests/e2e/factories/tsconfig.json | 5 +- 4 files changed, 340 insertions(+), 4 deletions(-) create mode 100644 tests/e2e/factories/src/http/api-service.ts create mode 100644 tests/e2e/factories/src/http/axios/axios-api-service.spec.ts create mode 100644 tests/e2e/factories/src/http/axios/axios-api-service.ts diff --git a/tests/e2e/factories/src/http/api-service.ts b/tests/e2e/factories/src/http/api-service.ts new file mode 100644 index 00000000000..28477006918 --- /dev/null +++ b/tests/e2e/factories/src/http/api-service.ts @@ -0,0 +1,95 @@ +/** + * A structured response from the API. + */ +export class APIResponse< T = any > { + public readonly status: number; + public readonly headers: any; + public readonly data: T | null; + + public constructor( status: number, headers: any, data: T | null ) { + this.status = status; + this.headers = headers; + this.data = data; + } +} + +/** + * A structured error from the API. + */ +export class APIError< T = any > extends Error { + public readonly response: APIResponse< T > | null; + + public constructor( + response: APIResponse< T > | null, + message: string | null + ) { + super( message || 'An error has been returned by the API.' ); + + this.response = response; + } +} + +/** + * An interface for implementing services to make calls against the API. + */ +export interface APIService { + /** + * Performs a GET request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} params Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and rejects an APIError. + */ + get< T >( + endpoint: string, + params?: any + ): Promise< APIResponse< T > | APIError< T > >; + + /** + * Performs a POST request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} data Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and rejects an APIError. + */ + post< T >( + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > >; + + /** + * Performs a PUT request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} data Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and rejects an APIError. + */ + put< T >( + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > >; + + /** + * Performs a PATCH request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} data Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and rejects an APIError. + */ + patch< T >( + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > >; + + /** + * Performs a DELETE request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} params Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and rejects an APIError. + */ + delete< T >( + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > >; +} diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts b/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts new file mode 100644 index 00000000000..9183d416444 --- /dev/null +++ b/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts @@ -0,0 +1,66 @@ +import axios, { AxiosInstance } from 'axios'; +import moxios from 'moxios'; +import { APIResponse, APIError } from './../api-service'; +import { AxiosAPIService } from './axios-api-service'; + +describe( 'AxiosAPIService', () => { + let apiClient: AxiosAPIService; + + beforeEach( () => { + moxios.install(); + apiClient = new AxiosAPIService( + 'https://test.test/wp-json/', + 'consumer_key', + 'consumer_secret' + ); + } ); + + afterEach( () => { + moxios.uninstall(); + } ); + + it( 'should transform responses into APIResponse', async () => { + moxios.stubOnce( 'GET', '/wc/v2/product', { + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + responseText: JSON.stringify( { test: 'value' } ), + } ); + + const response = await apiClient.request( 'GET', '/wc/v2/product' ); + + expect( response ).toMatchObject( { + status: 200, + headers: { + 'content-type': 'application/json', + }, + data: { + test: 'value', + }, + } ); + } ); + + it( 'should transform response errors into APIError', async () => { + moxios.stubOnce( 'GET', '/wc/v2/product', { + status: 404, + headers: { + 'Content-Type': 'application/json', + }, + responseText: JSON.stringify( { message: 'value' } ), + } ); + + await apiClient.request( 'GET', '/wc/v2/product' ).catch( ( error ) => { + expect( error ).toMatchObject( + new APIError( + new APIResponse( + 404, + { 'content-type': 'application/json' }, + { message: 'value' } + ), + null + ) + ); + } ); + } ); +} ); diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.ts b/tests/e2e/factories/src/http/axios/axios-api-service.ts new file mode 100644 index 00000000000..8c3fdf65fb3 --- /dev/null +++ b/tests/e2e/factories/src/http/axios/axios-api-service.ts @@ -0,0 +1,178 @@ +import { APIResponse, APIError, APIService } from '../api-service'; +import { APIAuthInterceptor } from './api-auth-interceptor'; +import axios, { + AxiosInstance, + AxiosTransformer, + AxiosResponse, + AxiosError, + Method, + AxiosRequestConfig, +} from 'axios'; + +/** + * An API service implementation that uses Axios to make requests to the WordPress API. + */ +export class AxiosAPIService implements APIService { + private client: AxiosInstance; + private authInterceptor: APIAuthInterceptor; + + public constructor( + baseAPIURL: string, + consumerKey: string, + consumerSecret: string + ) { + this.client = axios.create( { + baseURL: baseAPIURL, + } ); + this.authInterceptor = new APIAuthInterceptor( + this.client, + consumerKey, + consumerSecret + ); + this.authInterceptor.start(); + } + + /** + * Performs a GET request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} params Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and rejects an APIError. + */ + public get< T >( + endpoint: string, + params?: any + ): Promise< APIResponse< T > | APIError< T > > { + return this.request( 'GET', endpoint, params ); + } + + /** + * Performs a POST request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} data Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and throws an APIError. + */ + public post< T >( + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > > { + return this.request( 'POST', endpoint, data ); + } + + /** + * Performs a PUT request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} data Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and throws an APIError. + */ + public put< T >( + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > > { + return this.request( 'PUT', endpoint, data ); + } + + /** + * Performs a PATCH request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} data Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and throws an APIError. + */ + public patch< T >( + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > > { + return this.request( 'PATCH', endpoint, data ); + } + + /** + * Performs a DELETE request against the WordPress API. + * + * @param {string} endpoint The API endpoint we should query. + * @param {*} data Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and throws an APIError. + */ + public delete< T >( + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > > { + return this.request( 'DELETE', endpoint, data ); + } + + /** + * Performs an HTTP request against the WordPress API. + * + * @param {string} method The HTTP method we should use in the request. + * @param {string} endpoint The API endpoint we should query. + * @param {*} data Any parameters that should be passed in the request. + * @return {Promise} Resolves to an APIResponse and throws an APIError. + */ + public request< T >( + method: Method, + endpoint: string, + data?: any + ): Promise< APIResponse< T > | APIError< T > > { + const config: AxiosRequestConfig = { + method, + url: endpoint, + }; + if ( data ) { + if ( 'GET' === method ) { + config.params = data; + } else { + config.data = data; + } + } + + return this.client.request( config ).then( + ( response ) => this.onFulfilled< T >( response ), + ( error ) => this.onRejected< T >( error ) + ); + } + + /** + * Transforms the Axios response into our API response to be consumed in a consistent manner. + * + * @param {AxiosResponse} response The respons ethat we need to transform. + * @return {Promise} A promise containing the APIResponse. + */ + private onFulfilled< T >( + response: AxiosResponse + ): Promise< APIResponse< T > > { + return Promise.resolve< APIResponse< T > >( + new APIResponse< T >( + response.status, + response.headers, + response.data + ) + ); + } + + /** + * Transforms the Axios error into our API error to be consumed in a consistent manner. + * + * @param {*} error The error + * @return {Promise} A promise containing the APIError. + */ + private onRejected< T >( error: any ): Promise< APIError< T > > { + let apiResponse: APIResponse< T > | null = null; + let message: string | null = null; + if ( error.response ) { + apiResponse = new APIResponse< T >( + error.response.status, + error.response.headers, + error.response.data + ); + } else if ( error.request ) { + message = 'No response was received from the server.'; + } else { + // Keep bubbling up the errors that we aren't handling. + throw error; + } + + return Promise.reject( new APIError< T >( apiResponse, message ) ); + } +} diff --git a/tests/e2e/factories/tsconfig.json b/tests/e2e/factories/tsconfig.json index 092b080ffe2..4379bfd36b5 100644 --- a/tests/e2e/factories/tsconfig.json +++ b/tests/e2e/factories/tsconfig.json @@ -9,8 +9,5 @@ "strict": true, "esModuleInterop": true }, - "include": [ "./src/**/*" ], - "exclude": [ - "node_modules" - ] + "include": [ "./src/**/*" ] } From 2869867e359da368dda1635270f03db228f2d92a Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 24 Jun 2020 13:08:08 -0300 Subject: [PATCH 267/440] Updated since tag --- src/Checkout/Helpers/ReserveStock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Checkout/Helpers/ReserveStock.php b/src/Checkout/Helpers/ReserveStock.php index 25708b0f64d..651fa739834 100644 --- a/src/Checkout/Helpers/ReserveStock.php +++ b/src/Checkout/Helpers/ReserveStock.php @@ -177,7 +177,7 @@ final class ReserveStock { * Filter: woocommerce_query_for_reserved_stock * Allows to filter the query for getting reserved stock of a product. * - * @since 4.3.0 + * @since 4.4.0 * @param string $query The query for getting reserved stock of a product. * @param int $product_id Product ID. * @param int $exclude_order_id Order to exclude from the results. From 4e02ce7afd967ecc4792b43cd9bedc7dd9f39d3d Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 24 Jun 2020 11:35:04 -0700 Subject: [PATCH 268/440] Moved the Axios response/error transformations into an interceptor --- .../axios/api-response-interceptor.spec.ts | 66 ++++++++++++++ .../http/axios/api-response-interceptor.ts | 72 +++++++++++++++ .../src/http/axios/axios-api-service.spec.ts | 39 ++------ .../src/http/axios/axios-api-service.ts | 88 ++----------------- 4 files changed, 152 insertions(+), 113 deletions(-) create mode 100644 tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts create mode 100644 tests/e2e/factories/src/http/axios/api-response-interceptor.ts diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts b/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts new file mode 100644 index 00000000000..f883fc099ca --- /dev/null +++ b/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts @@ -0,0 +1,66 @@ +import axios, { AxiosInstance } from 'axios'; +import moxios from 'moxios'; +import { APIResponse, APIError } from './../api-service'; +import { APIResponseInterceptor } from './api-response-interceptor'; + +describe( 'APIResponseInterceptor', () => { + let apiResponseInterceptor: APIResponseInterceptor; + let axiosInstance: AxiosInstance; + + beforeEach( () => { + axiosInstance = axios.create(); + moxios.install( axiosInstance ); + apiResponseInterceptor = new APIResponseInterceptor( axiosInstance ); + apiResponseInterceptor.start(); + } ); + + afterEach( () => { + apiResponseInterceptor.stop(); + moxios.uninstall(); + } ); + + it( 'should transform responses into APIResponse', async () => { + moxios.stubOnce( 'GET', 'http://test.test', { + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + responseText: JSON.stringify( { test: 'value' } ), + } ); + + const response = await axiosInstance.get( 'http://test.test' ); + + expect( response ).toMatchObject( { + status: 200, + headers: { + 'content-type': 'application/json', + }, + data: { + test: 'value', + }, + } ); + } ); + + it( 'should transform response errors into APIError', async () => { + moxios.stubOnce( 'GET', 'http://test.test', { + status: 404, + headers: { + 'Content-Type': 'application/json', + }, + responseText: JSON.stringify( { message: 'value' } ), + } ); + + await axiosInstance.get( 'http://test.test' ).catch( ( error ) => { + expect( error ).toMatchObject( + new APIError( + new APIResponse( + 404, + { 'content-type': 'application/json' }, + { message: 'value' } + ), + null + ) + ); + } ); + } ); +} ); diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.ts b/tests/e2e/factories/src/http/axios/api-response-interceptor.ts new file mode 100644 index 00000000000..d75c27dea7f --- /dev/null +++ b/tests/e2e/factories/src/http/axios/api-response-interceptor.ts @@ -0,0 +1,72 @@ +import { AxiosInstance, AxiosResponse } from 'axios'; +import { APIError, APIResponse } from '../api-service'; + +export class APIResponseInterceptor { + private readonly client: AxiosInstance; + private interceptorID: number | null; + + public constructor( client: AxiosInstance ) { + this.client = client; + this.interceptorID = null; + } + + /** + * Starts transforming the response and errors into a consistent format. + */ + public start(): void { + if ( null === this.interceptorID ) { + this.interceptorID = this.client.interceptors.response.use( + // @ts-ignore: We WANT to change the type of response returned. + ( response ) => this.onFulfilled( response ), + ( error: any ) => this.onRejected( error ) + ); + } + } + + /** + * Stops transforming the response and errors into a consistent format. + */ + public stop(): void { + if ( null !== this.interceptorID ) { + this.client.interceptors.response.eject( this.interceptorID ); + this.interceptorID = null; + } + } + + /** + * Transforms the Axios response into our API response to be consumed in a consistent manner. + * + * @param {AxiosResponse} response The respons ethat we need to transform. + * @return {Promise} A promise containing the APIResponse. + */ + private onFulfilled( response: AxiosResponse ): Promise< APIResponse > { + return Promise.resolve< APIResponse >( + new APIResponse( response.status, response.headers, response.data ) + ); + } + + /** + * Transforms the Axios error into our API error to be consumed in a consistent manner. + * + * @param {*} error The error + * @return {Promise} A promise containing the APIError. + */ + private onRejected( error: any ): Promise< APIError > { + let apiResponse: APIResponse | null = null; + let message: string | null = null; + if ( error.response ) { + apiResponse = new APIResponse( + error.response.status, + error.response.headers, + error.response.data + ); + } else if ( error.request ) { + message = 'No response was received from the server.'; + } else { + // Keep bubbling up the errors that we aren't handling. + throw error; + } + + return Promise.reject( new APIError( apiResponse, message ) ); + } +} diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts b/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts index 9183d416444..da1a3729a3d 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts +++ b/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts @@ -19,7 +19,7 @@ describe( 'AxiosAPIService', () => { moxios.uninstall(); } ); - it( 'should transform responses into APIResponse', async () => { + it( 'should add interceptors', async () => { moxios.stubOnce( 'GET', '/wc/v2/product', { status: 200, headers: { @@ -28,39 +28,10 @@ describe( 'AxiosAPIService', () => { responseText: JSON.stringify( { test: 'value' } ), } ); - const response = await apiClient.request( 'GET', '/wc/v2/product' ); + const response = await apiClient.get( '/wc/v2/product' ); + expect( response ).toBeInstanceOf( APIResponse ); - expect( response ).toMatchObject( { - status: 200, - headers: { - 'content-type': 'application/json', - }, - data: { - test: 'value', - }, - } ); - } ); - - it( 'should transform response errors into APIError', async () => { - moxios.stubOnce( 'GET', '/wc/v2/product', { - status: 404, - headers: { - 'Content-Type': 'application/json', - }, - responseText: JSON.stringify( { message: 'value' } ), - } ); - - await apiClient.request( 'GET', '/wc/v2/product' ).catch( ( error ) => { - expect( error ).toMatchObject( - new APIError( - new APIResponse( - 404, - { 'content-type': 'application/json' }, - { message: 'value' } - ), - null - ) - ); - } ); + const request = moxios.requests.mostRecent(); + expect( request.headers ).toHaveProperty( 'Authorization' ); } ); } ); diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.ts b/tests/e2e/factories/src/http/axios/axios-api-service.ts index 8c3fdf65fb3..92bdee5aa31 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/http/axios/axios-api-service.ts @@ -1,5 +1,6 @@ import { APIResponse, APIError, APIService } from '../api-service'; import { APIAuthInterceptor } from './api-auth-interceptor'; +import { APIResponseInterceptor } from './api-response-interceptor'; import axios, { AxiosInstance, AxiosTransformer, @@ -15,6 +16,7 @@ import axios, { export class AxiosAPIService implements APIService { private client: AxiosInstance; private authInterceptor: APIAuthInterceptor; + private responseInterceptor: APIResponseInterceptor; public constructor( baseAPIURL: string, @@ -30,6 +32,8 @@ export class AxiosAPIService implements APIService { consumerSecret ); this.authInterceptor.start(); + this.responseInterceptor = new APIResponseInterceptor( this.client ); + this.responseInterceptor.start(); } /** @@ -43,7 +47,7 @@ export class AxiosAPIService implements APIService { endpoint: string, params?: any ): Promise< APIResponse< T > | APIError< T > > { - return this.request( 'GET', endpoint, params ); + return this.client.get( endpoint, { params } ); } /** @@ -57,7 +61,7 @@ export class AxiosAPIService implements APIService { endpoint: string, data?: any ): Promise< APIResponse< T > | APIError< T > > { - return this.request( 'POST', endpoint, data ); + return this.client.post( endpoint, { data } ); } /** @@ -71,7 +75,7 @@ export class AxiosAPIService implements APIService { endpoint: string, data?: any ): Promise< APIResponse< T > | APIError< T > > { - return this.request( 'PUT', endpoint, data ); + return this.client.put( endpoint, { data } ); } /** @@ -85,7 +89,7 @@ export class AxiosAPIService implements APIService { endpoint: string, data?: any ): Promise< APIResponse< T > | APIError< T > > { - return this.request( 'PATCH', endpoint, data ); + return this.client.patch( endpoint, { data } ); } /** @@ -99,80 +103,6 @@ export class AxiosAPIService implements APIService { endpoint: string, data?: any ): Promise< APIResponse< T > | APIError< T > > { - return this.request( 'DELETE', endpoint, data ); - } - - /** - * Performs an HTTP request against the WordPress API. - * - * @param {string} method The HTTP method we should use in the request. - * @param {string} endpoint The API endpoint we should query. - * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and throws an APIError. - */ - public request< T >( - method: Method, - endpoint: string, - data?: any - ): Promise< APIResponse< T > | APIError< T > > { - const config: AxiosRequestConfig = { - method, - url: endpoint, - }; - if ( data ) { - if ( 'GET' === method ) { - config.params = data; - } else { - config.data = data; - } - } - - return this.client.request( config ).then( - ( response ) => this.onFulfilled< T >( response ), - ( error ) => this.onRejected< T >( error ) - ); - } - - /** - * Transforms the Axios response into our API response to be consumed in a consistent manner. - * - * @param {AxiosResponse} response The respons ethat we need to transform. - * @return {Promise} A promise containing the APIResponse. - */ - private onFulfilled< T >( - response: AxiosResponse - ): Promise< APIResponse< T > > { - return Promise.resolve< APIResponse< T > >( - new APIResponse< T >( - response.status, - response.headers, - response.data - ) - ); - } - - /** - * Transforms the Axios error into our API error to be consumed in a consistent manner. - * - * @param {*} error The error - * @return {Promise} A promise containing the APIError. - */ - private onRejected< T >( error: any ): Promise< APIError< T > > { - let apiResponse: APIResponse< T > | null = null; - let message: string | null = null; - if ( error.response ) { - apiResponse = new APIResponse< T >( - error.response.status, - error.response.headers, - error.response.data - ); - } else if ( error.request ) { - message = 'No response was received from the server.'; - } else { - // Keep bubbling up the errors that we aren't handling. - throw error; - } - - return Promise.reject( new APIError< T >( apiResponse, message ) ); + return this.client.delete( endpoint, { data } ); } } From 6ad8b57f2e82f73e57ba3245331c6580c809bfef Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 24 Jun 2020 14:47:46 -0700 Subject: [PATCH 269/440] Added formatting requirements to the code style --- tests/e2e/factories/.eslintrc.js | 3 +- tests/e2e/factories/src/http/api-service.ts | 31 ++++++------- .../http/axios/api-auth-interceptor.spec.ts | 10 +++-- .../src/http/axios/api-auth-interceptor.ts | 10 ++--- .../axios/api-response-interceptor.spec.ts | 6 +-- .../http/axios/api-response-interceptor.ts | 12 +++--- .../src/http/axios/axios-api-service.spec.ts | 5 +-- .../src/http/axios/axios-api-service.ts | 43 ++++++++----------- 8 files changed, 54 insertions(+), 66 deletions(-) diff --git a/tests/e2e/factories/.eslintrc.js b/tests/e2e/factories/.eslintrc.js index bfefabe0d83..0dc62f94697 100644 --- a/tests/e2e/factories/.eslintrc.js +++ b/tests/e2e/factories/.eslintrc.js @@ -11,8 +11,7 @@ module.exports = { 'no-unused-vars': 'off', }, extends: [ - 'plugin:@wordpress/eslint-plugin/recommended', - 'plugin:jest/recommended' + 'plugin:@wordpress/eslint-plugin/recommended-with-formatting' ], overrides: [ { "files": [ '**/*.ts' ] } diff --git a/tests/e2e/factories/src/http/api-service.ts b/tests/e2e/factories/src/http/api-service.ts index 28477006918..d3242609b84 100644 --- a/tests/e2e/factories/src/http/api-service.ts +++ b/tests/e2e/factories/src/http/api-service.ts @@ -1,7 +1,7 @@ /** * A structured response from the API. */ -export class APIResponse< T = any > { +export class APIResponse { public readonly status: number; public readonly headers: any; public readonly data: T | null; @@ -16,12 +16,12 @@ export class APIResponse< T = any > { /** * A structured error from the API. */ -export class APIError< T = any > extends Error { - public readonly response: APIResponse< T > | null; +export class APIError extends Error { + public readonly response: APIResponse | null; public constructor( - response: APIResponse< T > | null, - message: string | null + response: APIResponse | null, + message: string | null, ) { super( message || 'An error has been returned by the API.' ); @@ -40,10 +40,10 @@ export interface APIService { * @param {*} params Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and rejects an APIError. */ - get< T >( + get( endpoint: string, params?: any - ): Promise< APIResponse< T > | APIError< T > >; + ): Promise | APIError>; /** * Performs a POST request against the WordPress API. @@ -52,10 +52,10 @@ export interface APIService { * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and rejects an APIError. */ - post< T >( + post( endpoint: string, data?: any - ): Promise< APIResponse< T > | APIError< T > >; + ): Promise | APIError>; /** * Performs a PUT request against the WordPress API. @@ -64,10 +64,7 @@ export interface APIService { * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and rejects an APIError. */ - put< T >( - endpoint: string, - data?: any - ): Promise< APIResponse< T > | APIError< T > >; + put( endpoint: string, data?: any ): Promise | APIError>; /** * Performs a PATCH request against the WordPress API. @@ -76,10 +73,10 @@ export interface APIService { * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and rejects an APIError. */ - patch< T >( + patch( endpoint: string, data?: any - ): Promise< APIResponse< T > | APIError< T > >; + ): Promise | APIError>; /** * Performs a DELETE request against the WordPress API. @@ -88,8 +85,8 @@ export interface APIService { * @param {*} params Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and rejects an APIError. */ - delete< T >( + delete( endpoint: string, data?: any - ): Promise< APIResponse< T > | APIError< T > >; + ): Promise | APIError>; } diff --git a/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts b/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts index f7722e0ccbf..293c2d14310 100644 --- a/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts +++ b/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts @@ -12,7 +12,7 @@ describe( 'APIAuthInterceptor', () => { apiAuthInterceptor = new APIAuthInterceptor( axiosInstance, 'consumer_key', - 'consumer_secret' + 'consumer_secret', ); apiAuthInterceptor.start(); } ); @@ -46,7 +46,8 @@ describe( 'APIAuthInterceptor', () => { expect( request.headers ).toHaveProperty( 'Authorization' ); expect( request.headers.Authorization ).toEqual( - 'Basic ' + btoa( 'consumer_key:consumer_secret' ) + 'Basic ' + + Buffer.from( 'consumer_key:consumer_secret' ).toString( 'base64' ), ); } ); @@ -60,7 +61,7 @@ describe( 'APIAuthInterceptor', () => { // focus on ensuring that the header looks roughly correct given what we readily know. expect( request.headers ).toHaveProperty( 'Authorization' ); expect( request.headers.Authorization ).toMatch( - /^OAuth oauth_consumer_key="consumer_key".*oauth_signature_method="HMAC-SHA256".*oauth_version="1.0"/ + /^OAuth oauth_consumer_key="consumer_key".*oauth_signature_method="HMAC-SHA256".*oauth_version="1.0"/, ); } ); @@ -76,7 +77,8 @@ describe( 'APIAuthInterceptor', () => { expect( request.headers ).toHaveProperty( 'Authorization' ); expect( request.headers.Authorization ).toEqual( - 'Basic ' + btoa( 'consumer_key:consumer_secret' ) + 'Basic ' + + Buffer.from( 'consumer_key:consumer_secret' ).toString( 'base64' ), ); } ); } ); diff --git a/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts b/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts index 63e453e7e06..c2ef24280b8 100644 --- a/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts +++ b/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts @@ -13,7 +13,7 @@ export class APIAuthInterceptor { public constructor( client: AxiosInstance, consumerKey: string, - consumerSecret: string + consumerSecret: string, ) { this.client = client; this.interceptorID = null; @@ -24,9 +24,7 @@ export class APIAuthInterceptor { }, signature_method: 'HMAC-SHA256', hash_function: ( base: any, key: any ) => { - return createHmac( 'sha256', key ) - .update( base ) - .digest( 'base64' ); + return createHmac( 'sha256', key ).update( base ).digest( 'base64' ); }, } ); } @@ -37,7 +35,7 @@ export class APIAuthInterceptor { public start(): void { if ( null === this.interceptorID ) { this.interceptorID = this.client.interceptors.request.use( - ( request ) => this.handleRequest( request ) + ( request ) => this.handleRequest( request ), ); } } @@ -70,7 +68,7 @@ export class APIAuthInterceptor { this.oauth.authorize( { url, method: request.method!, - } ) + } ), ).Authorization; } diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts b/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts index f883fc099ca..9eab2309ad1 100644 --- a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts +++ b/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts @@ -56,10 +56,10 @@ describe( 'APIResponseInterceptor', () => { new APIResponse( 404, { 'content-type': 'application/json' }, - { message: 'value' } + { message: 'value' }, ), - null - ) + null, + ), ); } ); } ); diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.ts b/tests/e2e/factories/src/http/axios/api-response-interceptor.ts index d75c27dea7f..ba2dc483e35 100644 --- a/tests/e2e/factories/src/http/axios/api-response-interceptor.ts +++ b/tests/e2e/factories/src/http/axios/api-response-interceptor.ts @@ -18,7 +18,7 @@ export class APIResponseInterceptor { this.interceptorID = this.client.interceptors.response.use( // @ts-ignore: We WANT to change the type of response returned. ( response ) => this.onFulfilled( response ), - ( error: any ) => this.onRejected( error ) + ( error: any ) => this.onRejected( error ), ); } } @@ -39,9 +39,9 @@ export class APIResponseInterceptor { * @param {AxiosResponse} response The respons ethat we need to transform. * @return {Promise} A promise containing the APIResponse. */ - private onFulfilled( response: AxiosResponse ): Promise< APIResponse > { - return Promise.resolve< APIResponse >( - new APIResponse( response.status, response.headers, response.data ) + private onFulfilled( response: AxiosResponse ): Promise { + return Promise.resolve( + new APIResponse( response.status, response.headers, response.data ), ); } @@ -51,14 +51,14 @@ export class APIResponseInterceptor { * @param {*} error The error * @return {Promise} A promise containing the APIError. */ - private onRejected( error: any ): Promise< APIError > { + private onRejected( error: any ): Promise { let apiResponse: APIResponse | null = null; let message: string | null = null; if ( error.response ) { apiResponse = new APIResponse( error.response.status, error.response.headers, - error.response.data + error.response.data, ); } else if ( error.request ) { message = 'No response was received from the server.'; diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts b/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts index da1a3729a3d..a2dff0fad76 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts +++ b/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts @@ -1,6 +1,5 @@ -import axios, { AxiosInstance } from 'axios'; import moxios from 'moxios'; -import { APIResponse, APIError } from './../api-service'; +import { APIResponse } from './../api-service'; import { AxiosAPIService } from './axios-api-service'; describe( 'AxiosAPIService', () => { @@ -11,7 +10,7 @@ describe( 'AxiosAPIService', () => { apiClient = new AxiosAPIService( 'https://test.test/wp-json/', 'consumer_key', - 'consumer_secret' + 'consumer_secret', ); } ); diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.ts b/tests/e2e/factories/src/http/axios/axios-api-service.ts index 92bdee5aa31..63bb42ddb7e 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/http/axios/axios-api-service.ts @@ -1,14 +1,7 @@ import { APIResponse, APIError, APIService } from '../api-service'; import { APIAuthInterceptor } from './api-auth-interceptor'; import { APIResponseInterceptor } from './api-response-interceptor'; -import axios, { - AxiosInstance, - AxiosTransformer, - AxiosResponse, - AxiosError, - Method, - AxiosRequestConfig, -} from 'axios'; +import axios, { AxiosInstance } from 'axios'; /** * An API service implementation that uses Axios to make requests to the WordPress API. @@ -21,7 +14,7 @@ export class AxiosAPIService implements APIService { public constructor( baseAPIURL: string, consumerKey: string, - consumerSecret: string + consumerSecret: string, ) { this.client = axios.create( { baseURL: baseAPIURL, @@ -29,7 +22,7 @@ export class AxiosAPIService implements APIService { this.authInterceptor = new APIAuthInterceptor( this.client, consumerKey, - consumerSecret + consumerSecret, ); this.authInterceptor.start(); this.responseInterceptor = new APIResponseInterceptor( this.client ); @@ -43,10 +36,10 @@ export class AxiosAPIService implements APIService { * @param {*} params Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and rejects an APIError. */ - public get< T >( + public get( endpoint: string, - params?: any - ): Promise< APIResponse< T > | APIError< T > > { + params?: any, + ): Promise | APIError> { return this.client.get( endpoint, { params } ); } @@ -57,10 +50,10 @@ export class AxiosAPIService implements APIService { * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and throws an APIError. */ - public post< T >( + public post( endpoint: string, - data?: any - ): Promise< APIResponse< T > | APIError< T > > { + data?: any, + ): Promise | APIError> { return this.client.post( endpoint, { data } ); } @@ -71,10 +64,10 @@ export class AxiosAPIService implements APIService { * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and throws an APIError. */ - public put< T >( + public put( endpoint: string, - data?: any - ): Promise< APIResponse< T > | APIError< T > > { + data?: any, + ): Promise | APIError> { return this.client.put( endpoint, { data } ); } @@ -85,10 +78,10 @@ export class AxiosAPIService implements APIService { * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and throws an APIError. */ - public patch< T >( + public patch( endpoint: string, - data?: any - ): Promise< APIResponse< T > | APIError< T > > { + data?: any, + ): Promise | APIError> { return this.client.patch( endpoint, { data } ); } @@ -99,10 +92,10 @@ export class AxiosAPIService implements APIService { * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and throws an APIError. */ - public delete< T >( + public delete( endpoint: string, - data?: any - ): Promise< APIResponse< T > | APIError< T > > { + data?: any, + ): Promise | APIError> { return this.client.delete( endpoint, { data } ); } } From ddbbbbc07866542c06db4a1ddf1ee5b26e607aea Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 24 Jun 2020 14:48:32 -0700 Subject: [PATCH 270/440] Adjusted the TypeScript configuration to use the --build flag --- tests/e2e/factories/.gitignore | 1 + .../src/http/axios/axios-api-service.ts | 8 ++++---- tests/e2e/factories/src/index.ts | 2 ++ tests/e2e/factories/tsconfig.json | 12 ++++------- tsconfig.base.json | 20 +++++++++++++++++++ tsconfig.json | 6 ++++++ 6 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 tsconfig.base.json create mode 100644 tsconfig.json diff --git a/tests/e2e/factories/.gitignore b/tests/e2e/factories/.gitignore index 34dac168f2c..1f578929131 100644 --- a/tests/e2e/factories/.gitignore +++ b/tests/e2e/factories/.gitignore @@ -15,3 +15,4 @@ project.properties # Build Artifacts /node_modules/ /dist/ +tsconfig.tsbuildinfo diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.ts b/tests/e2e/factories/src/http/axios/axios-api-service.ts index 63bb42ddb7e..8c1d9e14de1 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/http/axios/axios-api-service.ts @@ -1,13 +1,13 @@ -import { APIResponse, APIError, APIService } from '../api-service'; -import { APIAuthInterceptor } from './api-auth-interceptor'; -import { APIResponseInterceptor } from './api-response-interceptor'; import axios, { AxiosInstance } from 'axios'; +import { APIAuthInterceptor } from './api-auth-interceptor'; +import { APIError, APIResponse, APIService } from '../api-service'; +import { APIResponseInterceptor } from './api-response-interceptor'; /** * An API service implementation that uses Axios to make requests to the WordPress API. */ export class AxiosAPIService implements APIService { - private client: AxiosInstance; + private readonly client: AxiosInstance; private authInterceptor: APIAuthInterceptor; private responseInterceptor: APIResponseInterceptor; diff --git a/tests/e2e/factories/src/index.ts b/tests/e2e/factories/src/index.ts index e69de29bb2d..0b46c864740 100644 --- a/tests/e2e/factories/src/index.ts +++ b/tests/e2e/factories/src/index.ts @@ -0,0 +1,2 @@ +export { APIService, APIResponse, APIError } from './http/api-service'; +export { AxiosAPIService } from './http/axios/axios-api-service'; diff --git a/tests/e2e/factories/tsconfig.json b/tests/e2e/factories/tsconfig.json index 4379bfd36b5..f32d56749ca 100644 --- a/tests/e2e/factories/tsconfig.json +++ b/tests/e2e/factories/tsconfig.json @@ -1,13 +1,9 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { - "incremental": true, - "target": "es5", - "module": "commonjs", "types": [ "node", "jest", "axios", "moxios", "create-hmac" ], - "outDir": "dist", - "declaration": true, - "strict": true, - "esModuleInterop": true + "rootDir": "src", + "outDir": "dist" }, - "include": [ "./src/**/*" ] + "include": [ "src/**/*" ] } diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 00000000000..0ea700b4018 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "incremental": true, + "allowJs": true, + "checkJs": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "declaration": true, + "composite": true, + "strict": true, + "strictNullChecks": true, + "noImplicitAny": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..5ce3f73bb9b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,6 @@ +{ + "references": [ + { "path": "tests/e2e/factories" } + ], + "files": [] +} From 4aa9360ba78f2ac682579006aedc5f1a37fb047e Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 30 Jun 2020 12:50:15 -0700 Subject: [PATCH 271/440] Added an adapter to support creating models via the API --- tests/e2e/factories/.eslintrc.js | 11 ++- tests/e2e/factories/src/adapters/adapter.ts | 13 +++ .../src/adapters/api-adapter.spec.ts | 55 ++++++++++++ .../e2e/factories/src/adapters/api-adapter.ts | 89 +++++++++++++++++++ tests/e2e/factories/src/http/api-service.ts | 12 +-- .../http/axios/api-auth-interceptor.spec.ts | 4 +- .../src/http/axios/axios-api-service.ts | 12 +-- tests/e2e/factories/src/models/model.ts | 29 ++++++ 8 files changed, 210 insertions(+), 15 deletions(-) create mode 100644 tests/e2e/factories/src/adapters/adapter.ts create mode 100644 tests/e2e/factories/src/adapters/api-adapter.spec.ts create mode 100644 tests/e2e/factories/src/adapters/api-adapter.ts create mode 100644 tests/e2e/factories/src/models/model.ts diff --git a/tests/e2e/factories/.eslintrc.js b/tests/e2e/factories/.eslintrc.js index 0dc62f94697..e8bd90774e9 100644 --- a/tests/e2e/factories/.eslintrc.js +++ b/tests/e2e/factories/.eslintrc.js @@ -9,11 +9,20 @@ module.exports = { ], rules: { 'no-unused-vars': 'off', + 'no-dupe-class-members': 'off', }, extends: [ 'plugin:@wordpress/eslint-plugin/recommended-with-formatting' ], overrides: [ - { "files": [ '**/*.ts' ] } + { + 'files': [ '**/*.ts' ] + }, + { + 'files': [ '**/*.spec.ts' ], + 'rules': { + 'no-console': 'off', + } + } ] } diff --git a/tests/e2e/factories/src/adapters/adapter.ts b/tests/e2e/factories/src/adapters/adapter.ts new file mode 100644 index 00000000000..85e90dc30ee --- /dev/null +++ b/tests/e2e/factories/src/adapters/adapter.ts @@ -0,0 +1,13 @@ +import { Model } from '../models/model'; + +export interface Adapter { + /** + * Creates a model or array of models using a service.. + * + * @param {Model|Model[]} model The model or array of models to create. + * @return {Promise} Resolves to the created input model or array of models. + */ + create( model: T ): Promise; + create( model: T[] ): Promise; + create( model: T | T[] ): Promise | Promise; +} diff --git a/tests/e2e/factories/src/adapters/api-adapter.spec.ts b/tests/e2e/factories/src/adapters/api-adapter.spec.ts new file mode 100644 index 00000000000..2003badd22b --- /dev/null +++ b/tests/e2e/factories/src/adapters/api-adapter.spec.ts @@ -0,0 +1,55 @@ +import { Model } from '../models/model'; +import { APIResponse, APIService } from '..'; +import { APIAdapter } from './api-adapter'; + +class MockAPI implements APIService { + public get = jest.fn(); + public post = jest.fn(); + public put = jest.fn(); + public patch = jest.fn(); + public delete = jest.fn(); +} + +class MockModel extends Model {} + +describe( 'APIModelCreator', () => { + let adapter: APIAdapter; + let mockService: MockAPI; + + beforeEach( () => { + adapter = new APIAdapter( '/wc/v3/product', () => 'test' ); + mockService = new MockAPI(); + adapter.setAPIService( mockService ); + } ); + + it( 'should create single instance', async () => { + mockService.post.mockReturnValueOnce( new APIResponse( 200, {}, { id: 1 } ) ); + + const result = await adapter.create( new MockModel() ); + + expect( result ).toBeInstanceOf( MockModel ); + expect( result.id ).toBe( 1 ); + expect( mockService.post.mock.calls[ 0 ][ 0 ] ).toBe( '/wc/v3/product' ); + expect( mockService.post.mock.calls[ 0 ][ 1 ] ).toBe( 'test' ); + } ); + + it( 'should create multiple instances', async () => { + mockService.post.mockReturnValueOnce( new APIResponse( 200, {}, { id: 1 } ) ) + .mockReturnValueOnce( new APIResponse( 200, {}, { id: 2 } ) ) + .mockReturnValueOnce( new APIResponse( 200, {}, { id: 3 } ) ); + + const result = await adapter.create( [ new MockModel(), new MockModel(), new MockModel() ] ); + + expect( result ).toBeInstanceOf( Array ); + expect( result ).toHaveLength( 3 ); + expect( result[ 0 ].id ).toBe( 1 ); + expect( result[ 1 ].id ).toBe( 2 ); + expect( result[ 2 ].id ).toBe( 3 ); + expect( mockService.post.mock.calls[ 0 ][ 0 ] ).toBe( '/wc/v3/product' ); + expect( mockService.post.mock.calls[ 0 ][ 1 ] ).toBe( 'test' ); + expect( mockService.post.mock.calls[ 1 ][ 0 ] ).toBe( '/wc/v3/product' ); + expect( mockService.post.mock.calls[ 1 ][ 1 ] ).toBe( 'test' ); + expect( mockService.post.mock.calls[ 2 ][ 0 ] ).toBe( '/wc/v3/product' ); + expect( mockService.post.mock.calls[ 2 ][ 1 ] ).toBe( 'test' ); + } ); +} ); diff --git a/tests/e2e/factories/src/adapters/api-adapter.ts b/tests/e2e/factories/src/adapters/api-adapter.ts new file mode 100644 index 00000000000..0a81275d0f5 --- /dev/null +++ b/tests/e2e/factories/src/adapters/api-adapter.ts @@ -0,0 +1,89 @@ +import { APIService } from '..'; +import { Model } from '../models/model'; +import { Adapter } from './adapter'; + +/** + * A callback for transforming models into an API request body. + * + * @callback APITransformerFn + * @param {Model} model The model that we want to transform. + * @return {*} The structured request data for the API. + */ +export type APITransformerFn = ( model: T ) => any; + +/** + * A class used for creating data models using a supplied API endpoint. + */ +export class APIAdapter implements Adapter { + private readonly endpoint: string; + private readonly transformer: APITransformerFn; + private apiService: APIService | null; + + public constructor( endpoint: string, transformer: APITransformerFn ) { + this.endpoint = endpoint; + this.transformer = transformer; + this.apiService = null; + } + + /** + * Sets the API service that the adapter should use for creation actions. + * + * @param {APIService|null} service The new API service for the adapter to use. + */ + public setAPIService( service: APIService | null ): void { + this.apiService = service; + } + + /** + * Creates a model or array of models using the API service. + * + * @param {Model|Model[]} model The model or array of models to create. + * @return {Promise} Resolves to the created input model or array of models. + */ + public create( model: T ): Promise; + public create( model: T[] ): Promise; + public create( model: T | T[] ): Promise | Promise { + if ( ! this.apiService ) { + throw new Error( 'An API service must be registered for the adapter to work.' ); + } + + if ( Array.isArray( model ) ) { + return this.createList( model ); + } + + return this.createSingle( model ); + } + + /** + * Creates a single model using the API service. + * + * @param {Model} model The model to create. + * @return {Promise} Resolves to the created input model. + */ + private async createSingle( model: T ): Promise { + return new Promise( async ( resolve ) => { + const response = await this.apiService!.post( + this.endpoint, + this.transformer( model ), + ); + + model.onCreated( response.data ); + resolve( model ); + } ); + } + + /** + * Creates an array of models using the API service. + * + * @param {Model[]} models The array of models to create. + * @return {Promise} Resolves to the array of created input models. + */ + private async createList( models: T[] ): Promise { + const promises: Promise[] = []; + for ( const model of models ) { + promises.push( this.createSingle( model ) ); + } + + return Promise.all( promises ); + } +} diff --git a/tests/e2e/factories/src/http/api-service.ts b/tests/e2e/factories/src/http/api-service.ts index d3242609b84..1a896408d64 100644 --- a/tests/e2e/factories/src/http/api-service.ts +++ b/tests/e2e/factories/src/http/api-service.ts @@ -43,7 +43,7 @@ export interface APIService { get( endpoint: string, params?: any - ): Promise | APIError>; + ): Promise>; /** * Performs a POST request against the WordPress API. @@ -55,7 +55,7 @@ export interface APIService { post( endpoint: string, data?: any - ): Promise | APIError>; + ): Promise>; /** * Performs a PUT request against the WordPress API. @@ -64,7 +64,7 @@ export interface APIService { * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and rejects an APIError. */ - put( endpoint: string, data?: any ): Promise | APIError>; + put( endpoint: string, data?: any ): Promise>; /** * Performs a PATCH request against the WordPress API. @@ -76,17 +76,17 @@ export interface APIService { patch( endpoint: string, data?: any - ): Promise | APIError>; + ): Promise>; /** * Performs a DELETE request against the WordPress API. * * @param {string} endpoint The API endpoint we should query. - * @param {*} params Any parameters that should be passed in the request. + * @param {*} data Any parameters that should be passed in the request. * @return {Promise} Resolves to an APIResponse and rejects an APIError. */ delete( endpoint: string, data?: any - ): Promise | APIError>; + ): Promise>; } diff --git a/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts b/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts index 293c2d14310..a6fbdc2cb05 100644 --- a/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts +++ b/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts @@ -45,7 +45,7 @@ describe( 'APIAuthInterceptor', () => { const request = moxios.requests.mostRecent(); expect( request.headers ).toHaveProperty( 'Authorization' ); - expect( request.headers.Authorization ).toEqual( + expect( request.headers.Authorization ).toBe( 'Basic ' + Buffer.from( 'consumer_key:consumer_secret' ).toString( 'base64' ), ); @@ -76,7 +76,7 @@ describe( 'APIAuthInterceptor', () => { const request = moxios.requests.mostRecent(); expect( request.headers ).toHaveProperty( 'Authorization' ); - expect( request.headers.Authorization ).toEqual( + expect( request.headers.Authorization ).toBe( 'Basic ' + Buffer.from( 'consumer_key:consumer_secret' ).toString( 'base64' ), ); diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.ts b/tests/e2e/factories/src/http/axios/axios-api-service.ts index 8c1d9e14de1..4f9d8280075 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/http/axios/axios-api-service.ts @@ -1,6 +1,6 @@ import axios, { AxiosInstance } from 'axios'; import { APIAuthInterceptor } from './api-auth-interceptor'; -import { APIError, APIResponse, APIService } from '../api-service'; +import { APIResponse, APIService } from '../api-service'; import { APIResponseInterceptor } from './api-response-interceptor'; /** @@ -39,7 +39,7 @@ export class AxiosAPIService implements APIService { public get( endpoint: string, params?: any, - ): Promise | APIError> { + ): Promise> { return this.client.get( endpoint, { params } ); } @@ -53,7 +53,7 @@ export class AxiosAPIService implements APIService { public post( endpoint: string, data?: any, - ): Promise | APIError> { + ): Promise> { return this.client.post( endpoint, { data } ); } @@ -67,7 +67,7 @@ export class AxiosAPIService implements APIService { public put( endpoint: string, data?: any, - ): Promise | APIError> { + ): Promise> { return this.client.put( endpoint, { data } ); } @@ -81,7 +81,7 @@ export class AxiosAPIService implements APIService { public patch( endpoint: string, data?: any, - ): Promise | APIError> { + ): Promise> { return this.client.patch( endpoint, { data } ); } @@ -95,7 +95,7 @@ export class AxiosAPIService implements APIService { public delete( endpoint: string, data?: any, - ): Promise | APIError> { + ): Promise> { return this.client.delete( endpoint, { data } ); } } diff --git a/tests/e2e/factories/src/models/model.ts b/tests/e2e/factories/src/models/model.ts new file mode 100644 index 00000000000..62a6775cef2 --- /dev/null +++ b/tests/e2e/factories/src/models/model.ts @@ -0,0 +1,29 @@ +/** + * A base class for all models. + */ +export abstract class Model { + private _id: number = 0; + + public constructor( partial?: Partial ) { + if ( partial ) { + Object.assign( this, partial ); + } + } + + public get id(): number { + return this._id; + } + + /** + * A handler to be called after the model has been created. + * + * @param {*} created The model that was created on the server. + */ + public onCreated( created: any ): void { + if ( this._id ) { + throw new Error( 'The model has been created already.' ); + } + + this._id = created.id; + } +} From 7500cc004d985820c0b479375f2b23edbf7c44e0 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 30 Jun 2020 13:05:25 -0700 Subject: [PATCH 272/440] Added a skeleton product factory for testing --- tests/e2e/factories/package-lock.json | 12 +++++++++++ tests/e2e/factories/package.json | 3 ++- .../src/adapters/api-adapter.spec.ts | 8 ++++---- .../e2e/factories/src/definitions/product.ts | 20 +++++++++++++++++++ tests/e2e/factories/src/models/model.ts | 6 ++++-- tests/e2e/factories/src/models/product.ts | 6 ++++++ 6 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 tests/e2e/factories/src/definitions/product.ts create mode 100644 tests/e2e/factories/src/models/product.ts diff --git a/tests/e2e/factories/package-lock.json b/tests/e2e/factories/package-lock.json index b2c8af6f674..fec2ecbee22 100644 --- a/tests/e2e/factories/package-lock.json +++ b/tests/e2e/factories/package-lock.json @@ -1897,6 +1897,13 @@ "path-exists": "^4.0.0" } }, + "fishery": { + "version": "1.0.0", + "resolved": "github:thoughtbot/fishery#b45f86d2073513aac9d9f577b4581b3de4ee75f3", + "requires": { + "lodash.merge": "^4.6.2" + } + }, "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", @@ -3121,6 +3128,11 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", diff --git a/tests/e2e/factories/package.json b/tests/e2e/factories/package.json index 133406dea02..f7e5a95e85f 100644 --- a/tests/e2e/factories/package.json +++ b/tests/e2e/factories/package.json @@ -25,12 +25,13 @@ ], "sideEffects": false, "scripts": { - "build": "tsc -p tsconfig.build.json", + "build": "tsc", "test": "jest" }, "dependencies": { "axios": "0.19.2", "create-hmac": "1.1.7", + "fishery": "1.0.0", "oauth-1.0a": "2.2.6" }, "devDependencies": { diff --git a/tests/e2e/factories/src/adapters/api-adapter.spec.ts b/tests/e2e/factories/src/adapters/api-adapter.spec.ts index 2003badd22b..3d07cb33e8c 100644 --- a/tests/e2e/factories/src/adapters/api-adapter.spec.ts +++ b/tests/e2e/factories/src/adapters/api-adapter.spec.ts @@ -28,7 +28,7 @@ describe( 'APIModelCreator', () => { const result = await adapter.create( new MockModel() ); expect( result ).toBeInstanceOf( MockModel ); - expect( result.id ).toBe( 1 ); + expect( result.ID ).toBe( 1 ); expect( mockService.post.mock.calls[ 0 ][ 0 ] ).toBe( '/wc/v3/product' ); expect( mockService.post.mock.calls[ 0 ][ 1 ] ).toBe( 'test' ); } ); @@ -42,9 +42,9 @@ describe( 'APIModelCreator', () => { expect( result ).toBeInstanceOf( Array ); expect( result ).toHaveLength( 3 ); - expect( result[ 0 ].id ).toBe( 1 ); - expect( result[ 1 ].id ).toBe( 2 ); - expect( result[ 2 ].id ).toBe( 3 ); + expect( result[ 0 ].ID ).toBe( 1 ); + expect( result[ 1 ].ID ).toBe( 2 ); + expect( result[ 2 ].ID ).toBe( 3 ); expect( mockService.post.mock.calls[ 0 ][ 0 ] ).toBe( '/wc/v3/product' ); expect( mockService.post.mock.calls[ 0 ][ 1 ] ).toBe( 'test' ); expect( mockService.post.mock.calls[ 1 ][ 0 ] ).toBe( '/wc/v3/product' ); diff --git a/tests/e2e/factories/src/definitions/product.ts b/tests/e2e/factories/src/definitions/product.ts new file mode 100644 index 00000000000..32516b6c11a --- /dev/null +++ b/tests/e2e/factories/src/definitions/product.ts @@ -0,0 +1,20 @@ +import { Factory } from 'fishery'; +import { Product } from '../models/product'; +import { APIAdapter } from '../adapters/api-adapter'; + +const productFactory = Factory.define( ( { params } ) => { + return new Product( params ); +} ); + +const productAPIAdapter = new APIAdapter( + '/wc/v3/product', + ( model ) => { + return { + type: 'simple', + name: model.Name, + regular_price: model.RegularPrice, + }; + }, +); + +export { productFactory, productAPIAdapter }; diff --git a/tests/e2e/factories/src/models/model.ts b/tests/e2e/factories/src/models/model.ts index 62a6775cef2..ad5b160cdee 100644 --- a/tests/e2e/factories/src/models/model.ts +++ b/tests/e2e/factories/src/models/model.ts @@ -1,16 +1,18 @@ /** * A base class for all models. */ +import { DeepPartial } from 'fishery'; + export abstract class Model { private _id: number = 0; - public constructor( partial?: Partial ) { + public constructor( partial?: DeepPartial ) { if ( partial ) { Object.assign( this, partial ); } } - public get id(): number { + public get ID(): number { return this._id; } diff --git a/tests/e2e/factories/src/models/product.ts b/tests/e2e/factories/src/models/product.ts new file mode 100644 index 00000000000..11625b30566 --- /dev/null +++ b/tests/e2e/factories/src/models/product.ts @@ -0,0 +1,6 @@ +import { Model } from './model'; + +export class Product extends Model { + public readonly Name: string = ''; + public readonly RegularPrice: string = ''; +} From 603a5e781294c77643c705c6272f6e2981ab65ed Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 30 Jun 2020 16:01:12 -0700 Subject: [PATCH 273/440] Changed the structure of error responses In practice having the response class contained within the error feels a little backwards. We can instead have a structured APIError model that is contained in the APIResponse and have a consistent response format to consume. --- tests/e2e/factories/.eslintrc.js | 5 ++- tests/e2e/factories/jest.config.js | 2 +- tests/e2e/factories/src/http/api-service.ts | 40 +++++++++++-------- .../axios/api-response-interceptor.spec.ts | 13 +++--- .../http/axios/api-response-interceptor.ts | 33 +++++++-------- .../src/http/axios/axios-api-service.ts | 14 ++++--- 6 files changed, 58 insertions(+), 49 deletions(-) diff --git a/tests/e2e/factories/.eslintrc.js b/tests/e2e/factories/.eslintrc.js index e8bd90774e9..fc56fef7cf8 100644 --- a/tests/e2e/factories/.eslintrc.js +++ b/tests/e2e/factories/.eslintrc.js @@ -19,7 +19,10 @@ module.exports = { 'files': [ '**/*.ts' ] }, { - 'files': [ '**/*.spec.ts' ], + 'files': [ + '**/*.spec.ts', + '**/*.test.ts' + ], 'rules': { 'no-console': 'off', } diff --git a/tests/e2e/factories/jest.config.js b/tests/e2e/factories/jest.config.js index 208afea0cbf..0595d52172f 100644 --- a/tests/e2e/factories/jest.config.js +++ b/tests/e2e/factories/jest.config.js @@ -1,5 +1,5 @@ module.exports = { preset: 'ts-jest', - testEnvironment: 'jsdom', + testEnvironment: 'node', testPathIgnorePatterns: [ '/node_modules/', '/dist/' ], }; diff --git a/tests/e2e/factories/src/http/api-service.ts b/tests/e2e/factories/src/http/api-service.ts index 1a896408d64..19191f6af46 100644 --- a/tests/e2e/factories/src/http/api-service.ts +++ b/tests/e2e/factories/src/http/api-service.ts @@ -4,9 +4,9 @@ export class APIResponse { public readonly status: number; public readonly headers: any; - public readonly data: T | null; + public readonly data: T; - public constructor( status: number, headers: any, data: T | null ) { + public constructor( status: number, headers: any, data: T ) { this.status = status; this.headers = headers; this.data = data; @@ -16,19 +16,27 @@ export class APIResponse { /** * A structured error from the API. */ -export class APIError extends Error { - public readonly response: APIResponse | null; +export class APIError { + public readonly code: string; + public readonly message: string; + public readonly data: any; - public constructor( - response: APIResponse | null, - message: string | null, - ) { - super( message || 'An error has been returned by the API.' ); - - this.response = response; + public constructor( code: string, message: string, data: any ) { + this.code = code; + this.message = message; + this.data = data; } } +/** + * Checks whether or not an APIResponse contains an error. + * + * @param {APIResponse} response The response to evaluate. + */ +export function isAPIError( response: APIResponse ): response is APIResponse { + return response.status < 200 || response.status >= 400; +} + /** * An interface for implementing services to make calls against the API. */ @@ -38,7 +46,7 @@ export interface APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} params Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and rejects an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ get( endpoint: string, @@ -50,7 +58,7 @@ export interface APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and rejects an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ post( endpoint: string, @@ -62,7 +70,7 @@ export interface APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and rejects an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ put( endpoint: string, data?: any ): Promise>; @@ -71,7 +79,7 @@ export interface APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and rejects an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ patch( endpoint: string, @@ -83,7 +91,7 @@ export interface APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and rejects an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ delete( endpoint: string, diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts b/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts index 9eab2309ad1..91bc78dbfd2 100644 --- a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts +++ b/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts @@ -47,18 +47,15 @@ describe( 'APIResponseInterceptor', () => { headers: { 'Content-Type': 'application/json', }, - responseText: JSON.stringify( { message: 'value' } ), + responseText: JSON.stringify( { code: 'error_code', message: 'value', data: null } ), } ); await axiosInstance.get( 'http://test.test' ).catch( ( error ) => { expect( error ).toMatchObject( - new APIError( - new APIResponse( - 404, - { 'content-type': 'application/json' }, - { message: 'value' }, - ), - null, + new APIResponse( + 404, + { 'content-type': 'application/json' }, + new APIError( 'error_code', 'value', null ), ), ); } ); diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.ts b/tests/e2e/factories/src/http/axios/api-response-interceptor.ts index ba2dc483e35..f21673b2571 100644 --- a/tests/e2e/factories/src/http/axios/api-response-interceptor.ts +++ b/tests/e2e/factories/src/http/axios/api-response-interceptor.ts @@ -18,7 +18,7 @@ export class APIResponseInterceptor { this.interceptorID = this.client.interceptors.response.use( // @ts-ignore: We WANT to change the type of response returned. ( response ) => this.onFulfilled( response ), - ( error: any ) => this.onRejected( error ), + ( error: any ) => APIResponseInterceptor.onRejected( error ), ); } } @@ -46,27 +46,24 @@ export class APIResponseInterceptor { } /** - * Transforms the Axios error into our API error to be consumed in a consistent manner. + * Transforms HTTP errors into an API error if the error came from the API. * - * @param {*} error The error - * @return {Promise} A promise containing the APIError. + * @param {*} error The error that was caught. */ - private onRejected( error: any ): Promise { - let apiResponse: APIResponse | null = null; - let message: string | null = null; - if ( error.response ) { - apiResponse = new APIResponse( - error.response.status, - error.response.headers, - error.response.data, - ); - } else if ( error.request ) { - message = 'No response was received from the server.'; - } else { - // Keep bubbling up the errors that we aren't handling. + private static onRejected( error: any ): Promise { + // Only transform API errors. + if ( ! error.response ) { throw error; } - return Promise.reject( new APIError( apiResponse, message ) ); + throw new APIResponse( + error.response.status, + error.response.headers, + new APIError( + error.response.data.code, + error.response.data.message, + error.response.data.data, + ), + ); } } diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.ts b/tests/e2e/factories/src/http/axios/axios-api-service.ts index 4f9d8280075..32a5cf80923 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/http/axios/axios-api-service.ts @@ -2,6 +2,7 @@ import axios, { AxiosInstance } from 'axios'; import { APIAuthInterceptor } from './api-auth-interceptor'; import { APIResponse, APIService } from '../api-service'; import { APIResponseInterceptor } from './api-response-interceptor'; +import { Agent } from 'https'; /** * An API service implementation that uses Axios to make requests to the WordPress API. @@ -18,6 +19,9 @@ export class AxiosAPIService implements APIService { ) { this.client = axios.create( { baseURL: baseAPIURL, + httpsAgent: new Agent( { + rejectUnauthorized: false, + } ), } ); this.authInterceptor = new APIAuthInterceptor( this.client, @@ -34,7 +38,7 @@ export class AxiosAPIService implements APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} params Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and rejects an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ public get( endpoint: string, @@ -48,7 +52,7 @@ export class AxiosAPIService implements APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and throws an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ public post( endpoint: string, @@ -62,7 +66,7 @@ export class AxiosAPIService implements APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and throws an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ public put( endpoint: string, @@ -76,7 +80,7 @@ export class AxiosAPIService implements APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and throws an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ public patch( endpoint: string, @@ -90,7 +94,7 @@ export class AxiosAPIService implements APIService { * * @param {string} endpoint The API endpoint we should query. * @param {*} data Any parameters that should be passed in the request. - * @return {Promise} Resolves to an APIResponse and throws an APIError. + * @return {Promise} Resolves to an APIResponse and throws an APIResponse containing an APIError. */ public delete( endpoint: string, From 3e2e03d48a6f0282247a628d0ae5bfffd5a72a50 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 30 Jun 2020 16:01:47 -0700 Subject: [PATCH 274/440] Fixed the URL being passed to the OAuth package --- tests/e2e/factories/src/http/axios/api-auth-interceptor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts b/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts index c2ef24280b8..53ec82985f9 100644 --- a/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts +++ b/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts @@ -57,7 +57,7 @@ export class APIAuthInterceptor { * @return {AxiosRequestConfig} The request with the additional authorization headers. */ private handleRequest( request: AxiosRequestConfig ): AxiosRequestConfig { - const url = request.baseURL || '' + request.url || ''; + const url = ( request.baseURL || '' ) + ( request.url || '' ); if ( url.startsWith( 'https' ) ) { request.auth = { username: this.oauth.consumer.key, From c23f52aedfe31c09e2c07b4bda94a5bba40eae56 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 30 Jun 2020 19:00:42 -0700 Subject: [PATCH 275/440] Created a base ModelFactory for all factories to extend --- .../src/adapters/api-adapter.spec.ts | 9 ++-- .../e2e/factories/src/definitions/product.ts | 4 +- .../src/factories/model-factory.spec.ts | 40 ++++++++++++++ .../factories/src/factories/model-factory.ts | 52 +++++++++++++++++++ .../axios/api-response-interceptor.spec.ts | 16 +++--- tests/e2e/factories/src/models/model.ts | 10 ++-- tests/e2e/factories/src/models/product.ts | 6 +++ 7 files changed, 115 insertions(+), 22 deletions(-) create mode 100644 tests/e2e/factories/src/factories/model-factory.spec.ts create mode 100644 tests/e2e/factories/src/factories/model-factory.ts diff --git a/tests/e2e/factories/src/adapters/api-adapter.spec.ts b/tests/e2e/factories/src/adapters/api-adapter.spec.ts index 3d07cb33e8c..7c730cd8c52 100644 --- a/tests/e2e/factories/src/adapters/api-adapter.spec.ts +++ b/tests/e2e/factories/src/adapters/api-adapter.spec.ts @@ -1,6 +1,7 @@ import { Model } from '../models/model'; import { APIResponse, APIService } from '..'; import { APIAdapter } from './api-adapter'; +import { Product } from '../models/product'; class MockAPI implements APIService { public get = jest.fn(); @@ -10,8 +11,6 @@ class MockAPI implements APIService { public delete = jest.fn(); } -class MockModel extends Model {} - describe( 'APIModelCreator', () => { let adapter: APIAdapter; let mockService: MockAPI; @@ -25,9 +24,9 @@ describe( 'APIModelCreator', () => { it( 'should create single instance', async () => { mockService.post.mockReturnValueOnce( new APIResponse( 200, {}, { id: 1 } ) ); - const result = await adapter.create( new MockModel() ); + const result = await adapter.create( new Product() ); - expect( result ).toBeInstanceOf( MockModel ); + expect( result ).toBeInstanceOf( Product ); expect( result.ID ).toBe( 1 ); expect( mockService.post.mock.calls[ 0 ][ 0 ] ).toBe( '/wc/v3/product' ); expect( mockService.post.mock.calls[ 0 ][ 1 ] ).toBe( 'test' ); @@ -38,7 +37,7 @@ describe( 'APIModelCreator', () => { .mockReturnValueOnce( new APIResponse( 200, {}, { id: 2 } ) ) .mockReturnValueOnce( new APIResponse( 200, {}, { id: 3 } ) ); - const result = await adapter.create( [ new MockModel(), new MockModel(), new MockModel() ] ); + const result = await adapter.create( [ new Product(), new Product(), new Product() ] ); expect( result ).toBeInstanceOf( Array ); expect( result ).toHaveLength( 3 ); diff --git a/tests/e2e/factories/src/definitions/product.ts b/tests/e2e/factories/src/definitions/product.ts index 32516b6c11a..7668bcffef2 100644 --- a/tests/e2e/factories/src/definitions/product.ts +++ b/tests/e2e/factories/src/definitions/product.ts @@ -1,8 +1,8 @@ -import { Factory } from 'fishery'; import { Product } from '../models/product'; import { APIAdapter } from '../adapters/api-adapter'; +import { ModelFactory } from '../factories/model-factory'; -const productFactory = Factory.define( ( { params } ) => { +const productFactory: ModelFactory = ModelFactory.define>( ( { params } ) => { return new Product( params ); } ); diff --git a/tests/e2e/factories/src/factories/model-factory.spec.ts b/tests/e2e/factories/src/factories/model-factory.spec.ts new file mode 100644 index 00000000000..062726e5b60 --- /dev/null +++ b/tests/e2e/factories/src/factories/model-factory.spec.ts @@ -0,0 +1,40 @@ +import { ModelFactory } from './model-factory'; +import { Adapter } from '../adapters/adapter'; +import { Product } from '../models/product'; + +class MockAdapter implements Adapter { + public create = jest.fn(); +} + +describe( 'ModelFactory', () => { + let mockAdapter: MockAdapter; + let factory: ModelFactory; + + beforeEach( () => { + mockAdapter = new MockAdapter(); + factory = ModelFactory.define>( + ( { params } ) => { + return new Product( params ); + }, + ); + } ); + + it( 'should error without adapter', async () => { + expect( () => factory.create() ).toThrowError( /no adapter/ ); + } ); + + it( 'should create using adapter', async () => { + factory.setAdapter( mockAdapter ); + + const expectedModel = new Product( { Name: 'test2' } ); + expectedModel.onCreated( { id: 1 } ); + mockAdapter.create.mockReturnValueOnce( Promise.resolve( expectedModel ) ); + + const created = await factory.create( { Name: 'test' } ); + + expect( mockAdapter.create.mock.calls ).toHaveLength( 1 ); + expect( created ).toBeInstanceOf( Product ); + expect( created.ID ).toBe( 1 ); + expect( created.Name ).toBe( 'test2' ); + } ); +} ); diff --git a/tests/e2e/factories/src/factories/model-factory.ts b/tests/e2e/factories/src/factories/model-factory.ts new file mode 100644 index 00000000000..71a91d3e6a8 --- /dev/null +++ b/tests/e2e/factories/src/factories/model-factory.ts @@ -0,0 +1,52 @@ +import { DeepPartial, Factory, BuildOptions } from 'fishery'; +import { Model } from '../models/model'; +import { Adapter } from '../adapters/adapter'; + +/** + * A factory that can be used to create models using an adapter. + */ +export class ModelFactory extends Factory { + private adapter: Adapter | null = null; + + /** + * Sets the adapter that the factory will use to create models. + * + * @param {Adapter|null} adapter + */ + public setAdapter( adapter: Adapter | null ): void { + this.adapter = adapter; + } + + /** + * Create an object using your factory + * + * @param {DeepPartial} params The parameters that should populate the object. + * @param {BuildOptions} options The options to be used in the builder. + * @return {Promise} Resolves to the created model. + */ + public create( params?: DeepPartial, options?: BuildOptions ): Promise { + if ( ! this.adapter ) { + throw new Error( 'The factory has no adapter to create using.' ); + } + + const model = this.build( params, options ); + return this.adapter.create( model ); + } + + /** + * Create an array of objects using your factory + * + * @param {number} number The number of models to create. + * @param {DeepPartial} params The parameters that should populate the object. + * @param {BuildOptions} options The options to be used in the builder. + * @return {Promise} Resolves to the created model. + */ + public createList( number: number, params?: DeepPartial, options?: BuildOptions ): Promise { + if ( ! this.adapter ) { + throw new Error( 'The factory has no adapter to create using.' ); + } + + const model = this.buildList( number, params, options ); + return this.adapter.create( model ); + } +} diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts b/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts index 91bc78dbfd2..c945b829000 100644 --- a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts +++ b/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts @@ -50,14 +50,12 @@ describe( 'APIResponseInterceptor', () => { responseText: JSON.stringify( { code: 'error_code', message: 'value', data: null } ), } ); - await axiosInstance.get( 'http://test.test' ).catch( ( error ) => { - expect( error ).toMatchObject( - new APIResponse( - 404, - { 'content-type': 'application/json' }, - new APIError( 'error_code', 'value', null ), - ), - ); - } ); + await expect( axiosInstance.get( 'http://test.test' ) ).rejects.toMatchObject( + new APIResponse( + 404, + { 'content-type': 'application/json' }, + new APIError( 'error_code', 'value', null ), + ), + ); } ); } ); diff --git a/tests/e2e/factories/src/models/model.ts b/tests/e2e/factories/src/models/model.ts index ad5b160cdee..103d4b1535c 100644 --- a/tests/e2e/factories/src/models/model.ts +++ b/tests/e2e/factories/src/models/model.ts @@ -1,15 +1,13 @@ +import { DeepPartial } from 'fishery'; + /** * A base class for all models. */ -import { DeepPartial } from 'fishery'; - export abstract class Model { private _id: number = 0; - public constructor( partial?: DeepPartial ) { - if ( partial ) { - Object.assign( this, partial ); - } + protected constructor( partial: DeepPartial = {} ) { + Object.assign( this, partial ); } public get ID(): number { diff --git a/tests/e2e/factories/src/models/product.ts b/tests/e2e/factories/src/models/product.ts index 11625b30566..198340d3797 100644 --- a/tests/e2e/factories/src/models/product.ts +++ b/tests/e2e/factories/src/models/product.ts @@ -1,6 +1,12 @@ import { Model } from './model'; +import { DeepPartial } from 'fishery'; export class Product extends Model { public readonly Name: string = ''; public readonly RegularPrice: string = ''; + + public constructor( partial: DeepPartial = {} ) { + super( partial ); + Object.assign( this, partial ); + } } From 627bd5a99a0293319e9499d649c4f92a526435b9 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 30 Jun 2020 21:37:17 -0700 Subject: [PATCH 276/440] Simplified the package directory structure --- .../e2e/factories/src/definitions/product.ts | 20 ------------------- .../src/{adapters => framework}/adapter.ts | 0 .../api-adapter.spec.ts | 2 +- .../{adapters => framework}/api-adapter.ts | 4 ++-- .../src/{http => framework}/api-service.ts | 0 .../axios/axios-api-service.spec.ts | 2 +- .../axios/axios-api-service.ts | 12 +++++------ .../axios/axios-auth-interceptor.spec.ts} | 8 ++++---- .../axios/axios-auth-interceptor.ts} | 2 +- .../axios/axios-response-interceptor.spec.ts} | 10 +++++----- .../axios/axios-response-interceptor.ts} | 4 ++-- .../model-factory.spec.ts | 2 +- .../{factories => framework}/model-factory.ts | 2 +- tests/e2e/factories/src/index.ts | 4 ++-- 14 files changed, 26 insertions(+), 46 deletions(-) delete mode 100644 tests/e2e/factories/src/definitions/product.ts rename tests/e2e/factories/src/{adapters => framework}/adapter.ts (100%) rename tests/e2e/factories/src/{adapters => framework}/api-adapter.spec.ts (97%) rename tests/e2e/factories/src/{adapters => framework}/api-adapter.ts (96%) rename tests/e2e/factories/src/{http => framework}/api-service.ts (100%) rename tests/e2e/factories/src/{http => framework}/axios/axios-api-service.spec.ts (94%) rename tests/e2e/factories/src/{http => framework}/axios/axios-api-service.ts (88%) rename tests/e2e/factories/src/{http/axios/api-auth-interceptor.spec.ts => framework/axios/axios-auth-interceptor.spec.ts} (92%) rename tests/e2e/factories/src/{http/axios/api-auth-interceptor.ts => framework/axios/axios-auth-interceptor.ts} (98%) rename tests/e2e/factories/src/{http/axios/api-response-interceptor.spec.ts => framework/axios/axios-response-interceptor.spec.ts} (81%) rename tests/e2e/factories/src/{http/axios/api-response-interceptor.ts => framework/axios/axios-response-interceptor.ts} (94%) rename tests/e2e/factories/src/{factories => framework}/model-factory.spec.ts (95%) rename tests/e2e/factories/src/{factories => framework}/model-factory.ts (97%) diff --git a/tests/e2e/factories/src/definitions/product.ts b/tests/e2e/factories/src/definitions/product.ts deleted file mode 100644 index 7668bcffef2..00000000000 --- a/tests/e2e/factories/src/definitions/product.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Product } from '../models/product'; -import { APIAdapter } from '../adapters/api-adapter'; -import { ModelFactory } from '../factories/model-factory'; - -const productFactory: ModelFactory = ModelFactory.define>( ( { params } ) => { - return new Product( params ); -} ); - -const productAPIAdapter = new APIAdapter( - '/wc/v3/product', - ( model ) => { - return { - type: 'simple', - name: model.Name, - regular_price: model.RegularPrice, - }; - }, -); - -export { productFactory, productAPIAdapter }; diff --git a/tests/e2e/factories/src/adapters/adapter.ts b/tests/e2e/factories/src/framework/adapter.ts similarity index 100% rename from tests/e2e/factories/src/adapters/adapter.ts rename to tests/e2e/factories/src/framework/adapter.ts diff --git a/tests/e2e/factories/src/adapters/api-adapter.spec.ts b/tests/e2e/factories/src/framework/api-adapter.spec.ts similarity index 97% rename from tests/e2e/factories/src/adapters/api-adapter.spec.ts rename to tests/e2e/factories/src/framework/api-adapter.spec.ts index 7c730cd8c52..075ee480391 100644 --- a/tests/e2e/factories/src/adapters/api-adapter.spec.ts +++ b/tests/e2e/factories/src/framework/api-adapter.spec.ts @@ -1,5 +1,5 @@ import { Model } from '../models/model'; -import { APIResponse, APIService } from '..'; +import { APIResponse, APIService } from '../index'; import { APIAdapter } from './api-adapter'; import { Product } from '../models/product'; diff --git a/tests/e2e/factories/src/adapters/api-adapter.ts b/tests/e2e/factories/src/framework/api-adapter.ts similarity index 96% rename from tests/e2e/factories/src/adapters/api-adapter.ts rename to tests/e2e/factories/src/framework/api-adapter.ts index 0a81275d0f5..d22c7ff7d90 100644 --- a/tests/e2e/factories/src/adapters/api-adapter.ts +++ b/tests/e2e/factories/src/framework/api-adapter.ts @@ -1,4 +1,4 @@ -import { APIService } from '..'; +import { APIService } from '../index'; import { Model } from '../models/model'; import { Adapter } from './adapter'; @@ -62,7 +62,7 @@ export class APIAdapter implements Adapter { */ private async createSingle( model: T ): Promise { return new Promise( async ( resolve ) => { - const response = await this.apiService!.post( + const response = await this.apiService!.post( this.endpoint, this.transformer( model ), ); diff --git a/tests/e2e/factories/src/http/api-service.ts b/tests/e2e/factories/src/framework/api-service.ts similarity index 100% rename from tests/e2e/factories/src/http/api-service.ts rename to tests/e2e/factories/src/framework/api-service.ts diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts b/tests/e2e/factories/src/framework/axios/axios-api-service.spec.ts similarity index 94% rename from tests/e2e/factories/src/http/axios/axios-api-service.spec.ts rename to tests/e2e/factories/src/framework/axios/axios-api-service.spec.ts index a2dff0fad76..1f075fed6c8 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.spec.ts +++ b/tests/e2e/factories/src/framework/axios/axios-api-service.spec.ts @@ -1,5 +1,5 @@ import moxios from 'moxios'; -import { APIResponse } from './../api-service'; +import { APIResponse } from '../api-service'; import { AxiosAPIService } from './axios-api-service'; describe( 'AxiosAPIService', () => { diff --git a/tests/e2e/factories/src/http/axios/axios-api-service.ts b/tests/e2e/factories/src/framework/axios/axios-api-service.ts similarity index 88% rename from tests/e2e/factories/src/http/axios/axios-api-service.ts rename to tests/e2e/factories/src/framework/axios/axios-api-service.ts index 32a5cf80923..5617b52d3d9 100644 --- a/tests/e2e/factories/src/http/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/framework/axios/axios-api-service.ts @@ -1,16 +1,16 @@ import axios, { AxiosInstance } from 'axios'; -import { APIAuthInterceptor } from './api-auth-interceptor'; import { APIResponse, APIService } from '../api-service'; -import { APIResponseInterceptor } from './api-response-interceptor'; import { Agent } from 'https'; +import { AxiosAuthInterceptor } from './axios-auth-interceptor'; +import { AxiosResponseInterceptor } from './axios-response-interceptor'; /** * An API service implementation that uses Axios to make requests to the WordPress API. */ export class AxiosAPIService implements APIService { private readonly client: AxiosInstance; - private authInterceptor: APIAuthInterceptor; - private responseInterceptor: APIResponseInterceptor; + private authInterceptor: AxiosAuthInterceptor; + private responseInterceptor: AxiosResponseInterceptor; public constructor( baseAPIURL: string, @@ -23,13 +23,13 @@ export class AxiosAPIService implements APIService { rejectUnauthorized: false, } ), } ); - this.authInterceptor = new APIAuthInterceptor( + this.authInterceptor = new AxiosAuthInterceptor( this.client, consumerKey, consumerSecret, ); this.authInterceptor.start(); - this.responseInterceptor = new APIResponseInterceptor( this.client ); + this.responseInterceptor = new AxiosResponseInterceptor( this.client ); this.responseInterceptor.start(); } diff --git a/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts b/tests/e2e/factories/src/framework/axios/axios-auth-interceptor.spec.ts similarity index 92% rename from tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts rename to tests/e2e/factories/src/framework/axios/axios-auth-interceptor.spec.ts index a6fbdc2cb05..5c1e1af9769 100644 --- a/tests/e2e/factories/src/http/axios/api-auth-interceptor.spec.ts +++ b/tests/e2e/factories/src/framework/axios/axios-auth-interceptor.spec.ts @@ -1,15 +1,15 @@ import axios, { AxiosInstance } from 'axios'; import moxios from 'moxios'; -import { APIAuthInterceptor } from './api-auth-interceptor'; +import { AxiosAuthInterceptor } from './axios-auth-interceptor'; -describe( 'APIAuthInterceptor', () => { - let apiAuthInterceptor: APIAuthInterceptor; +describe( 'AxiosAuthInterceptor', () => { + let apiAuthInterceptor: AxiosAuthInterceptor; let axiosInstance: AxiosInstance; beforeEach( () => { axiosInstance = axios.create(); moxios.install( axiosInstance ); - apiAuthInterceptor = new APIAuthInterceptor( + apiAuthInterceptor = new AxiosAuthInterceptor( axiosInstance, 'consumer_key', 'consumer_secret', diff --git a/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts b/tests/e2e/factories/src/framework/axios/axios-auth-interceptor.ts similarity index 98% rename from tests/e2e/factories/src/http/axios/api-auth-interceptor.ts rename to tests/e2e/factories/src/framework/axios/axios-auth-interceptor.ts index 53ec82985f9..6953138b17d 100644 --- a/tests/e2e/factories/src/http/axios/api-auth-interceptor.ts +++ b/tests/e2e/factories/src/framework/axios/axios-auth-interceptor.ts @@ -5,7 +5,7 @@ import OAuth from 'oauth-1.0a'; /** * A utility class for managing the lifecycle of an authentication interceptor. */ -export class APIAuthInterceptor { +export class AxiosAuthInterceptor { private readonly client: AxiosInstance; private interceptorID: number | null; private oauth: OAuth; diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts b/tests/e2e/factories/src/framework/axios/axios-response-interceptor.spec.ts similarity index 81% rename from tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts rename to tests/e2e/factories/src/framework/axios/axios-response-interceptor.spec.ts index c945b829000..7bbfb9e24d5 100644 --- a/tests/e2e/factories/src/http/axios/api-response-interceptor.spec.ts +++ b/tests/e2e/factories/src/framework/axios/axios-response-interceptor.spec.ts @@ -1,16 +1,16 @@ import axios, { AxiosInstance } from 'axios'; import moxios from 'moxios'; -import { APIResponse, APIError } from './../api-service'; -import { APIResponseInterceptor } from './api-response-interceptor'; +import { APIResponse, APIError } from '../api-service'; +import { AxiosResponseInterceptor } from './axios-response-interceptor'; -describe( 'APIResponseInterceptor', () => { - let apiResponseInterceptor: APIResponseInterceptor; +describe( 'AxiosResponseInterceptor', () => { + let apiResponseInterceptor: AxiosResponseInterceptor; let axiosInstance: AxiosInstance; beforeEach( () => { axiosInstance = axios.create(); moxios.install( axiosInstance ); - apiResponseInterceptor = new APIResponseInterceptor( axiosInstance ); + apiResponseInterceptor = new AxiosResponseInterceptor( axiosInstance ); apiResponseInterceptor.start(); } ); diff --git a/tests/e2e/factories/src/http/axios/api-response-interceptor.ts b/tests/e2e/factories/src/framework/axios/axios-response-interceptor.ts similarity index 94% rename from tests/e2e/factories/src/http/axios/api-response-interceptor.ts rename to tests/e2e/factories/src/framework/axios/axios-response-interceptor.ts index f21673b2571..bc60c7b4af8 100644 --- a/tests/e2e/factories/src/http/axios/api-response-interceptor.ts +++ b/tests/e2e/factories/src/framework/axios/axios-response-interceptor.ts @@ -1,7 +1,7 @@ import { AxiosInstance, AxiosResponse } from 'axios'; import { APIError, APIResponse } from '../api-service'; -export class APIResponseInterceptor { +export class AxiosResponseInterceptor { private readonly client: AxiosInstance; private interceptorID: number | null; @@ -18,7 +18,7 @@ export class APIResponseInterceptor { this.interceptorID = this.client.interceptors.response.use( // @ts-ignore: We WANT to change the type of response returned. ( response ) => this.onFulfilled( response ), - ( error: any ) => APIResponseInterceptor.onRejected( error ), + ( error: any ) => AxiosResponseInterceptor.onRejected( error ), ); } } diff --git a/tests/e2e/factories/src/factories/model-factory.spec.ts b/tests/e2e/factories/src/framework/model-factory.spec.ts similarity index 95% rename from tests/e2e/factories/src/factories/model-factory.spec.ts rename to tests/e2e/factories/src/framework/model-factory.spec.ts index 062726e5b60..58819159eec 100644 --- a/tests/e2e/factories/src/factories/model-factory.spec.ts +++ b/tests/e2e/factories/src/framework/model-factory.spec.ts @@ -1,5 +1,5 @@ import { ModelFactory } from './model-factory'; -import { Adapter } from '../adapters/adapter'; +import { Adapter } from './adapter'; import { Product } from '../models/product'; class MockAdapter implements Adapter { diff --git a/tests/e2e/factories/src/factories/model-factory.ts b/tests/e2e/factories/src/framework/model-factory.ts similarity index 97% rename from tests/e2e/factories/src/factories/model-factory.ts rename to tests/e2e/factories/src/framework/model-factory.ts index 71a91d3e6a8..099d4ecb173 100644 --- a/tests/e2e/factories/src/factories/model-factory.ts +++ b/tests/e2e/factories/src/framework/model-factory.ts @@ -1,6 +1,6 @@ import { DeepPartial, Factory, BuildOptions } from 'fishery'; import { Model } from '../models/model'; -import { Adapter } from '../adapters/adapter'; +import { Adapter } from './adapter'; /** * A factory that can be used to create models using an adapter. diff --git a/tests/e2e/factories/src/index.ts b/tests/e2e/factories/src/index.ts index 0b46c864740..51d79ca5822 100644 --- a/tests/e2e/factories/src/index.ts +++ b/tests/e2e/factories/src/index.ts @@ -1,2 +1,2 @@ -export { APIService, APIResponse, APIError } from './http/api-service'; -export { AxiosAPIService } from './http/axios/axios-api-service'; +export { APIService, APIResponse, APIError } from './framework/api-service'; +export { AxiosAPIService } from './framework/axios/axios-api-service'; From e6e764320b1b01f49fc7e318721f25bd8f381be5 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 1 Jul 2020 11:07:57 -0700 Subject: [PATCH 277/440] Added a registry to hold all of the factories and adapters --- tests/e2e/factories/src/framework/adapter.ts | 3 + .../src/framework/factory-registry.spec.ts | 42 +++++++++ .../src/framework/factory-registry.ts | 87 +++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 tests/e2e/factories/src/framework/factory-registry.spec.ts create mode 100644 tests/e2e/factories/src/framework/factory-registry.ts diff --git a/tests/e2e/factories/src/framework/adapter.ts b/tests/e2e/factories/src/framework/adapter.ts index 85e90dc30ee..e04e45ad714 100644 --- a/tests/e2e/factories/src/framework/adapter.ts +++ b/tests/e2e/factories/src/framework/adapter.ts @@ -1,5 +1,8 @@ import { Model } from '../models/model'; +/** + * An interface for implementing adapters to create models. + */ export interface Adapter { /** * Creates a model or array of models using a service.. diff --git a/tests/e2e/factories/src/framework/factory-registry.spec.ts b/tests/e2e/factories/src/framework/factory-registry.spec.ts new file mode 100644 index 00000000000..df727595ac6 --- /dev/null +++ b/tests/e2e/factories/src/framework/factory-registry.spec.ts @@ -0,0 +1,42 @@ +import { AdapterTypes, FactoryRegistry } from './factory-registry'; +import { ModelFactory } from './model-factory'; +import { Product } from '../models/product'; +import { APIAdapter } from './api-adapter'; + +describe( 'FactoryRegistry', () => { + let factoryRegistry: FactoryRegistry; + + beforeEach( () => { + factoryRegistry = new FactoryRegistry(); + } ); + + it( 'should register factories once', () => { + const factory = ModelFactory.define>( ( { params } ) => { + return new Product( params ); + } ); + + expect( factoryRegistry.getFactory( Product ) ).toBeNull(); + + factoryRegistry.registerFactory( Product, factory ); + + expect( () => factoryRegistry.registerFactory( Product, factory ) ).toThrowError( /already been registered/ ); + + const loaded = factoryRegistry.getFactory( Product ); + + expect( loaded ).toBe( factory ); + } ); + + it( 'should register adapters once', () => { + const adapter = new APIAdapter( '', ( model ) => model ); + + expect( factoryRegistry.getAdapter( Product, AdapterTypes.API ) ).toBeNull(); + + factoryRegistry.registerAdapter( Product, AdapterTypes.API, adapter ); + + expect( () => factoryRegistry.registerAdapter( Product, AdapterTypes.API, adapter ) ).toThrowError( /already been registered/ ); + + const loaded = factoryRegistry.getAdapter( Product, AdapterTypes.API ); + + expect( loaded ).toBe( adapter ); + } ); +} ); diff --git a/tests/e2e/factories/src/framework/factory-registry.ts b/tests/e2e/factories/src/framework/factory-registry.ts new file mode 100644 index 00000000000..615e1541213 --- /dev/null +++ b/tests/e2e/factories/src/framework/factory-registry.ts @@ -0,0 +1,87 @@ +import { Adapter } from './adapter'; +import { Model } from '../models/model'; +import { ModelFactory } from './model-factory'; + +type Registry = { [key: string ]: T }; + +/** + * The types of adapters that can be stored in the registry. + * + * @typedef AdapterTypes + * @property {string} API "api" + * @property {string} Database "database" + * @property {string} Custom "custom" + */ +export enum AdapterTypes { + API = 'api', + Database = 'database', + Custom = 'custom' +} + +/** + * A registry that allows for us to easily manage all of our factories and related state. + */ +export class FactoryRegistry { + private readonly registry: Registry> = {}; + private readonly adapters: { [key in AdapterTypes]: Registry> } = { + api: {}, + database: {}, + custom: {}, + }; + + /** + * Registers a factory for the class. + * + * @param {Function} modelClass The class of model we're registering the factory for. + * @param {ModelFactory} factory The factory that we're registering. + */ + public registerFactory( modelClass: new () => T, factory: ModelFactory ): void { + if ( this.registry.hasOwnProperty( modelClass.name ) ) { + throw new Error( 'A factory of this type has already been registered for the model class.' ); + } + + this.registry[ modelClass.name ] = factory; + } + + /** + * Fetches a factory that was registered for the class. + * + * @param {Function} modelClass The class of model for the factory we're fetching. + */ + public getFactory( modelClass: new () => T ): ModelFactory | null { + if ( this.registry.hasOwnProperty( modelClass.name ) ) { + return this.registry[ modelClass.name ]; + } + + return null; + } + + /** + * Registers an adapter for the class. + * + * @param {Function} modelClass The class of model that we're registering the adapter for. + * @param {AdapterTypes} type The type of adapter that we're registering. + * @param {Adapter} adapter The adapter that we're registering. + */ + public registerAdapter( modelClass: new () => T, type: AdapterTypes, adapter: Adapter ): void { + if ( this.adapters[ type ].hasOwnProperty( modelClass.name ) ) { + throw new Error( 'An adapter of this type has already been registered for the model class.' ); + } + + this.adapters[ type ][ modelClass.name ] = adapter; + } + + /** + * Fetches an adapter registered for the class. + * + * @param {Function} modelClass The class of the model for the adapter we're fetching. + * @param {AdapterTypes} type The type of adapter we're fetching. + */ + public getAdapter( modelClass: new () => T, type: AdapterTypes ): Adapter | null { + if ( this.adapters[ type ].hasOwnProperty( modelClass.name ) ) { + return this.adapters[ type ][ modelClass.name ]; + } + + return null; + } +} From bc3e1b45559e48c414e97ac2efd97767f6df5c06 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 1 Jul 2020 12:08:08 -0700 Subject: [PATCH 278/440] Replaced the exported variables with functions to populate the registry --- .../src/framework/api-adapter.spec.ts | 11 ++--- .../src/framework/factory-registry.spec.ts | 42 ----------------- .../src/framework/model-factory.spec.ts | 5 ++- .../src/framework/model-registry.spec.ts | 45 +++++++++++++++++++ ...{factory-registry.ts => model-registry.ts} | 2 +- tests/e2e/factories/src/models/product.ts | 7 ++- .../factories/src/models/simple-product.ts | 42 +++++++++++++++++ 7 files changed, 102 insertions(+), 52 deletions(-) delete mode 100644 tests/e2e/factories/src/framework/factory-registry.spec.ts create mode 100644 tests/e2e/factories/src/framework/model-registry.spec.ts rename tests/e2e/factories/src/framework/{factory-registry.ts => model-registry.ts} (98%) create mode 100644 tests/e2e/factories/src/models/simple-product.ts diff --git a/tests/e2e/factories/src/framework/api-adapter.spec.ts b/tests/e2e/factories/src/framework/api-adapter.spec.ts index 075ee480391..523d4a5f300 100644 --- a/tests/e2e/factories/src/framework/api-adapter.spec.ts +++ b/tests/e2e/factories/src/framework/api-adapter.spec.ts @@ -1,7 +1,7 @@ import { Model } from '../models/model'; import { APIResponse, APIService } from '../index'; import { APIAdapter } from './api-adapter'; -import { Product } from '../models/product'; +import { SimpleProduct } from '../models/simple-product'; class MockAPI implements APIService { public get = jest.fn(); @@ -24,20 +24,21 @@ describe( 'APIModelCreator', () => { it( 'should create single instance', async () => { mockService.post.mockReturnValueOnce( new APIResponse( 200, {}, { id: 1 } ) ); - const result = await adapter.create( new Product() ); + const result = await adapter.create( new SimpleProduct() ); - expect( result ).toBeInstanceOf( Product ); + expect( result ).toBeInstanceOf( SimpleProduct ); expect( result.ID ).toBe( 1 ); expect( mockService.post.mock.calls[ 0 ][ 0 ] ).toBe( '/wc/v3/product' ); expect( mockService.post.mock.calls[ 0 ][ 1 ] ).toBe( 'test' ); } ); it( 'should create multiple instances', async () => { - mockService.post.mockReturnValueOnce( new APIResponse( 200, {}, { id: 1 } ) ) + mockService.post + .mockReturnValueOnce( new APIResponse( 200, {}, { id: 1 } ) ) .mockReturnValueOnce( new APIResponse( 200, {}, { id: 2 } ) ) .mockReturnValueOnce( new APIResponse( 200, {}, { id: 3 } ) ); - const result = await adapter.create( [ new Product(), new Product(), new Product() ] ); + const result = await adapter.create( [ new SimpleProduct(), new SimpleProduct(), new SimpleProduct() ] ); expect( result ).toBeInstanceOf( Array ); expect( result ).toHaveLength( 3 ); diff --git a/tests/e2e/factories/src/framework/factory-registry.spec.ts b/tests/e2e/factories/src/framework/factory-registry.spec.ts deleted file mode 100644 index df727595ac6..00000000000 --- a/tests/e2e/factories/src/framework/factory-registry.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { AdapterTypes, FactoryRegistry } from './factory-registry'; -import { ModelFactory } from './model-factory'; -import { Product } from '../models/product'; -import { APIAdapter } from './api-adapter'; - -describe( 'FactoryRegistry', () => { - let factoryRegistry: FactoryRegistry; - - beforeEach( () => { - factoryRegistry = new FactoryRegistry(); - } ); - - it( 'should register factories once', () => { - const factory = ModelFactory.define>( ( { params } ) => { - return new Product( params ); - } ); - - expect( factoryRegistry.getFactory( Product ) ).toBeNull(); - - factoryRegistry.registerFactory( Product, factory ); - - expect( () => factoryRegistry.registerFactory( Product, factory ) ).toThrowError( /already been registered/ ); - - const loaded = factoryRegistry.getFactory( Product ); - - expect( loaded ).toBe( factory ); - } ); - - it( 'should register adapters once', () => { - const adapter = new APIAdapter( '', ( model ) => model ); - - expect( factoryRegistry.getAdapter( Product, AdapterTypes.API ) ).toBeNull(); - - factoryRegistry.registerAdapter( Product, AdapterTypes.API, adapter ); - - expect( () => factoryRegistry.registerAdapter( Product, AdapterTypes.API, adapter ) ).toThrowError( /already been registered/ ); - - const loaded = factoryRegistry.getAdapter( Product, AdapterTypes.API ); - - expect( loaded ).toBe( adapter ); - } ); -} ); diff --git a/tests/e2e/factories/src/framework/model-factory.spec.ts b/tests/e2e/factories/src/framework/model-factory.spec.ts index 58819159eec..4850f77b854 100644 --- a/tests/e2e/factories/src/framework/model-factory.spec.ts +++ b/tests/e2e/factories/src/framework/model-factory.spec.ts @@ -1,6 +1,7 @@ import { ModelFactory } from './model-factory'; import { Adapter } from './adapter'; import { Product } from '../models/product'; +import { SimpleProduct } from '../models/simple-product'; class MockAdapter implements Adapter { public create = jest.fn(); @@ -14,7 +15,7 @@ describe( 'ModelFactory', () => { mockAdapter = new MockAdapter(); factory = ModelFactory.define>( ( { params } ) => { - return new Product( params ); + return new SimpleProduct( params ); }, ); } ); @@ -26,7 +27,7 @@ describe( 'ModelFactory', () => { it( 'should create using adapter', async () => { factory.setAdapter( mockAdapter ); - const expectedModel = new Product( { Name: 'test2' } ); + const expectedModel = new SimpleProduct( { Name: 'test2' } ); expectedModel.onCreated( { id: 1 } ); mockAdapter.create.mockReturnValueOnce( Promise.resolve( expectedModel ) ); diff --git a/tests/e2e/factories/src/framework/model-registry.spec.ts b/tests/e2e/factories/src/framework/model-registry.spec.ts new file mode 100644 index 00000000000..247b9fb0d29 --- /dev/null +++ b/tests/e2e/factories/src/framework/model-registry.spec.ts @@ -0,0 +1,45 @@ +import { AdapterTypes, ModelRegistry } from './model-registry'; +import { ModelFactory } from './model-factory'; +import { Product } from '../models/product'; +import { APIAdapter } from './api-adapter'; +import { SimpleProduct } from '../models/simple-product'; + +describe( 'ModelRegistry', () => { + let factoryRegistry: ModelRegistry; + + beforeEach( () => { + factoryRegistry = new ModelRegistry(); + } ); + + it( 'should register factories once', () => { + const factory = ModelFactory.define>( ( { params } ) => { + return new SimpleProduct( params ); + } ); + + expect( factoryRegistry.getFactory( SimpleProduct ) ).toBeNull(); + + factoryRegistry.registerFactory( SimpleProduct, factory ); + + expect( () => factoryRegistry.registerFactory( SimpleProduct, factory ) ) + .toThrowError( /already been registered/ ); + + const loaded = factoryRegistry.getFactory( SimpleProduct ); + + expect( loaded ).toBe( factory ); + } ); + + it( 'should register adapters once', () => { + const adapter = new APIAdapter( '', ( model ) => model ); + + expect( factoryRegistry.getAdapter( SimpleProduct, AdapterTypes.API ) ).toBeNull(); + + factoryRegistry.registerAdapter( SimpleProduct, AdapterTypes.API, adapter ); + + expect( () => factoryRegistry.registerAdapter( SimpleProduct, AdapterTypes.API, adapter ) ) + .toThrowError( /already been registered/ ); + + const loaded = factoryRegistry.getAdapter( SimpleProduct, AdapterTypes.API ); + + expect( loaded ).toBe( adapter ); + } ); +} ); diff --git a/tests/e2e/factories/src/framework/factory-registry.ts b/tests/e2e/factories/src/framework/model-registry.ts similarity index 98% rename from tests/e2e/factories/src/framework/factory-registry.ts rename to tests/e2e/factories/src/framework/model-registry.ts index 615e1541213..0ad577adc4c 100644 --- a/tests/e2e/factories/src/framework/factory-registry.ts +++ b/tests/e2e/factories/src/framework/model-registry.ts @@ -21,7 +21,7 @@ export enum AdapterTypes { /** * A registry that allows for us to easily manage all of our factories and related state. */ -export class FactoryRegistry { +export class ModelRegistry { private readonly registry: Registry> = {}; private readonly adapters: { [key in AdapterTypes]: Registry> } = { api: {}, diff --git a/tests/e2e/factories/src/models/product.ts b/tests/e2e/factories/src/models/product.ts index 198340d3797..33b379d7f8b 100644 --- a/tests/e2e/factories/src/models/product.ts +++ b/tests/e2e/factories/src/models/product.ts @@ -1,11 +1,14 @@ import { Model } from './model'; import { DeepPartial } from 'fishery'; -export class Product extends Model { +/** + * The base class for all product types. + */ +export abstract class Product extends Model { public readonly Name: string = ''; public readonly RegularPrice: string = ''; - public constructor( partial: DeepPartial = {} ) { + protected constructor( partial: DeepPartial = {} ) { super( partial ); Object.assign( this, partial ); } diff --git a/tests/e2e/factories/src/models/simple-product.ts b/tests/e2e/factories/src/models/simple-product.ts new file mode 100644 index 00000000000..46c81196b14 --- /dev/null +++ b/tests/e2e/factories/src/models/simple-product.ts @@ -0,0 +1,42 @@ +import { DeepPartial } from 'fishery'; +import { Product } from './product'; +import { AdapterTypes, ModelRegistry } from '../framework/model-registry'; +import { ModelFactory } from '../framework/model-factory'; +import { APIAdapter } from '../framework/api-adapter'; + +export class SimpleProduct extends Product { + public constructor( partial: DeepPartial = {} ) { + super( partial ); + Object.assign( this, partial ); + } +} + +/** + * Registers the simple product factory and adapters. + * + * @param {ModelRegistry} registry The registry to hold the model reference. + */ +export function registerSimpleProduct( registry: ModelRegistry ) { + if ( null !== registry.getFactory( SimpleProduct ) ) { + return; + } + + const factory = ModelFactory.define>( + ( { params } ) => { + return new SimpleProduct( params ); + }, + ); + registry.registerFactory( SimpleProduct, factory ); + + const apiAdapter = new APIAdapter( + '/wc/v3/products', + ( model ) => { + return { + type: 'simple', + name: model.Name, + regular_price: model.RegularPrice, + }; + }, + ); + registry.registerAdapter( SimpleProduct, AdapterTypes.API, apiAdapter ); +} From b4c1f3ca8f6513811622f0c1d79654acbf7a5de6 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 1 Jul 2020 12:31:20 -0700 Subject: [PATCH 279/440] Fixed the POST, PUT, and PATCH Axios service actions --- .../e2e/factories/src/framework/axios/axios-api-service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/factories/src/framework/axios/axios-api-service.ts b/tests/e2e/factories/src/framework/axios/axios-api-service.ts index 5617b52d3d9..9258c7d7bf3 100644 --- a/tests/e2e/factories/src/framework/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/framework/axios/axios-api-service.ts @@ -58,7 +58,7 @@ export class AxiosAPIService implements APIService { endpoint: string, data?: any, ): Promise> { - return this.client.post( endpoint, { data } ); + return this.client.post( endpoint, data ); } /** @@ -72,7 +72,7 @@ export class AxiosAPIService implements APIService { endpoint: string, data?: any, ): Promise> { - return this.client.put( endpoint, { data } ); + return this.client.put( endpoint, data ); } /** @@ -86,7 +86,7 @@ export class AxiosAPIService implements APIService { endpoint: string, data?: any, ): Promise> { - return this.client.patch( endpoint, { data } ); + return this.client.patch( endpoint, data ); } /** From 68daac3a949444f6bdd10a2d83409f823fc10810 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 1 Jul 2020 13:58:12 -0700 Subject: [PATCH 280/440] Added a utility for initializing all of the APIAdapters with a service --- .../factories/src/framework/model-registry.ts | 51 +++++++++++++++++-- tests/e2e/factories/src/framework/utils.ts | 28 ++++++++++ .../factories/src/models/simple-product.ts | 2 +- 3 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 tests/e2e/factories/src/framework/utils.ts diff --git a/tests/e2e/factories/src/framework/model-registry.ts b/tests/e2e/factories/src/framework/model-registry.ts index 0ad577adc4c..96b9cf6ac35 100644 --- a/tests/e2e/factories/src/framework/model-registry.ts +++ b/tests/e2e/factories/src/framework/model-registry.ts @@ -22,7 +22,7 @@ export enum AdapterTypes { * A registry that allows for us to easily manage all of our factories and related state. */ export class ModelRegistry { - private readonly registry: Registry> = {}; + private readonly factories: Registry> = {}; private readonly adapters: { [key in AdapterTypes]: Registry> } = { api: {}, database: {}, @@ -36,11 +36,11 @@ export class ModelRegistry { * @param {ModelFactory} factory The factory that we're registering. */ public registerFactory( modelClass: new () => T, factory: ModelFactory ): void { - if ( this.registry.hasOwnProperty( modelClass.name ) ) { + if ( this.factories.hasOwnProperty( modelClass.name ) ) { throw new Error( 'A factory of this type has already been registered for the model class.' ); } - this.registry[ modelClass.name ] = factory; + this.factories[ modelClass.name ] = factory; } /** @@ -49,8 +49,8 @@ export class ModelRegistry { * @param {Function} modelClass The class of model for the factory we're fetching. */ public getFactory( modelClass: new () => T ): ModelFactory | null { - if ( this.registry.hasOwnProperty( modelClass.name ) ) { - return this.registry[ modelClass.name ]; + if ( this.factories.hasOwnProperty( modelClass.name ) ) { + return this.factories[ modelClass.name ]; } return null; @@ -84,4 +84,45 @@ export class ModelRegistry { return null; } + + /** + * Fetches all of the adapters of a given type from the registry. + * + * @param {AdapterTypes} type The type of adapters to fetch. + */ + public getAdapters( type: AdapterTypes ): Adapter[] { + return Object.values( this.adapters[ type ] ); + } + + /** + * Changes the adapter a factory is using. + * + * @param {Function} modelClass The class of the model factory we're changing. + * @param {AdapterTypes} type The type of adapter to set. + */ + public changeFactoryAdapter( modelClass: new () => T, type: AdapterTypes ): void { + const factory = this.getFactory( modelClass ); + if ( ! factory ) { + throw new Error( 'No factory defined for this model class.' ); + } + const adapter = this.getAdapter( modelClass, type ); + if ( ! adapter ) { + throw new Error( 'No adapter of this type registered for this model class.' ); + } + + factory.setAdapter( adapter ); + } + + /** + * Changes the adapters of all factories to the given type or null if one is not registered for that type. + * + * @param {AdapterTypes} type The type of adapter to set. + */ + public changeAllFactoryAdapters( type: AdapterTypes ): void { + for ( const key in this.factories ) { + this.factories[ key ].setAdapter( + this.adapters[ type ][ key ] || null, + ); + } + } } diff --git a/tests/e2e/factories/src/framework/utils.ts b/tests/e2e/factories/src/framework/utils.ts new file mode 100644 index 00000000000..3a5ecf7017d --- /dev/null +++ b/tests/e2e/factories/src/framework/utils.ts @@ -0,0 +1,28 @@ +import { AdapterTypes, ModelRegistry } from './model-registry'; +import { APIAdapter } from './api-adapter'; +import { AxiosAPIService } from './axios/axios-api-service'; + +/** + * Initializes all of the APIAdapters with a client to communicate with the API. + * + * @param {ModelRegistry} registry The model registry that we want to initialize. + * @param {string} apiURL The base URL for the API. + * @param {string} consumerKey The OAuth consumer key for the API service. + * @param {string} consumerSecret The OAuth consumer secret for the API service. + */ +export function initializeAPIAdapters( + registry: ModelRegistry, + apiURL: string, + consumerKey: string, + consumerSecret: string, +): void { + const adapters = registry.getAdapters( AdapterTypes.API ) as APIAdapter[]; + if ( ! adapters.length ) { + return; + } + + const apiService = new AxiosAPIService( apiURL, consumerKey, consumerSecret ); + for ( const adapter of adapters ) { + adapter.setAPIService( apiService ); + } +} diff --git a/tests/e2e/factories/src/models/simple-product.ts b/tests/e2e/factories/src/models/simple-product.ts index 46c81196b14..0996940de74 100644 --- a/tests/e2e/factories/src/models/simple-product.ts +++ b/tests/e2e/factories/src/models/simple-product.ts @@ -16,7 +16,7 @@ export class SimpleProduct extends Product { * * @param {ModelRegistry} registry The registry to hold the model reference. */ -export function registerSimpleProduct( registry: ModelRegistry ) { +export function registerSimpleProduct( registry: ModelRegistry ): void { if ( null !== registry.getFactory( SimpleProduct ) ) { return; } From b8eb65aacc27fb48840632fe9cefe03b3b7c8f9d Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 1 Jul 2020 14:22:01 -0700 Subject: [PATCH 281/440] Added missing @wordpress/eslint-plugin for factory package --- package-lock.json | 3994 +++++++++++++++++++-------------------------- package.json | 1 + 2 files changed, 1668 insertions(+), 2327 deletions(-) diff --git a/package-lock.json b/package-lock.json index d890ecee0a6..6641cb3bf84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -320,28 +320,37 @@ } }, "@babel/helper-builder-react-jsx": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz", - "integrity": "sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz", + "integrity": "sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/types": "^7.9.0" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/types": "^7.10.4" }, "dependencies": { + "@babel/helper-annotate-as-pure": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", + "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -355,29 +364,47 @@ } }, "@babel/helper-builder-react-jsx-experimental": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.5.tgz", - "integrity": "sha512-HAagjAC93tk748jcXpZ7oYRZH485RCq/+yEv9SIWezHRPv9moZArTnkUNciUNzvwHUABmiWKlcxJvMcu59UwTg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.4.tgz", + "integrity": "sha512-LyacH/kgQPgLAuaWrvvq1+E7f5bLyT8jXCh7nM67sRsy2cpIGfgWJ+FCnAKQXfY+F0tXUaN6FqLkp4JiCzdK8Q==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-module-imports": "^7.8.3", - "@babel/types": "^7.9.5" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-module-imports": "^7.10.4", + "@babel/types": "^7.10.4" }, "dependencies": { + "@babel/helper-annotate-as-pure": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", + "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -1851,18 +1878,18 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", - "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", + "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true } } @@ -2566,21 +2593,21 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.4.tgz", - "integrity": "sha512-Mjqf3pZBNLt854CK0C/kRuXAnE6H/bo7xYojP+WGtX8glDGSibcwnsWwhwoSuRg0+EBnxPC1ouVnuetUIlPSAw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz", + "integrity": "sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A==", "dev": true, "requires": { - "@babel/helper-builder-react-jsx": "^7.9.0", - "@babel/helper-builder-react-jsx-experimental": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.8.3" + "@babel/helper-builder-react-jsx": "^7.10.4", + "@babel/helper-builder-react-jsx-experimental": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-jsx": "^7.10.4" }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true } } @@ -2612,21 +2639,53 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.6.tgz", - "integrity": "sha512-qcmiECD0mYOjOIt8YHNsAP1SxPooC/rDmfmiSK9BNY72EitdSc7l44WTEklaWuFtbOEBjNhWWyph/kOImbNJ4w==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.4.tgz", + "integrity": "sha512-8ULlGv8p+Vuxu+kz2Y1dk6MYS2b/Dki+NO6/0ZlfSj5tMalfDL7jI/o/2a+rrWLqSXvnadEqc2WguB4gdQIxZw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", "resolve": "^1.8.1", "semver": "^5.5.1" }, "dependencies": { + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true } } @@ -2888,6 +2947,24 @@ "regenerator-runtime": "^0.13.2" } }, + "@babel/runtime-corejs3": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", + "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, "@babel/template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", @@ -3121,9 +3198,9 @@ } }, "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "tar": { @@ -5103,194 +5180,12 @@ "whatwg-url": "^7.0.0" }, "dependencies": { - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -5836,152 +5731,6 @@ "write-json-file": "^3.2.0" }, "dependencies": { - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", @@ -5995,27 +5744,6 @@ "type-fest": "^0.3.0" } }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", @@ -6032,29 +5760,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -6308,17 +6013,6 @@ "@lerna/query-graph": "3.18.5", "figgy-pudding": "^3.5.1", "p-queue": "^4.0.0" - }, - "dependencies": { - "p-queue": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-4.0.0.tgz", - "integrity": "sha512-3cRXXn3/O0o3+eVmUroJPSj/esxoEFIm0ZOno/T+NzG/VZgPOqQ8WKmlNqubSEpZmCIngEy34unkHGg83ZIBmg==", - "dev": true, - "requires": { - "eventemitter3": "^3.1.0" - } - } } }, "@lerna/symlink-binary": { @@ -6528,38 +6222,29 @@ } }, "@octokit/auth-token": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.0.tgz", - "integrity": "sha512-eoOVMjILna7FVQf96iWc3+ZtE/ZT6y8ob8ZzcqKY1ibSQCnu4O/B7pJvzMx5cyZ/RjAff6DAdEb0O0Cjcxidkg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.2.tgz", + "integrity": "sha512-jE/lE/IKIz2v1+/P0u4fJqv0kYwXOTujKemJMFr6FeopsxlIK3+wKDCJGnysg81XID5TgZQbIfuJ5J0lnTiuyQ==", "dev": true, "requires": { - "@octokit/types": "^2.0.0" + "@octokit/types": "^5.0.0" } }, "@octokit/endpoint": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz", - "integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.3.tgz", + "integrity": "sha512-Y900+r0gIz+cWp6ytnkibbD95ucEzDSKzlEnaWS52hbCDNcCJYO5mRmWW7HRAnDc7am+N/5Lnd8MppSaTYx1Yg==", "dev": true, "requires": { - "@octokit/types": "^2.11.1", + "@octokit/types": "^5.0.0", "is-plain-object": "^3.0.0", "universal-user-agent": "^5.0.0" }, "dependencies": { "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "dev": true, - "requires": { - "isobject": "^4.0.0" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", "dev": true }, "universal-user-agent": { @@ -6586,6 +6271,17 @@ "dev": true, "requires": { "@octokit/types": "^2.0.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } } }, "@octokit/plugin-request-log": { @@ -6602,17 +6298,28 @@ "requires": { "@octokit/types": "^2.0.1", "deprecation": "^2.3.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } } }, "@octokit/request": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz", - "integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.5.tgz", + "integrity": "sha512-atAs5GAGbZedvJXXdjtKljin+e2SltEs48B3naJjqWupYl2IUBbB/CJisyjbNHcKpHzb3E+OYEZ46G8eakXgQg==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", "@octokit/request-error": "^2.0.0", - "@octokit/types": "^2.11.1", + "@octokit/types": "^5.0.0", "deprecation": "^2.0.0", "is-plain-object": "^3.0.0", "node-fetch": "^2.3.0", @@ -6621,29 +6328,20 @@ }, "dependencies": { "@octokit/request-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.0.tgz", - "integrity": "sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.2.tgz", + "integrity": "sha512-2BrmnvVSV1MXQvEkrb9zwzP0wXFNbPJij922kYBTLIlIafukrGOb+ABBT2+c6wZiuyWDH1K1zmjGQ0toN/wMWw==", "dev": true, "requires": { - "@octokit/types": "^2.0.0", + "@octokit/types": "^5.0.1", "deprecation": "^2.0.0", "once": "^1.4.0" } }, "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "dev": true, - "requires": { - "isobject": "^4.0.0" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", "dev": true }, "node-fetch": { @@ -6672,12 +6370,23 @@ "@octokit/types": "^2.0.0", "deprecation": "^2.0.0", "once": "^1.4.0" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } } }, "@octokit/rest": { - "version": "16.43.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.1.tgz", - "integrity": "sha512-gfFKwRT/wFxq5qlNjnW2dh+qh74XgTQ2B179UX5K1HYCluioWj8Ndbgqw2PVqa1NnVJkGHp2ovMpVn/DImlmkw==", + "version": "16.43.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz", + "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==", "dev": true, "requires": { "@octokit/auth-token": "^2.4.0", @@ -6699,9 +6408,9 @@ } }, "@octokit/types": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz", - "integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.0.1.tgz", + "integrity": "sha512-GorvORVwp244fGKEt3cgt/P+M0MGy4xEDbckw+K5ojEezxyMDgCaYPKVct+/eWQfZXOT7uq0xRpmrl/+hliabA==", "dev": true, "requires": { "@types/node": ">= 8" @@ -6769,6 +6478,12 @@ "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } + }, + "p-queue": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz", + "integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng==", + "dev": true } } }, @@ -6850,6 +6565,12 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -6919,12 +6640,24 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, "@types/node": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.0.tgz", "integrity": "sha512-Jrb/x3HT4PTJp6a4avhmJCDEVrPdqLfl3e8GGMbpkGGdwAV5UGlIs4vVEfsHHfylZVOKZWpOqmqFH8CbfOZ6kg==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, "@types/p-queue": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz", @@ -6990,6 +6723,104 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.1.0.tgz", + "integrity": "sha512-D52KwdgkjYc+fmTZKW7CZpH5ZBJREJKZXRrveMiRCmlzZ+Rw9wRVJ1JAmHQ9b/+Ehy1ZeaylofDB9wwXUt83wg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "3.1.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz", + "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz", + "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@typescript-eslint/experimental-utils": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.26.0.tgz", @@ -7013,6 +6844,97 @@ } } }, + "@typescript-eslint/parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.1.0.tgz", + "integrity": "sha512-NcDSJK8qTA2tPfyGiPes9HtVKLbksmuYjlgGAUs7Ld2K0swdWibnCq9IJx9kJN8JJdgUJSorFiGaPHBgH81F/Q==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "3.1.0", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz", + "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz", + "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@typescript-eslint/typescript-estree": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.26.0.tgz", @@ -7352,9 +7274,9 @@ } }, "@wordpress/browserslist-config": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.6.0.tgz", - "integrity": "sha512-vRgzGoxhcNVChBP30XZlyK4w6r/9ZpO+Fi1dzmButp31lUEb1pT5WBxTIQl3HE0JZ9YTEJ00WWGO5sjGi5MHZA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.7.0.tgz", + "integrity": "sha512-pB45JlfmHuEigNFZ1X+CTgIsOT3/TTb9iZxw1DHXge/7ytY8FNhtcNwTfF9IgnS6/xaFRZBqzw4DyH4sP1Lyxg==", "dev": true }, "@wordpress/e2e-test-utils": { @@ -7371,115 +7293,69 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, - "@tannin/compile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@tannin/compile/-/compile-1.1.0.tgz", - "integrity": "sha512-n8m9eNDfoNZoxdvWiTfW/hSPhehzLJ3zW7f8E7oT6mCROoMNWCB4TYtv041+2FMAxweiE0j7i1jubQU4MEC/Gg==", - "dev": true, - "requires": { - "@tannin/evaluate": "^1.2.0", - "@tannin/postfix": "^1.1.0" - } - }, - "@tannin/evaluate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tannin/evaluate/-/evaluate-1.2.0.tgz", - "integrity": "sha512-3ioXvNowbO/wSrxsDG5DKIMxC81P0QrQTYai8zFNY+umuoHWRPbQ/TuuDEOju9E+jQDXmj6yI5GyejNuh8I+eg==", - "dev": true - }, - "@tannin/plural-forms": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@tannin/plural-forms/-/plural-forms-1.1.0.tgz", - "integrity": "sha512-xl9R2mDZO/qiHam1AgMnAES6IKIg7OBhcXqy6eDsRCdXuxAFPcjrej9HMjyCLE0DJ/8cHf0i5OQTstuBRhpbHw==", - "dev": true, - "requires": { - "@tannin/compile": "^1.1.0" - } - }, - "@tannin/postfix": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.1.0.tgz", - "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==", - "dev": true - }, - "@wordpress/i18n": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.12.0.tgz", - "integrity": "sha512-QkdHd2Z2yTFItBnnzzjMW4IXJlofWMivct4BkgwRivrG7kLxE7nd2xMG3+hFkkdYGdzE67u8vmin0gmQ+14yPA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "gettext-parser": "^1.3.1", - "lodash": "^4.17.15", - "memize": "^1.1.0", - "sprintf-js": "^1.1.1", - "tannin": "^1.2.0" - } - }, - "@wordpress/keycodes": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.12.0.tgz", - "integrity": "sha512-7fUwfquRLmE4CvJahZTHdNn31heoDcyZ4acgEQR4iKYsKjX6dF1coZjUe693xbf/4r8GmsOg0/uYDImMdDm+1Q==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "@wordpress/i18n": "^3.12.0", - "lodash": "^4.17.15" - } - }, - "@wordpress/url": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.14.0.tgz", - "integrity": "sha512-TSp6vDpmBTiYTwhlc5mleT4g3mOsw2w5bu5AcqiX344o48rju+ktuTZBQofNIhl3m04zYtl6YR14M1dsXKTsNQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "lodash": "^4.17.15", - "qs": "^6.5.2", - "react-native-url-polyfill": "^1.1.2" - } - }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, - "memize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", - "integrity": "sha512-K4FcPETOMTwe7KL2LK0orMhpOmWD2wRGwWWpbZy0fyArwsyIKR8YJVz8+efBAh3BO4zPqlSICu4vsLTRRqtFAg==", - "dev": true - }, "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", "dev": true + } + } + }, + "@wordpress/eslint-plugin": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-7.1.0.tgz", + "integrity": "sha512-FTrKkpEa8vZg7/7M6GBhd1YW24hnh5rFGzKgKX4MGyB0Jw8GGSwld9J23eRbQ5JQWGFP/tmOMeiu6W1/arxy7Q==", + "dev": true, + "requires": { + "@wordpress/prettier-config": "^0.3.0", + "babel-eslint": "^10.1.0", + "eslint-config-prettier": "^6.10.1", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-jsdoc": "^26.0.0", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-react": "^7.20.0", + "eslint-plugin-react-hooks": "^4.0.4", + "globals": "^12.0.0", + "prettier": "npm:wp-prettier@2.0.5", + "requireindex": "^1.2.0" + }, + "dependencies": { + "eslint-plugin-react-hooks": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.5.tgz", + "integrity": "sha512-3YLSjoArsE2rUwL8li4Yxx1SUg3DQWp+78N3bcJQGWVZckcp+yeQGsap/MSq05+thJk57o+Ww4PtZukXGL02TQ==", + "dev": true }, - "tannin": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tannin/-/tannin-1.2.0.tgz", - "integrity": "sha512-U7GgX/RcSeUETbV7gYgoz8PD7Ni4y95pgIP/Z6ayI3CfhSujwKEBlGFTCRN+Aqnuyf4AN2yHL+L8x+TCGjb9uA==", + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { - "@tannin/plural-forms": "^1.1.0" + "type-fest": "^0.8.1" } } } }, "@wordpress/i18n": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.13.0.tgz", - "integrity": "sha512-eMlOvg2vYKmGV4C1vPrWuOEyskxMeCGoQJ0N3mQ6t7iWKs4bKWAJGlGL5QXMwN7xJJ863h3L7mrbLM3zKVrF1g==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.14.0.tgz", + "integrity": "sha512-FQbSggdvkdS+IWMNhTl3n1nThqfzAPxORvoFpjDma7DOwuRKOA8iPyomwacfeG/krAeaurj1DIDzDvZh9Ex79w==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -7491,9 +7367,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", - "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -7514,9 +7390,9 @@ } }, "@wordpress/jest-console": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.6.0.tgz", - "integrity": "sha512-0XpvIvgjdmVYYAA0l2XUktq+Z18upDhvaMFDdK8JDxu+vsso0XyFee5VNyHd/PvjInPrTXHoqGj0tx48uUqxhQ==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.7.0.tgz", + "integrity": "sha512-+PLH0jbY7xuKJckrkbtRk7zfyg4YDHFVulqydEBzSiU+LsZ2f/9hdRbb4/JDUneG7NpROO2smqxmaACxu5o9gw==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -7525,9 +7401,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -7810,9 +7686,9 @@ } }, "@types/yargs": { - "version": "13.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", - "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", + "version": "13.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", + "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -7824,12 +7700,6 @@ "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, "babel-jest": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", @@ -7905,12 +7775,6 @@ } } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "cssom": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", @@ -8104,15 +7968,6 @@ "pretty-format": "^24.9.0" } }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, "jest-each": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", @@ -8153,12 +8008,6 @@ "jest-util": "^24.9.0" } }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", - "dev": true - }, "jest-haste-map": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", @@ -8374,20 +8223,6 @@ "source-map": "^0.6.0" } }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" - } - }, "jest-worker": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", @@ -8438,12 +8273,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -8514,12 +8343,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -8535,18 +8358,6 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -8648,20 +8459,20 @@ } }, "@wordpress/keycodes": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.13.0.tgz", - "integrity": "sha512-Bm3N4Qf5qLXds+eflM+JXD15VEW/7IQ7eqWt9/UhsssuDTMTMbXnYjxOAh5zoVi2toAMSMs8EYpV28V+Qv0ZjA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.14.0.tgz", + "integrity": "sha512-R/0orMutajuQ1d1kFFIvksXKR5C5TtszEkbnxSfdNlKaOW7p9Srv8+8m2QqM+AKNvEGMaq6cn7BfDtTbZ33Dbw==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", - "@wordpress/i18n": "^3.13.0", + "@wordpress/i18n": "^3.14.0", "lodash": "^4.17.15" }, "dependencies": { "@babel/runtime": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", - "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -8681,10 +8492,16 @@ } } }, + "@wordpress/prettier-config": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-0.3.0.tgz", + "integrity": "sha512-wL1ztV+so5Ttwz23lDmb8ZmREmND96sf+Dh/kbP2nyAw/DWt3K8uj31qbczVmjwfoetTiRoH9Z1CasgPs4bccg==", + "dev": true + }, "@wordpress/url": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.16.0.tgz", - "integrity": "sha512-xja1pOwIEt7DgqSSyRP1oVAQtayoCcvcCyj4yvq/8qiRpkNlzn0HNWmzKL/qBkAJhPGM4Q6D4ehvOfK4x4/Qtw==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.17.0.tgz", + "integrity": "sha512-4OBUy8IKZlobXe41GASw+p5xP/Nvh+HSzfhTN+BU0OggnIsXvZpf0iBYRYGp6M60ne8MkeEoQg9rMM22Osh9Cg==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -8694,9 +8511,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", - "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -8834,21 +8651,28 @@ } }, "airbnb-prop-types": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz", - "integrity": "sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz", + "integrity": "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==", "dev": true, "requires": { - "array.prototype.find": "^2.1.0", - "function.prototype.name": "^1.1.1", - "has": "^1.0.3", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", + "array.prototype.find": "^2.1.1", + "function.prototype.name": "^1.1.2", + "is-regex": "^1.1.0", + "object-is": "^1.1.2", "object.assign": "^4.1.0", - "object.entries": "^1.1.0", + "object.entries": "^1.1.2", "prop-types": "^15.7.2", "prop-types-exact": "^1.2.0", - "react-is": "^16.9.0" + "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + } } }, "ajv": { @@ -9079,6 +8903,33 @@ } } }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -9127,6 +8978,17 @@ "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -9168,6 +9030,17 @@ "es-abstract": "^1.17.0-next.1" } }, + "array.prototype.flatmap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", + "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -9245,6 +9118,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -9369,6 +9248,12 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, + "axe-core": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.5.5.tgz", + "integrity": "sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==", + "dev": true + }, "axios": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", @@ -9378,6 +9263,12 @@ "follow-redirects": "1.5.10" } }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -10767,6 +10658,17 @@ "htmlparser2": "^3.9.1", "lodash": "^4.15.0", "parse5": "^3.0.1" + }, + "dependencies": { + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "dev": true, + "requires": { + "@types/node": "*" + } + } } }, "chokidar": { @@ -10897,12 +10799,6 @@ "safe-buffer": "^5.0.1" } }, - "cjk-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cjk-regex/-/cjk-regex-1.0.2.tgz", - "integrity": "sha512-NwSMtwULPLk8Ka9DEUcoFXhMRnV/bpyKDnoyDiVw/Qy5przhvHTvXLcsKaOmx13o8J4XEsPVT1baoCUj5zQs3w==", - "dev": true - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -11241,6 +11137,12 @@ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true }, + "comment-parser": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.5.tgz", + "integrity": "sha512-iH9YA35ccw94nx5244GVkpyC9eVTsL71jZz6iz5w6RIf79JLF2AsXHXq9p6Oaohyl3sx5qSMnGsWUDFIAfWL4w==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -11248,9 +11150,9 @@ "dev": true }, "compare-func": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", - "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz", + "integrity": "sha512-sq2sWtrqKPkEXAC8tEJA1+BqAH9GbFkGBtUOqrUX57VSfwp8xyktctk+uLoRy5eccTdxzDcVIztlYDpKs3Jv1Q==", "dev": true, "requires": { "array-ify": "^1.0.0", @@ -11342,9 +11244,9 @@ "dev": true }, "conventional-changelog-angular": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.6.tgz", - "integrity": "sha512-QDEmLa+7qdhVIv8sFZfVxU1VSyVvnXPsxq8Vam49mKUcO1Z8VTLEJk9uI21uiJUsnmm0I4Hrsdc9TgkOQo9WSA==", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.10.tgz", + "integrity": "sha512-k7RPPRs0vp8+BtPsM9uDxRl6KcgqtCJmzRD1wRtgqmhQ96g8ifBGo9O/TZBG23jqlXS/rg8BKRDELxfnQQGiaA==", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -11387,6 +11289,12 @@ "locate-path": "^2.0.0" } }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -11492,55 +11400,70 @@ "dev": true }, "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", "dev": true, "requires": { + "inherits": "^2.0.4", "readable-stream": "2 || 3" } } } }, "conventional-changelog-preset-loader": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.0.tgz", - "integrity": "sha512-/rHb32J2EJnEXeK4NpDgMaAVTFZS3o1ExmjKMtYVgIC4MQn0vkNSbYpdGRotkfGGRWiqk3Ri3FBkiZGbAfIfOQ==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", "dev": true }, "conventional-changelog-writer": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.11.tgz", - "integrity": "sha512-g81GQOR392I+57Cw3IyP1f+f42ME6aEkbR+L7v1FBBWolB0xkjKTeCWVguzRrp6UiT1O6gBpJbEy2eq7AnV1rw==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.16.tgz", + "integrity": "sha512-jmU1sDJDZpm/dkuFxBeRXvyNcJQeKhGtVcFFkwTphUAzyYWcwz2j36Wcv+Mv2hU3tpvLMkysOPXJTLO55AUrYQ==", "dev": true, "requires": { "compare-func": "^1.3.1", - "conventional-commits-filter": "^2.0.2", + "conventional-commits-filter": "^2.0.6", "dateformat": "^3.0.0", - "handlebars": "^4.4.0", + "handlebars": "^4.7.6", "json-stringify-safe": "^5.0.1", "lodash": "^4.17.15", - "meow": "^5.0.0", + "meow": "^7.0.0", "semver": "^6.0.0", "split": "^1.0.0", "through2": "^3.0.0" }, "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", "dev": true }, "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } }, "dateformat": { @@ -11550,40 +11473,53 @@ "dev": true }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "handlebars": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" } }, "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -11593,112 +11529,137 @@ "dev": true }, "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", + "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", "dev": true, "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" + "@types/minimist": "^1.2.0", + "arrify": "^2.0.1", + "camelcase": "^6.0.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { - "p-try": "^1.0.0" + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" } }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } } }, "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } } }, "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, "semver": { @@ -11707,48 +11668,61 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { + "min-indent": "^1.0.0" + } + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", "readable-stream": "2 || 3" } }, "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "dev": true + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } } } }, "conventional-commits-filter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz", - "integrity": "sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.6.tgz", + "integrity": "sha512-4g+sw8+KA50/Qwzfr0hL5k5NWxqtrOVw4DDk3/h6L85a9Gz0/Eqp3oP+CWCNfesBvZZZEFHF7OTEbRe+yYSyKw==", "dev": true, "requires": { "lodash.ismatch": "^4.4.0", @@ -11756,72 +11730,86 @@ } }, "conventional-commits-parser": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.8.tgz", - "integrity": "sha512-YcBSGkZbYp7d+Cr3NWUeXbPDFUN6g3SaSIzOybi8bjHL5IJ5225OSCxJJ4LgziyEJ7AaJtE9L2/EU6H7Nt/DDQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", + "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", "dev": true, "requires": { "JSONStream": "^1.0.4", "is-text-path": "^1.0.1", "lodash": "^4.17.15", - "meow": "^5.0.0", + "meow": "^7.0.0", "split2": "^2.0.0", "through2": "^3.0.0", "trim-off-newlines": "^1.0.0" }, "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", "dev": true }, "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -11831,148 +11819,180 @@ "dev": true }, "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", + "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", "dev": true, "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" + "@types/minimist": "^1.2.0", + "arrify": "^2.0.1", + "camelcase": "^6.0.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { - "p-try": "^1.0.0" + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" } }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } } }, "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } } }, "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { + "min-indent": "^1.0.0" + } + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", "readable-stream": "2 || 3" } }, "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "dev": true + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } } } @@ -12258,6 +12278,12 @@ } } }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -12497,6 +12523,12 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "dev": true + }, "dargs": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", @@ -12515,12 +12547,6 @@ "assert-plus": "^1.0.0" } }, - "dashify": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz", - "integrity": "sha1-agdBWgHJH69KMuONnfunH2HLIP4=", - "dev": true - }, "data-urls": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", @@ -12966,42 +12992,6 @@ "safer-buffer": "^2.1.0" } }, - "editorconfig": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.14.2.tgz", - "integrity": "sha512-tghjvKwo1gakrhFiZWlbo5ILWAfnuOu1JFztW0li+vzbnInN0CMZuF4F0T/Pnn9UWpT7Mr1aFTWdHVuxiR9K9A==", - "dev": true, - "requires": { - "bluebird": "^3.0.5", - "commander": "^2.9.0", - "lru-cache": "^3.2.0", - "semver": "^5.1.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "lru-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", - "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", - "dev": true, - "requires": { - "pseudomap": "^1.0.1" - } - } - } - }, - "editorconfig-to-prettier": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.0.6.tgz", - "integrity": "sha512-Ysw+hBdwhPFruYmLapKRm7Or5XgMzhasbqu4AN07V2l/AkqpgooWm2xtTQPzTD6S0tq54A+WbSxNt6qmsO3hoA==", - "dev": true - }, "electron-to-chromium": { "version": "1.3.392", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.392.tgz", @@ -13180,9 +13170,9 @@ } }, "enzyme-to-json": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.4.4.tgz", - "integrity": "sha512-50LELP/SCPJJGic5rAARvU7pgE3m1YaNj7JLM+Qkhl5t7PAs6fiyc8xzc50RnkKPFQCv0EeFVjEWdIFRGPWMsA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.5.0.tgz", + "integrity": "sha512-clusXRsiaQhG7+wtyc4t7MU8N3zCOgf4eY9+CeSenYzKlFST4lxerfOvnWd4SNaToKhkuba+w6m242YpQOS7eA==", "dev": true, "requires": { "lodash": "^4.17.15", @@ -13232,22 +13222,22 @@ } }, "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" }, "dependencies": { "has-symbols": { @@ -13415,6 +13405,23 @@ } } }, + "eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, "eslint-config-wpcalypso": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-config-wpcalypso/-/eslint-config-wpcalypso-5.0.0.tgz", @@ -13433,6 +13440,150 @@ "@typescript-eslint/experimental-utils": "^2.5.0" } }, + "eslint-plugin-jsdoc": { + "version": "26.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-26.0.2.tgz", + "integrity": "sha512-KtZjqtM3Z8x84vQBFKGUyBbZRGXYHVWSJ2XyYSUTc8KhfFrvzQ/GXPp6f1M1/YCNzP3ImD5RuDNcr+OVvIZcBA==", + "dev": true, + "requires": { + "comment-parser": "^0.7.4", + "debug": "^4.1.1", + "jsdoctypeparser": "^6.1.0", + "lodash": "^4.17.15", + "regextras": "^0.7.1", + "semver": "^6.3.0", + "spdx-expression-parse": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.3.1.tgz", + "integrity": "sha512-i1S+P+c3HOlBJzMFORRbC58tHa65Kbo8b52/TwCwSKLohwvpfT5rm2GjGWzOHTEuq4xxf2aRlHHTtmExDQOP+g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^3.5.4", + "axobject-query": "^2.1.2", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1", + "language-tags": "^1.0.5" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "emoji-regex": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.0.0.tgz", + "integrity": "sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-react": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz", + "integrity": "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1", + "object.entries": "^1.1.2", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.17.0", + "string.prototype.matchall": "^4.0.2" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, "eslint-plugin-react-hooks": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.3.0.tgz", @@ -13805,6 +13956,12 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", @@ -13839,15 +13996,6 @@ "reusify": "^1.0.0" } }, - "fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "dev": true, - "requires": { - "format": "^0.2.0" - } - }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -14111,18 +14259,6 @@ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", - "dev": true - }, - "flow-parser": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.59.0.tgz", - "integrity": "sha1-9uvK5h/6GH5CCZnUDOCoAfObJjU=", - "dev": true - }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -14185,12 +14321,6 @@ "mime-types": "^2.1.12" } }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "dev": true - }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -14269,628 +14399,14 @@ "dev": true }, "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "optional": true, "requires": { "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": false, - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": false, - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": false, - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "resolved": false, - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": false, - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": false, - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "resolved": false, - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": false, - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": false, - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": false, - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "resolved": false, - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": false, - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": false, - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "resolved": false, - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": false, - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": false, - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "resolved": false, - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": false, - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "resolved": false, - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": false, - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": false, - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "resolved": false, - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "optional": true - }, - "needle": { - "version": "2.4.0", - "resolved": false, - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "resolved": false, - "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": false, - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.7", - "resolved": false, - "integrity": "sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": false, - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": false, - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": false, - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "resolved": false, - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "resolved": false, - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": false, - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": false, - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": false, - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "resolved": false, - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "resolved": false, - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": false, - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": false, - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": false, - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "resolved": false, - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": false, - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "resolved": false, - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "optional": true - } + "nan": "^2.12.1" } }, "fstream": { @@ -15628,22 +15144,191 @@ "dev": true }, "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", "dev": true, "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" }, "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true } } @@ -15688,15 +15373,6 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, - "graphql": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz", - "integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==", - "dev": true, - "requires": { - "iterall": "^1.1.0" - } - }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -16321,6 +15997,12 @@ "har-schema": "^2.0.0" } }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -16961,6 +16643,17 @@ } } }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + } + }, "interpret": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", @@ -17053,9 +16746,9 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-ci": { @@ -17230,12 +16923,20 @@ "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } } }, "is-regexp": { @@ -17502,12 +17203,6 @@ "handlebars": "^4.0.3" } }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", - "dev": true - }, "jest": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz", @@ -18138,9 +17833,9 @@ } }, "jest-docblock": { - "version": "21.3.0-beta.11", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.3.0-beta.11.tgz", - "integrity": "sha512-sxSwZUm7JyCO8dverup5g/OKJhjYRrBdgEdezIO1qAmMGWuza7ewovpfDmxp+JLvlm0i2WRFKUQNNIMGmPGTVg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", "dev": true, "requires": { "detect-newline": "^2.1.0" @@ -18327,9 +18022,9 @@ } }, "jest-get-type": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", - "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", "dev": true }, "jest-haste-map": { @@ -19317,15 +19012,45 @@ } }, "jest-validate": { - "version": "21.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.1.0.tgz", - "integrity": "sha512-xS0cyErNWpsLFlGkn/b87pk/Mv7J+mCTs8hQ4KmtOIIoM1sHYobXII8AtkoN8FC7E3+Ptxjo+/3xWk6LK1dKcw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", "dev": true, "requires": { + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", "chalk": "^2.0.1", - "jest-get-type": "^21.0.2", - "leven": "^2.1.0", - "pretty-format": "^21.1.0" + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "pretty-format": "^24.9.0" + }, + "dependencies": { + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@types/yargs": { + "version": "13.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", + "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } }, "jest-watcher": { @@ -19458,6 +19183,12 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "jsdoctypeparser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", + "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", + "dev": true + }, "jsdom": { "version": "15.2.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", @@ -19597,6 +19328,16 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", + "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "object.assign": "^4.1.0" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -19618,6 +19359,21 @@ "integrity": "sha512-Vi3nxDGMm/z+lAaCjvAR1u+7fiv+sG6gU/iYDj5QOF8h76ytK9EW/EKfF0NeTyiGBi8Jy6Hklty/vxISrLox3w==", "dev": true }, + "language-subtag-registry": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz", + "integrity": "sha512-KPMwROklF4tEx283Xw0pNKtfTj1gZ4UByp4EsIFWLgBavJltF4TiYPc39k06zSTsLzxTVXXDSpbwaQXaFB4Qeg==", + "dev": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -19711,9 +19467,9 @@ } }, "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, "levenary": { @@ -20229,12 +19985,6 @@ "lodash._reinterpolate": "^3.0.0" } }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", - "dev": true - }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -20336,9 +20086,9 @@ } }, "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.0.tgz", + "integrity": "sha512-ko6deozZYiAkqa/0gmcsz+p4jSy3gY7/ZsCEokPaYd8k+6/aXGkiTgr61+Owup7Sf+xjqW8u2ElhoM9SEcEfuA==", "dev": true }, "make-dir": { @@ -20565,15 +20315,6 @@ "unist-util-visit": "^1.1.0" } }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "memize": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", @@ -20692,6 +20433,12 @@ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -20863,12 +20610,6 @@ "yargs-unparser": "1.6.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, "anymatch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", @@ -20880,9 +20621,9 @@ } }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, "camelcase": { @@ -20907,17 +20648,6 @@ "readdirp": "~3.2.0" } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -20988,26 +20718,6 @@ "picomatch": "^2.0.4" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, "supports-color": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", @@ -21017,35 +20727,6 @@ "has-flag": "^3.0.0" } }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", @@ -21177,9 +20858,9 @@ "dev": true }, "nearley": { - "version": "2.19.3", - "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.3.tgz", - "integrity": "sha512-FpAy1PmTsUpOtgxr23g4jRNvJHYzZEW2PixXeSzksLR/ykPfwKhAodc2+9wQhY+JneWLcvkDw6q7FJIsIdF/aQ==", + "version": "2.19.4", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.4.tgz", + "integrity": "sha512-oqj3m4oqwKsN77pETa9IPvxHHHLW68KrDc2KYoWMUOhDlrNUo7finubwffQMBRnwNCOXc4kRxCZO0Rvx4L6Zrw==", "dev": true, "requires": { "commander": "^2.19.0", @@ -21210,9 +20891,9 @@ "dev": true }, "node-addon-api": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", - "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", "dev": true }, "node-environment-flags": { @@ -21525,9 +21206,9 @@ } }, "node-gyp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.0.tgz", - "integrity": "sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz", + "integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==", "dev": true, "requires": { "env-paths": "^2.2.0", @@ -21726,33 +21407,6 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - } } }, "object-keys": { @@ -21791,15 +21445,41 @@ } }, "object.entries": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", - "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", + "es-abstract": "^1.17.5", "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } } }, "object.fromentries": { @@ -22058,10 +21738,13 @@ "dev": true }, "p-queue": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz", - "integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-4.0.0.tgz", + "integrity": "sha512-3cRXXn3/O0o3+eVmUroJPSj/esxoEFIm0ZOno/T+NzG/VZgPOqQ8WKmlNqubSEpZmCIngEy34unkHGg83ZIBmg==", + "dev": true, + "requires": { + "eventemitter3": "^3.1.0" + } }, "p-reduce": { "version": "1.0.0", @@ -22077,6 +21760,14 @@ "requires": { "@types/retry": "^0.12.0", "retry": "^0.12.0" + }, + "dependencies": { + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + } } }, "p-try": { @@ -22192,13 +21883,10 @@ } }, "parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", - "dev": true, - "requires": { - "@types/node": "*" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true }, "pascalcase": { "version": "0.1.1", @@ -22251,21 +21939,6 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", @@ -22546,92 +22219,6 @@ "@babel/core": ">=7.2.2" } }, - "postcss-less": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-1.1.3.tgz", - "integrity": "sha512-WS0wsQxRm+kmN8wEYAGZ3t4lnoNfoyx9EJZrhiPR1K0lMHR0UNWnz52Ya5QRXChHtY75Ef+kDc05FpnBujebgw==", - "dev": true, - "requires": { - "postcss": "^5.2.16" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, "postcss-markdown": { "version": "0.36.0", "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", @@ -22696,48 +22283,6 @@ "postcss": "^7.0.21" } }, - "postcss-scss": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.2.tgz", - "integrity": "sha1-/0XPM1S4ee6JpOtoaA9GrJuxT5Q=", - "dev": true, - "requires": { - "postcss": "^6.0.3" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", - "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", - "dev": true, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "postcss-syntax": { "version": "0.36.2", "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", @@ -22750,17 +22295,6 @@ "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==", "dev": true }, - "postcss-values-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-1.3.1.tgz", - "integrity": "sha512-chFn9CnFAAUpQ3cwrxvVjKB8c0y6BfONv6eapndJoTXJ3h8fr1uAiue8lGP3rUIpBI2KgJGdgCVk9KNvXh0n6A==", - "dev": true, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -22768,163 +22302,18 @@ "dev": true }, "prettier": { - "version": "github:automattic/calypso-prettier#c56b42511ec98ba6d8f72b6c391e0a626e90f531", - "from": "github:automattic/calypso-prettier#c56b4251", + "version": "npm:wp-prettier@2.0.5", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.0.5.tgz", + "integrity": "sha512-5GCgdeevIXwR3cW4Qj5XWC5MO1iSCz8+IPn0mMw6awAt/PBiey8yyO7MhePRsaMqghJAhg6Q3QLYWSnUHWkG6A==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { - "babel-code-frame": "7.0.0-beta.3", - "babylon": "7.0.0-beta.34", - "camelcase": "4.1.0", - "chalk": "2.1.0", - "cjk-regex": "1.0.2", - "cosmiconfig": "3.1.0", - "dashify": "0.2.2", - "diff": "3.2.0", - "editorconfig": "0.14.2", - "editorconfig-to-prettier": "0.0.6", - "emoji-regex": "6.5.1", - "escape-string-regexp": "1.0.5", - "esutils": "2.0.2", - "flow-parser": "0.59.0", - "get-stream": "3.0.0", - "globby": "6.1.0", - "graphql": "0.10.5", - "ignore": "3.3.7", - "jest-docblock": "21.3.0-beta.11", - "jest-validate": "21.1.0", - "leven": "2.1.0", - "mem": "1.1.0", - "minimatch": "3.0.4", - "minimist": "1.2.0", - "parse5": "3.0.3", - "path-root": "0.1.1", - "postcss-less": "1.1.3", - "postcss-media-query-parser": "0.2.3", - "postcss-scss": "1.0.2", - "postcss-selector-parser": "2.2.3", - "postcss-values-parser": "1.3.1", - "remark-frontmatter": "1.1.0", - "remark-parse": "4.0.0", - "semver": "5.4.1", - "string-width": "2.1.1", - "typescript": "2.6.2", - "typescript-eslint-parser": "9.0.1", - "unicode-regex": "1.0.1", - "unified": "6.1.6" - }, - "dependencies": { - "babel-code-frame": { - "version": "7.0.0-beta.3", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-7.0.0-beta.3.tgz", - "integrity": "sha512-flMsJ9eSpShupt2Gwpka84DoMePvE4HlDObzdEc+1iNkacv3+NHlsJ7dMKmbnVA/AT22UhcGEBHwbJLoXWBO6Q==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^3.0.0" - } - }, - "babylon": { - "version": "7.0.0-beta.34", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.34.tgz", - "integrity": "sha512-ribEzWEhWKKjY+1FdKCryo+HiN/1idPjUB8vyR5Yf221MtGzCd5+7OwPvWvYHerHHC2eJLr6MhvumbTocXGY7Q==", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "cosmiconfig": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-3.1.0.tgz", - "integrity": "sha512-zedsBhLSbPBms+kE7AH4vHg6JsKDz6epSv2/+5XHs8ILHlgDciSJfSWf8sX9aQ52Jb7KI7VswUTsLpR/G0cr2Q==", - "dev": true, - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^3.0.0", - "require-from-string": "^2.0.1" - } - }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "emoji-regex": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", - "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "parse-json": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-3.0.0.tgz", - "integrity": "sha1-+m9HsY4jgm6tMvJj50TQ4ehH+xM=", - "dev": true, - "requires": { - "error-ex": "^1.3.1" - } - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } + "fast-diff": "^1.1.2" } }, "pretty-bytes": { @@ -22937,13 +22326,43 @@ } }, "pretty-format": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", - "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "dependencies": { + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@types/yargs": { + "version": "13.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", + "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } } }, "private": { @@ -22984,14 +22403,6 @@ "requires": { "err-code": "^1.0.0", "retry": "^0.10.0" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "dev": true - } } }, "prompts": { @@ -23460,12 +22871,6 @@ } } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "cssom": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", @@ -23767,15 +23172,6 @@ "pretty-format": "^24.9.0" } }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, "jest-each": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", @@ -23816,12 +23212,6 @@ "jest-util": "^24.9.0" } }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", - "dev": true - }, "jest-haste-map": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", @@ -24048,20 +23438,6 @@ "source-map": "^0.6.0" } }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" - } - }, "jest-watcher": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", @@ -24127,12 +23503,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -24218,12 +23588,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -24254,18 +23618,6 @@ "integrity": "sha512-mqAC2r1NDmRjG+z3KCJ/i61tycKlmADIjxnDhQab+KBxSAGbF/W7/zwB2guy/ypIeKrrftNsIYkNZZQKf3vJcg==", "dev": true }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -24838,6 +24190,16 @@ "safe-regex": "^1.1.0" } }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -24858,6 +24220,12 @@ "unicode-match-property-value-ecmascript": "^1.2.0" } }, + "regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", + "dev": true + }, "regjsgen": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", @@ -24951,39 +24319,6 @@ } } }, - "remark-frontmatter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.1.0.tgz", - "integrity": "sha512-mLbYtwP9w1L9TA8dX+I/HyDF5lCpa0dmYvvW9Io+zUPpqEZ49QMKWb0hSpunpLVA+Squy0SowzSzjHVPbxWq1g==", - "dev": true, - "requires": { - "fault": "^1.0.1", - "xtend": "^4.0.1" - } - }, - "remark-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", - "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, "remark-stringify": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", @@ -25109,18 +24444,18 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "resolve": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", @@ -25216,9 +24551,9 @@ "dev": true }, "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", "dev": true }, "reusify": { @@ -25817,11 +25152,15 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" + } }, "signal-exit": { "version": "3.0.2", @@ -26321,6 +25660,28 @@ } } }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } + } + }, "string.prototype.trim": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz", @@ -26332,6 +25693,16 @@ "function-bind": "^1.1.1" } }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "string.prototype.trimleft": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", @@ -26352,6 +25723,16 @@ "function-bind": "^1.1.1" } }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -27458,9 +26839,9 @@ "dev": true }, "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, "requires": { "any-promise": "^1.0.0" @@ -27757,29 +27138,11 @@ } }, "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", "dev": true }, - "typescript-eslint-parser": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-9.0.1.tgz", - "integrity": "sha512-w1jqotvnhLtLukD9H3gQPAlbD0kLf7ZkoQGwiwSIshKIlzRL7i0OY9Y7VIdE1xtytZXThg678eomxMZ1rZXGVQ==", - "dev": true, - "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - } - } - }, "uglify-js": { "version": "3.5.11", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.11.tgz", @@ -27858,27 +27221,6 @@ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", "dev": true }, - "unicode-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-1.0.1.tgz", - "integrity": "sha1-+BngUBkdW5VhozmljdO5CV7ZSzU=", - "dev": true - }, - "unified": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.1.6.tgz", - "integrity": "sha512-pW2f82bCIo2ifuIGYcV12fL96kMMYgw7JKVEgh7ODlrM9rj6vXSY3BV+H6lCcv1ksxynFf582hwWLnA1qRFy4w==", - "dev": true, - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-function": "^1.0.4", - "x-is-string": "^0.1.0" - } - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -28249,18 +27591,6 @@ "extsprintf": "^1.2.0" } }, - "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", - "dev": true, - "requires": { - "is-buffer": "^1.1.4", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - }, "vfile-location": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.4.tgz", @@ -28927,9 +28257,9 @@ } }, "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "dev": true }, "whatwg-encoding": { @@ -29006,9 +28336,9 @@ } }, "windows-release": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz", - "integrity": "sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.1.tgz", + "integrity": "sha512-Pngk/RDCaI/DkuHPlGTdIkDiTAnAkyMjoQMZqRsxydNl1qGXNIoZrB7RK8g53F2tEgQBMqQJHQdYZuQEEAu54A==", "dev": true, "requires": { "execa": "^1.0.0" @@ -29185,12 +28515,6 @@ "async-limiter": "~1.0.0" } }, - "x-is-function": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz", - "integrity": "sha1-XSlNw9Joy90GJYDgxd93o5HR+h4=", - "dev": true - }, "x-is-string": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", @@ -29237,9 +28561,9 @@ } }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -29251,7 +28575,7 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" }, "dependencies": { "ansi-regex": { @@ -29260,6 +28584,12 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -29310,6 +28640,16 @@ "string-width": "^3.0.0", "strip-ansi": "^5.0.0" } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, diff --git a/package.json b/package.json index 446fb48931b..eb02d05cb0e 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@wordpress/babel-plugin-import-jsx-pragma": "1.1.3", "@wordpress/babel-preset-default": "3.0.2", "@wordpress/e2e-test-utils": "4.6.0", + "@wordpress/eslint-plugin": "7.1.0", "autoprefixer": "9.7.5", "babel-eslint": "10.1.0", "chai": "4.2.0", From c3de8f0d1253b479a580fe84d30282da6f55ddc1 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 1 Jul 2020 22:07:27 -0700 Subject: [PATCH 282/440] Adjusted the structure of the factory package for easier consumption --- tests/e2e/factories/src/framework/adapter.ts | 2 +- .../framework/{ => api}/api-adapter.spec.ts | 6 +++--- .../src/framework/{ => api}/api-adapter.ts | 6 +++--- .../src/framework/{ => api}/api-service.ts | 0 .../{ => api}/axios/axios-api-service.spec.ts | 0 .../{ => api}/axios/axios-api-service.ts | 4 ---- .../axios/axios-auth-interceptor.spec.ts | 0 .../{ => api}/axios/axios-auth-interceptor.ts | 0 .../axios/axios-response-interceptor.spec.ts | 0 .../axios/axios-response-interceptor.ts | 2 +- tests/e2e/factories/src/framework/index.ts | 14 ++++++++++++++ .../factories/src/framework/model-factory.ts | 2 +- .../src/framework/model-registry.spec.ts | 2 +- .../factories/src/framework/model-registry.ts | 2 +- .../src/{models => framework}/model.ts | 0 tests/e2e/factories/src/index.ts | 19 +++++++++++++++++-- tests/e2e/factories/src/models/index.ts | 2 ++ tests/e2e/factories/src/models/product.ts | 2 +- .../factories/src/models/simple-product.ts | 2 +- .../factories/src/{framework => }/utils.ts | 6 +++--- tests/e2e/factories/tsconfig.json | 2 +- 21 files changed, 50 insertions(+), 23 deletions(-) rename tests/e2e/factories/src/framework/{ => api}/api-adapter.spec.ts (92%) rename tests/e2e/factories/src/framework/{ => api}/api-adapter.ts (95%) rename tests/e2e/factories/src/framework/{ => api}/api-service.ts (100%) rename tests/e2e/factories/src/framework/{ => api}/axios/axios-api-service.spec.ts (100%) rename tests/e2e/factories/src/framework/{ => api}/axios/axios-api-service.ts (96%) rename tests/e2e/factories/src/framework/{ => api}/axios/axios-auth-interceptor.spec.ts (100%) rename tests/e2e/factories/src/framework/{ => api}/axios/axios-auth-interceptor.ts (100%) rename tests/e2e/factories/src/framework/{ => api}/axios/axios-response-interceptor.spec.ts (100%) rename tests/e2e/factories/src/framework/{ => api}/axios/axios-response-interceptor.ts (97%) create mode 100644 tests/e2e/factories/src/framework/index.ts rename tests/e2e/factories/src/{models => framework}/model.ts (100%) create mode 100644 tests/e2e/factories/src/models/index.ts rename tests/e2e/factories/src/{framework => }/utils.ts (79%) diff --git a/tests/e2e/factories/src/framework/adapter.ts b/tests/e2e/factories/src/framework/adapter.ts index e04e45ad714..30f08a2d12d 100644 --- a/tests/e2e/factories/src/framework/adapter.ts +++ b/tests/e2e/factories/src/framework/adapter.ts @@ -1,4 +1,4 @@ -import { Model } from '../models/model'; +import { Model } from './model'; /** * An interface for implementing adapters to create models. diff --git a/tests/e2e/factories/src/framework/api-adapter.spec.ts b/tests/e2e/factories/src/framework/api/api-adapter.spec.ts similarity index 92% rename from tests/e2e/factories/src/framework/api-adapter.spec.ts rename to tests/e2e/factories/src/framework/api/api-adapter.spec.ts index 523d4a5f300..6bc6cafa22c 100644 --- a/tests/e2e/factories/src/framework/api-adapter.spec.ts +++ b/tests/e2e/factories/src/framework/api/api-adapter.spec.ts @@ -1,7 +1,7 @@ -import { Model } from '../models/model'; -import { APIResponse, APIService } from '../index'; +import { Model } from '../model'; import { APIAdapter } from './api-adapter'; -import { SimpleProduct } from '../models/simple-product'; +import { SimpleProduct } from '../../models/simple-product'; +import { APIResponse, APIService } from './api-service'; class MockAPI implements APIService { public get = jest.fn(); diff --git a/tests/e2e/factories/src/framework/api-adapter.ts b/tests/e2e/factories/src/framework/api/api-adapter.ts similarity index 95% rename from tests/e2e/factories/src/framework/api-adapter.ts rename to tests/e2e/factories/src/framework/api/api-adapter.ts index d22c7ff7d90..0ef37497be9 100644 --- a/tests/e2e/factories/src/framework/api-adapter.ts +++ b/tests/e2e/factories/src/framework/api/api-adapter.ts @@ -1,6 +1,6 @@ -import { APIService } from '../index'; -import { Model } from '../models/model'; -import { Adapter } from './adapter'; +import { APIService } from './api-service'; +import { Model } from '../model'; +import { Adapter } from '../adapter'; /** * A callback for transforming models into an API request body. diff --git a/tests/e2e/factories/src/framework/api-service.ts b/tests/e2e/factories/src/framework/api/api-service.ts similarity index 100% rename from tests/e2e/factories/src/framework/api-service.ts rename to tests/e2e/factories/src/framework/api/api-service.ts diff --git a/tests/e2e/factories/src/framework/axios/axios-api-service.spec.ts b/tests/e2e/factories/src/framework/api/axios/axios-api-service.spec.ts similarity index 100% rename from tests/e2e/factories/src/framework/axios/axios-api-service.spec.ts rename to tests/e2e/factories/src/framework/api/axios/axios-api-service.spec.ts diff --git a/tests/e2e/factories/src/framework/axios/axios-api-service.ts b/tests/e2e/factories/src/framework/api/axios/axios-api-service.ts similarity index 96% rename from tests/e2e/factories/src/framework/axios/axios-api-service.ts rename to tests/e2e/factories/src/framework/api/axios/axios-api-service.ts index 9258c7d7bf3..39f58cef19e 100644 --- a/tests/e2e/factories/src/framework/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/framework/api/axios/axios-api-service.ts @@ -1,6 +1,5 @@ import axios, { AxiosInstance } from 'axios'; import { APIResponse, APIService } from '../api-service'; -import { Agent } from 'https'; import { AxiosAuthInterceptor } from './axios-auth-interceptor'; import { AxiosResponseInterceptor } from './axios-response-interceptor'; @@ -19,9 +18,6 @@ export class AxiosAPIService implements APIService { ) { this.client = axios.create( { baseURL: baseAPIURL, - httpsAgent: new Agent( { - rejectUnauthorized: false, - } ), } ); this.authInterceptor = new AxiosAuthInterceptor( this.client, diff --git a/tests/e2e/factories/src/framework/axios/axios-auth-interceptor.spec.ts b/tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.spec.ts similarity index 100% rename from tests/e2e/factories/src/framework/axios/axios-auth-interceptor.spec.ts rename to tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.spec.ts diff --git a/tests/e2e/factories/src/framework/axios/axios-auth-interceptor.ts b/tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.ts similarity index 100% rename from tests/e2e/factories/src/framework/axios/axios-auth-interceptor.ts rename to tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.ts diff --git a/tests/e2e/factories/src/framework/axios/axios-response-interceptor.spec.ts b/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.spec.ts similarity index 100% rename from tests/e2e/factories/src/framework/axios/axios-response-interceptor.spec.ts rename to tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.spec.ts diff --git a/tests/e2e/factories/src/framework/axios/axios-response-interceptor.ts b/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.ts similarity index 97% rename from tests/e2e/factories/src/framework/axios/axios-response-interceptor.ts rename to tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.ts index bc60c7b4af8..e915ef0bfc0 100644 --- a/tests/e2e/factories/src/framework/axios/axios-response-interceptor.ts +++ b/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.ts @@ -1,5 +1,5 @@ import { AxiosInstance, AxiosResponse } from 'axios'; -import { APIError, APIResponse } from '../api-service'; +import { APIResponse, APIError } from '../api-service'; export class AxiosResponseInterceptor { private readonly client: AxiosInstance; diff --git a/tests/e2e/factories/src/framework/index.ts b/tests/e2e/factories/src/framework/index.ts new file mode 100644 index 00000000000..d611eab4c1e --- /dev/null +++ b/tests/e2e/factories/src/framework/index.ts @@ -0,0 +1,14 @@ +/** + * CORE CLASSES + * These exports relate to extending the core functionality of the package. + */ +export { Adapter } from './adapter'; +export { ModelFactory } from './model-factory'; +export { Model } from './model'; + +/** + * API ADAPTER + * These exports relate to replacing the underlying HTTP layer of API adapters. + */ +export { APIAdapter } from './api/api-adapter'; +export { APIService, APIResponse, APIError } from './api/api-service'; diff --git a/tests/e2e/factories/src/framework/model-factory.ts b/tests/e2e/factories/src/framework/model-factory.ts index 099d4ecb173..c975381a187 100644 --- a/tests/e2e/factories/src/framework/model-factory.ts +++ b/tests/e2e/factories/src/framework/model-factory.ts @@ -1,5 +1,5 @@ import { DeepPartial, Factory, BuildOptions } from 'fishery'; -import { Model } from '../models/model'; +import { Model } from './model'; import { Adapter } from './adapter'; /** diff --git a/tests/e2e/factories/src/framework/model-registry.spec.ts b/tests/e2e/factories/src/framework/model-registry.spec.ts index 247b9fb0d29..1673df9345f 100644 --- a/tests/e2e/factories/src/framework/model-registry.spec.ts +++ b/tests/e2e/factories/src/framework/model-registry.spec.ts @@ -1,7 +1,7 @@ import { AdapterTypes, ModelRegistry } from './model-registry'; import { ModelFactory } from './model-factory'; import { Product } from '../models/product'; -import { APIAdapter } from './api-adapter'; +import { APIAdapter } from './api/api-adapter'; import { SimpleProduct } from '../models/simple-product'; describe( 'ModelRegistry', () => { diff --git a/tests/e2e/factories/src/framework/model-registry.ts b/tests/e2e/factories/src/framework/model-registry.ts index 96b9cf6ac35..c31a8ef122a 100644 --- a/tests/e2e/factories/src/framework/model-registry.ts +++ b/tests/e2e/factories/src/framework/model-registry.ts @@ -1,5 +1,5 @@ import { Adapter } from './adapter'; -import { Model } from '../models/model'; +import { Model } from './model'; import { ModelFactory } from './model-factory'; type Registry = { [key: string ]: T }; diff --git a/tests/e2e/factories/src/models/model.ts b/tests/e2e/factories/src/framework/model.ts similarity index 100% rename from tests/e2e/factories/src/models/model.ts rename to tests/e2e/factories/src/framework/model.ts diff --git a/tests/e2e/factories/src/index.ts b/tests/e2e/factories/src/index.ts index 51d79ca5822..6d291ded820 100644 --- a/tests/e2e/factories/src/index.ts +++ b/tests/e2e/factories/src/index.ts @@ -1,2 +1,17 @@ -export { APIService, APIResponse, APIError } from './framework/api-service'; -export { AxiosAPIService } from './framework/axios/axios-api-service'; +/** + * FRAMEWORK CLASSES + * These exports relate to the core classes needed to utilize the package. + */ +export { ModelRegistry, AdapterTypes } from './framework/model-registry'; + +/** + * MODELS + * This exports all of the models we have defined and their related functions. + */ +export * from './models'; + +/** + * UTILITIES + * These exports relate to common utilities that can be used to utilize the package. + */ +export { initializeAPIAdapters } from './utils'; diff --git a/tests/e2e/factories/src/models/index.ts b/tests/e2e/factories/src/models/index.ts new file mode 100644 index 00000000000..57d084aad6f --- /dev/null +++ b/tests/e2e/factories/src/models/index.ts @@ -0,0 +1,2 @@ +export { Product } from './product'; +export { SimpleProduct, registerSimpleProduct } from './simple-product'; diff --git a/tests/e2e/factories/src/models/product.ts b/tests/e2e/factories/src/models/product.ts index 33b379d7f8b..12d6b83c5d9 100644 --- a/tests/e2e/factories/src/models/product.ts +++ b/tests/e2e/factories/src/models/product.ts @@ -1,4 +1,4 @@ -import { Model } from './model'; +import { Model } from '../framework/model'; import { DeepPartial } from 'fishery'; /** diff --git a/tests/e2e/factories/src/models/simple-product.ts b/tests/e2e/factories/src/models/simple-product.ts index 0996940de74..14f96f4567e 100644 --- a/tests/e2e/factories/src/models/simple-product.ts +++ b/tests/e2e/factories/src/models/simple-product.ts @@ -2,7 +2,7 @@ import { DeepPartial } from 'fishery'; import { Product } from './product'; import { AdapterTypes, ModelRegistry } from '../framework/model-registry'; import { ModelFactory } from '../framework/model-factory'; -import { APIAdapter } from '../framework/api-adapter'; +import { APIAdapter } from '../framework/api/api-adapter'; export class SimpleProduct extends Product { public constructor( partial: DeepPartial = {} ) { diff --git a/tests/e2e/factories/src/framework/utils.ts b/tests/e2e/factories/src/utils.ts similarity index 79% rename from tests/e2e/factories/src/framework/utils.ts rename to tests/e2e/factories/src/utils.ts index 3a5ecf7017d..c647a2ae0b8 100644 --- a/tests/e2e/factories/src/framework/utils.ts +++ b/tests/e2e/factories/src/utils.ts @@ -1,6 +1,6 @@ -import { AdapterTypes, ModelRegistry } from './model-registry'; -import { APIAdapter } from './api-adapter'; -import { AxiosAPIService } from './axios/axios-api-service'; +import { AdapterTypes, ModelRegistry } from './framework/model-registry'; +import { APIAdapter } from './framework/api/api-adapter'; +import { AxiosAPIService } from './framework/api/axios/axios-api-service'; /** * Initializes all of the APIAdapters with a client to communicate with the API. diff --git a/tests/e2e/factories/tsconfig.json b/tests/e2e/factories/tsconfig.json index f32d56749ca..b7f881ff66b 100644 --- a/tests/e2e/factories/tsconfig.json +++ b/tests/e2e/factories/tsconfig.json @@ -5,5 +5,5 @@ "rootDir": "src", "outDir": "dist" }, - "include": [ "src/**/*" ] + "include": [ "src/" ] } From 85833f137c85263c42f9d85891095126e1a6dfbd Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 1 Jul 2020 22:08:18 -0700 Subject: [PATCH 283/440] Fixed a bug that would cause APIService failures to throw unhandled exceptions when creating --- .../e2e/factories/src/framework/api/api-adapter.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/e2e/factories/src/framework/api/api-adapter.ts b/tests/e2e/factories/src/framework/api/api-adapter.ts index 0ef37497be9..26d31c5dbc2 100644 --- a/tests/e2e/factories/src/framework/api/api-adapter.ts +++ b/tests/e2e/factories/src/framework/api/api-adapter.ts @@ -61,14 +61,12 @@ export class APIAdapter implements Adapter { * @return {Promise} Resolves to the created input model. */ private async createSingle( model: T ): Promise { - return new Promise( async ( resolve ) => { - const response = await this.apiService!.post( - this.endpoint, - this.transformer( model ), - ); - - model.onCreated( response.data ); - resolve( model ); + return this.apiService!.post( + this.endpoint, + this.transformer( model ), + ).then( ( data ) => { + model.onCreated( data ); + return model; } ); } From f11a47693b9d3e87df7e60767f7851f97e0d0a3d Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 10:03:35 -0700 Subject: [PATCH 284/440] Refactored interceptors to support different authentication styles --- .../src/framework/api/api-adapter.spec.ts | 8 +- .../src/framework/api/api-adapter.ts | 2 +- .../api/axios/axios-api-service.spec.ts | 33 +++++++-- .../framework/api/axios/axios-api-service.ts | 64 +++++++++++----- .../framework/api/axios/axios-interceptor.ts | 73 +++++++++++++++++++ ...pec.ts => axios-oauth-interceptor.spec.ts} | 17 ++--- ...erceptor.ts => axios-oauth-interceptor.ts} | 40 ++-------- .../axios/axios-response-interceptor.spec.ts | 6 +- .../api/axios/axios-response-interceptor.ts | 40 ++-------- tests/e2e/factories/src/utils.ts | 2 +- 10 files changed, 174 insertions(+), 111 deletions(-) create mode 100644 tests/e2e/factories/src/framework/api/axios/axios-interceptor.ts rename tests/e2e/factories/src/framework/api/axios/{axios-auth-interceptor.spec.ts => axios-oauth-interceptor.spec.ts} (85%) rename tests/e2e/factories/src/framework/api/axios/{axios-auth-interceptor.ts => axios-oauth-interceptor.ts} (53%) diff --git a/tests/e2e/factories/src/framework/api/api-adapter.spec.ts b/tests/e2e/factories/src/framework/api/api-adapter.spec.ts index 6bc6cafa22c..cc046b12752 100644 --- a/tests/e2e/factories/src/framework/api/api-adapter.spec.ts +++ b/tests/e2e/factories/src/framework/api/api-adapter.spec.ts @@ -22,7 +22,7 @@ describe( 'APIModelCreator', () => { } ); it( 'should create single instance', async () => { - mockService.post.mockReturnValueOnce( new APIResponse( 200, {}, { id: 1 } ) ); + mockService.post.mockReturnValueOnce( Promise.resolve( new APIResponse( 200, {}, { id: 1 } ) ) ); const result = await adapter.create( new SimpleProduct() ); @@ -34,9 +34,9 @@ describe( 'APIModelCreator', () => { it( 'should create multiple instances', async () => { mockService.post - .mockReturnValueOnce( new APIResponse( 200, {}, { id: 1 } ) ) - .mockReturnValueOnce( new APIResponse( 200, {}, { id: 2 } ) ) - .mockReturnValueOnce( new APIResponse( 200, {}, { id: 3 } ) ); + .mockReturnValueOnce( Promise.resolve( new APIResponse( 200, {}, { id: 1 } ) ) ) + .mockReturnValueOnce( Promise.resolve( new APIResponse( 200, {}, { id: 2 } ) ) ) + .mockReturnValueOnce( Promise.resolve( new APIResponse( 200, {}, { id: 3 } ) ) ); const result = await adapter.create( [ new SimpleProduct(), new SimpleProduct(), new SimpleProduct() ] ); diff --git a/tests/e2e/factories/src/framework/api/api-adapter.ts b/tests/e2e/factories/src/framework/api/api-adapter.ts index 26d31c5dbc2..c8b2a3cd038 100644 --- a/tests/e2e/factories/src/framework/api/api-adapter.ts +++ b/tests/e2e/factories/src/framework/api/api-adapter.ts @@ -65,7 +65,7 @@ export class APIAdapter implements Adapter { this.endpoint, this.transformer( model ), ).then( ( data ) => { - model.onCreated( data ); + model.onCreated( data.data ); return model; } ); } diff --git a/tests/e2e/factories/src/framework/api/axios/axios-api-service.spec.ts b/tests/e2e/factories/src/framework/api/axios/axios-api-service.spec.ts index 1f075fed6c8..fbf911afa13 100644 --- a/tests/e2e/factories/src/framework/api/axios/axios-api-service.spec.ts +++ b/tests/e2e/factories/src/framework/api/axios/axios-api-service.spec.ts @@ -7,18 +7,19 @@ describe( 'AxiosAPIService', () => { beforeEach( () => { moxios.install(); - apiClient = new AxiosAPIService( - 'https://test.test/wp-json/', - 'consumer_key', - 'consumer_secret', - ); } ); afterEach( () => { moxios.uninstall(); } ); - it( 'should add interceptors', async () => { + it( 'should add OAuth interceptors', async () => { + apiClient = AxiosAPIService.createUsingOAuth( + 'http://test.test/wp-json/', + 'consumer_key', + 'consumer_secret', + ); + moxios.stubOnce( 'GET', '/wc/v2/product', { status: 200, headers: { @@ -32,5 +33,25 @@ describe( 'AxiosAPIService', () => { const request = moxios.requests.mostRecent(); expect( request.headers ).toHaveProperty( 'Authorization' ); + expect( request.headers.Authorization ).toMatch( /^OAuth/ ); + } ); + + it( 'should add basic auth interceptors', async () => { + apiClient = AxiosAPIService.createUsingBasicAuth( 'http://test.test/wp-json/', 'test', 'pass' ); + + moxios.stubOnce( 'GET', '/wc/v2/product', { + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + responseText: JSON.stringify( { test: 'value' } ), + } ); + + const response = await apiClient.get( '/wc/v2/product' ); + expect( response ).toBeInstanceOf( APIResponse ); + + const request = moxios.requests.mostRecent(); + expect( request.headers ).toHaveProperty( 'Authorization' ); + expect( request.headers.Authorization ).toMatch( /^Basic/ ); } ); } ); diff --git a/tests/e2e/factories/src/framework/api/axios/axios-api-service.ts b/tests/e2e/factories/src/framework/api/axios/axios-api-service.ts index 39f58cef19e..b5782518886 100644 --- a/tests/e2e/factories/src/framework/api/axios/axios-api-service.ts +++ b/tests/e2e/factories/src/framework/api/axios/axios-api-service.ts @@ -1,6 +1,7 @@ -import axios, { AxiosInstance } from 'axios'; +import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'; import { APIResponse, APIService } from '../api-service'; -import { AxiosAuthInterceptor } from './axios-auth-interceptor'; +import { AxiosOAuthInterceptor } from './axios-oauth-interceptor'; +import { AxiosInterceptor } from './axios-interceptor'; import { AxiosResponseInterceptor } from './axios-response-interceptor'; /** @@ -8,25 +9,50 @@ import { AxiosResponseInterceptor } from './axios-response-interceptor'; */ export class AxiosAPIService implements APIService { private readonly client: AxiosInstance; - private authInterceptor: AxiosAuthInterceptor; - private responseInterceptor: AxiosResponseInterceptor; + private readonly interceptors: AxiosInterceptor[]; - public constructor( - baseAPIURL: string, - consumerKey: string, - consumerSecret: string, - ) { - this.client = axios.create( { - baseURL: baseAPIURL, - } ); - this.authInterceptor = new AxiosAuthInterceptor( - this.client, - consumerKey, - consumerSecret, + public constructor( config: AxiosRequestConfig, interceptors: AxiosInterceptor[] = [] ) { + this.client = axios.create( config ); + this.interceptors = interceptors; + for ( const interceptor of this.interceptors ) { + interceptor.start( this.client ); + } + } + + /** + * Creates a new Axios API Service using OAuth 1.0a one-legged authentication. + * + * @param {string} apiURL The base URL for the API requests to be sent. + * @param {string} consumerKey The OAuth consumer key. + * @param {string} consumerSecret The OAuth consumer secret. + * @return {AxiosAPIService} The created service. + */ + public static createUsingOAuth( apiURL: string, consumerKey: string, consumerSecret: string ): AxiosAPIService { + return new AxiosAPIService( + { baseURL: apiURL }, + [ + new AxiosOAuthInterceptor( consumerKey, consumerSecret ), + new AxiosResponseInterceptor(), + ], + ); + } + + /** + * Creates a new Axios API Service using basic authentication. + * + * @param {string} apiURL The base URL for the API requests to be sent. + * @param {string} username The username for authentication. + * @param {string} password The password for authentication. + * @return {AxiosAPIService} The created service. + */ + public static createUsingBasicAuth( apiURL: string, username: string, password: string ): AxiosAPIService { + return new AxiosAPIService( + { + baseURL: apiURL, + auth: { username, password }, + }, + [ new AxiosResponseInterceptor() ], ); - this.authInterceptor.start(); - this.responseInterceptor = new AxiosResponseInterceptor( this.client ); - this.responseInterceptor.start(); } /** diff --git a/tests/e2e/factories/src/framework/api/axios/axios-interceptor.ts b/tests/e2e/factories/src/framework/api/axios/axios-interceptor.ts new file mode 100644 index 00000000000..2d2ac3c493a --- /dev/null +++ b/tests/e2e/factories/src/framework/api/axios/axios-interceptor.ts @@ -0,0 +1,73 @@ +import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; + +type ActiveInterceptor = { + client: AxiosInstance; + requestInterceptorID: number; + responseInterceptorID: number; +} + +/** + * A base class for encapsulating the start and stop functionality required by all axios interceptors. + */ +export abstract class AxiosInterceptor { + private readonly activeInterceptors: ActiveInterceptor[] = []; + + /** + * Starts intercepting requests and responses. + * + * @param {AxiosInstance} client The client to start intercepting the requests/responses of. + */ + public start( client: AxiosInstance ): void { + const requestInterceptorID = client.interceptors.request.use( + ( response ) => this.handleRequest( response ), + ); + const responseInterceptorID = client.interceptors.response.use( + ( response ) => this.onResponseSuccess( response ), + ( error ) => this.onResponseRejected( error ), + ); + this.activeInterceptors.push( { client, requestInterceptorID, responseInterceptorID } ); + } + + /** + * Stops intercepting requests and responses. + * + * @param {AxiosInstance} client The client to stop intercepting the requests/responses of. + */ + public stop( client: AxiosInstance ): void { + for ( let i = this.activeInterceptors.length - 1; i >= 0; --i ) { + const active = this.activeInterceptors[ i ]; + if ( client === active.client ) { + client.interceptors.request.eject( active.requestInterceptorID ); + client.interceptors.response.eject( active.responseInterceptorID ); + this.activeInterceptors.splice( i, 1 ); + } + } + } + + /** + * An interceptor method for handling requests before they are made to the server. + * + * @param {AxiosRequestConfig} config The axios request options. + */ + protected handleRequest( config: AxiosRequestConfig ): AxiosRequestConfig { + return config; + } + + /** + * An interceptor method for handling successful responses. + * + * @param {AxiosResponse} response The response from the axios client. + */ + protected onResponseSuccess( response: AxiosResponse ): any { + return response; + } + + /** + * An interceptor method for handling response failures. + * + * @param {*} error The error that occurred. + */ + protected onResponseRejected( error: any ): any { + return error; + } +} diff --git a/tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.spec.ts b/tests/e2e/factories/src/framework/api/axios/axios-oauth-interceptor.spec.ts similarity index 85% rename from tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.spec.ts rename to tests/e2e/factories/src/framework/api/axios/axios-oauth-interceptor.spec.ts index 5c1e1af9769..928762fee16 100644 --- a/tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.spec.ts +++ b/tests/e2e/factories/src/framework/api/axios/axios-oauth-interceptor.spec.ts @@ -1,37 +1,36 @@ import axios, { AxiosInstance } from 'axios'; import moxios from 'moxios'; -import { AxiosAuthInterceptor } from './axios-auth-interceptor'; +import { AxiosOAuthInterceptor } from './axios-oauth-interceptor'; -describe( 'AxiosAuthInterceptor', () => { - let apiAuthInterceptor: AxiosAuthInterceptor; +describe( 'AxiosOAuthInterceptor', () => { + let apiAuthInterceptor: AxiosOAuthInterceptor; let axiosInstance: AxiosInstance; beforeEach( () => { axiosInstance = axios.create(); moxios.install( axiosInstance ); - apiAuthInterceptor = new AxiosAuthInterceptor( - axiosInstance, + apiAuthInterceptor = new AxiosOAuthInterceptor( 'consumer_key', 'consumer_secret', ); - apiAuthInterceptor.start(); + apiAuthInterceptor.start( axiosInstance ); } ); afterEach( () => { - apiAuthInterceptor.stop(); + apiAuthInterceptor.stop( axiosInstance ); moxios.uninstall( axiosInstance ); } ); it( 'should not run unless started', async () => { moxios.stubOnce( 'GET', 'https://api.test', { status: 200 } ); - apiAuthInterceptor.stop(); + apiAuthInterceptor.stop( axiosInstance ); await axiosInstance.get( 'https://api.test' ); let request = moxios.requests.mostRecent(); expect( request.headers ).not.toHaveProperty( 'Authorization' ); - apiAuthInterceptor.start(); + apiAuthInterceptor.start( axiosInstance ); await axiosInstance.get( 'https://api.test' ); request = moxios.requests.mostRecent(); diff --git a/tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.ts b/tests/e2e/factories/src/framework/api/axios/axios-oauth-interceptor.ts similarity index 53% rename from tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.ts rename to tests/e2e/factories/src/framework/api/axios/axios-oauth-interceptor.ts index 6953138b17d..f9de2cef9b2 100644 --- a/tests/e2e/factories/src/framework/api/axios/axios-auth-interceptor.ts +++ b/tests/e2e/factories/src/framework/api/axios/axios-oauth-interceptor.ts @@ -1,22 +1,17 @@ -import { AxiosInstance, AxiosRequestConfig } from 'axios'; +import { AxiosRequestConfig } from 'axios'; import createHmac from 'create-hmac'; import OAuth from 'oauth-1.0a'; +import { AxiosInterceptor } from './axios-interceptor'; /** * A utility class for managing the lifecycle of an authentication interceptor. */ -export class AxiosAuthInterceptor { - private readonly client: AxiosInstance; - private interceptorID: number | null; +export class AxiosOAuthInterceptor extends AxiosInterceptor { private oauth: OAuth; - public constructor( - client: AxiosInstance, - consumerKey: string, - consumerSecret: string, - ) { - this.client = client; - this.interceptorID = null; + public constructor( consumerKey: string, consumerSecret: string ) { + super(); + this.oauth = new OAuth( { consumer: { key: consumerKey, @@ -29,34 +24,13 @@ export class AxiosAuthInterceptor { } ); } - /** - * Starts adding WooCommerce API authentication details to requests made using the contained client. - */ - public start(): void { - if ( null === this.interceptorID ) { - this.interceptorID = this.client.interceptors.request.use( - ( request ) => this.handleRequest( request ), - ); - } - } - - /** - * Stops adding WooCommerce API authentication details to requests made using the contained client. - */ - public stop(): void { - if ( null !== this.interceptorID ) { - this.client.interceptors.request.eject( this.interceptorID ); - this.interceptorID = null; - } - } - /** * Adds WooCommerce API authentication details to the outgoing request. * * @param {AxiosRequestConfig} request The request that was intercepted. * @return {AxiosRequestConfig} The request with the additional authorization headers. */ - private handleRequest( request: AxiosRequestConfig ): AxiosRequestConfig { + protected handleRequest( request: AxiosRequestConfig ): AxiosRequestConfig { const url = ( request.baseURL || '' ) + ( request.url || '' ); if ( url.startsWith( 'https' ) ) { request.auth = { diff --git a/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.spec.ts b/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.spec.ts index 7bbfb9e24d5..c4785e70b20 100644 --- a/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.spec.ts +++ b/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.spec.ts @@ -10,12 +10,12 @@ describe( 'AxiosResponseInterceptor', () => { beforeEach( () => { axiosInstance = axios.create(); moxios.install( axiosInstance ); - apiResponseInterceptor = new AxiosResponseInterceptor( axiosInstance ); - apiResponseInterceptor.start(); + apiResponseInterceptor = new AxiosResponseInterceptor(); + apiResponseInterceptor.start( axiosInstance ); } ); afterEach( () => { - apiResponseInterceptor.stop(); + apiResponseInterceptor.stop( axiosInstance ); moxios.uninstall(); } ); diff --git a/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.ts b/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.ts index e915ef0bfc0..164f48f6107 100644 --- a/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.ts +++ b/tests/e2e/factories/src/framework/api/axios/axios-response-interceptor.ts @@ -1,45 +1,15 @@ -import { AxiosInstance, AxiosResponse } from 'axios'; +import { AxiosResponse } from 'axios'; import { APIResponse, APIError } from '../api-service'; +import { AxiosInterceptor } from './axios-interceptor'; -export class AxiosResponseInterceptor { - private readonly client: AxiosInstance; - private interceptorID: number | null; - - public constructor( client: AxiosInstance ) { - this.client = client; - this.interceptorID = null; - } - - /** - * Starts transforming the response and errors into a consistent format. - */ - public start(): void { - if ( null === this.interceptorID ) { - this.interceptorID = this.client.interceptors.response.use( - // @ts-ignore: We WANT to change the type of response returned. - ( response ) => this.onFulfilled( response ), - ( error: any ) => AxiosResponseInterceptor.onRejected( error ), - ); - } - } - - /** - * Stops transforming the response and errors into a consistent format. - */ - public stop(): void { - if ( null !== this.interceptorID ) { - this.client.interceptors.response.eject( this.interceptorID ); - this.interceptorID = null; - } - } - +export class AxiosResponseInterceptor extends AxiosInterceptor { /** * Transforms the Axios response into our API response to be consumed in a consistent manner. * * @param {AxiosResponse} response The respons ethat we need to transform. * @return {Promise} A promise containing the APIResponse. */ - private onFulfilled( response: AxiosResponse ): Promise { + protected onResponseSuccess( response: AxiosResponse ): Promise { return Promise.resolve( new APIResponse( response.status, response.headers, response.data ), ); @@ -50,7 +20,7 @@ export class AxiosResponseInterceptor { * * @param {*} error The error that was caught. */ - private static onRejected( error: any ): Promise { + protected onResponseRejected( error: any ): Promise { // Only transform API errors. if ( ! error.response ) { throw error; diff --git a/tests/e2e/factories/src/utils.ts b/tests/e2e/factories/src/utils.ts index c647a2ae0b8..bbdc4f5674f 100644 --- a/tests/e2e/factories/src/utils.ts +++ b/tests/e2e/factories/src/utils.ts @@ -21,7 +21,7 @@ export function initializeAPIAdapters( return; } - const apiService = new AxiosAPIService( apiURL, consumerKey, consumerSecret ); + const apiService = AxiosAPIService.createUsingOAuth( apiURL, consumerKey, consumerSecret ); for ( const adapter of adapters ) { adapter.setAPIService( apiService ); } From 3e69dd3a64207818c1bfd60fab8519521fddf71a Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 10:50:56 -0700 Subject: [PATCH 285/440] Replaced the `createSimpleProduct` helper with a usage of the factory --- package-lock.json | 4473 ++++++++++++++++++++++++++++++ package.json | 1 + tests/e2e/docker/initialize.sh | 3 + tests/e2e/factories/src/index.ts | 2 +- tests/e2e/factories/src/utils.ts | 29 +- tests/e2e/utils/components.js | 35 +- 6 files changed, 4525 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6641cb3bf84..3ec4a93f00f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7247,6 +7247,4479 @@ } } }, + "@woocommerce/e2e-factories": { + "version": "file:tests/e2e/factories", + "dev": true, + "requires": { + "axios": "0.19.2", + "create-hmac": "1.1.7", + "fishery": "1.0.0", + "oauth-1.0a": "2.2.6" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/core": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", + "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.2", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helpers": "^7.10.1", + "@babel/parser": "^7.10.2", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.2", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "@babel/generator": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "requires": { + "@babel/types": "^7.10.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "requires": { + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", + "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", + "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", + "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", + "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", + "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==" + }, + "@babel/helper-replace-supers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", + "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "requires": { + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==" + }, + "@babel/helpers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", + "requires": { + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", + "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.1.tgz", + "integrity": "sha512-XyHIFa9kdrgJS91CUH+ccPVTnJShr8nLGc5bG2IhGXv5p1Rd+8BleGE5yzIg2Nc1QZAdHDa0Qp4m6066OL96Iw==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", + "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/traverse": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + } + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + }, + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz", + "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/reporters": "^25.5.1", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^25.5.0", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-resolve-dependencies": "^25.5.4", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "jest-watcher": "^25.5.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "realpath-native": "^2.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + } + }, + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "requires": { + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@types/babel__core": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", + "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", + "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "@types/create-hmac": { + "version": "1.1.0", + "integrity": "sha512-BNYNdzdhOZZQWCOpwvIll3FSvgo3e55Y2M6s/jOY6TuOCwqt3cLmQsK4tSmJ5fayDot8EG4k3+hcZagfww9JlQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz", + "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "25.2.1", + "integrity": "sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA==", + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "@types/moxios": { + "version": "0.4.9", + "integrity": "sha512-Sd1b24QRW2N194j2LEDPQAZK1h0TBtpN+2EIH+rERCgm38qm14JZwC7NlpE7n3jULhlCIPZBG8uNcbjF8KcCaQ==", + "requires": { + "axios": "^0.19.0" + } + }, + "@types/node": { + "version": "13.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz", + "integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==" + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" + }, + "acorn": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==" + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", + "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" + } + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==" + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.2.tgz", + "integrity": "sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==" + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "requires": { + "bser": "2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fishery": { + "version": "1.0.0", + "resolved": "github:thoughtbot/fishery#b45f86d2073513aac9d9f577b4581b3de4ee75f3", + "dev": true, + "requires": { + "lodash.merge": "^4.6.2" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "25.5.4", + "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==", + "requires": { + "@jest/core": "^25.5.4", + "import-local": "^3.0.2", + "jest-cli": "^25.5.4" + }, + "dependencies": { + "jest-cli": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz", + "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==", + "requires": { + "@jest/core": "^25.5.4", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^25.5.4", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "prompts": "^2.0.1", + "realpath-native": "^2.0.0", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz", + "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==", + "requires": { + "@jest/types": "^25.5.0", + "execa": "^3.2.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + } + }, + "jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" + } + }, + "jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "requires": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "requires": { + "@jest/types": "^25.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==" + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz", + "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==", + "requires": { + "@jest/types": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-snapshot": "^25.5.1" + } + }, + "jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + } + }, + "jest-watcher": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz", + "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==", + "requires": { + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "jest-util": "^25.5.0", + "string-length": "^3.1.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "requires": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "moxios": { + "version": "0.4.0", + "integrity": "sha1-/A2ixlR31yXKa5Z51YNw7QxS9Ts=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" + }, + "node-notifier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", + "shellwords": "^0.1.1", + "which": "^1.3.1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, + "oauth-1.0a": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-2.2.6.tgz", + "integrity": "sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "requires": { + "lodash": "^4.17.15" + } + }, + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "requires": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "requires": { + "xmlchars": "^2.1.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + } + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "^2.1.0" + } + }, + "ts-jest": { + "version": "25.5.0", + "integrity": "sha512-govrjbOk1UEzcJ5cX5k8X8IUtFuP3lp3mrF3ZuKtCdAOQzdeCM7qualhb/U8s8SWFwEDutOqfF5PLkJ+oaYD4w==", + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "micromatch": "4.x", + "mkdirp": "0.x", + "semver": "6.x", + "yargs-parser": "18.x" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "3.8.3", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==" + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "@wordpress/babel-plugin-import-jsx-pragma": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-1.1.3.tgz", diff --git a/package.json b/package.json index eb02d05cb0e..cf829f7d5a3 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@typescript-eslint/eslint-plugin": "3.1.0", "@typescript-eslint/parser": "3.1.0", "@woocommerce/e2e-environment": "file:tests/e2e/env", + "@woocommerce/e2e-factories": "file:tests/e2e/factories", "@wordpress/babel-plugin-import-jsx-pragma": "1.1.3", "@wordpress/babel-preset-default": "3.0.2", "@wordpress/e2e-test-utils": "4.6.0", diff --git a/tests/e2e/docker/initialize.sh b/tests/e2e/docker/initialize.sh index f04484a8947..86426ca19df 100755 --- a/tests/e2e/docker/initialize.sh +++ b/tests/e2e/docker/initialize.sh @@ -5,3 +5,6 @@ echo "Initializing WooCommerce E2E" wp plugin install woocommerce --activate wp theme install twentynineteen --activate wp user create customer customer@woocommercecoree2etestsuite.com --user_pass=password --role=customer --path=/var/www/html + +# we cannot create API keys for the API, so we using basic auth, this plugin allows that. +wp plugin install https://github.com/WP-API/Basic-Auth/archive/master.zip --activate diff --git a/tests/e2e/factories/src/index.ts b/tests/e2e/factories/src/index.ts index 6d291ded820..c488478486b 100644 --- a/tests/e2e/factories/src/index.ts +++ b/tests/e2e/factories/src/index.ts @@ -14,4 +14,4 @@ export * from './models'; * UTILITIES * These exports relate to common utilities that can be used to utilize the package. */ -export { initializeAPIAdapters } from './utils'; +export { initializeUsingOAuth, initializeUsingBasicAuth } from './utils'; diff --git a/tests/e2e/factories/src/utils.ts b/tests/e2e/factories/src/utils.ts index bbdc4f5674f..cd2f445725e 100644 --- a/tests/e2e/factories/src/utils.ts +++ b/tests/e2e/factories/src/utils.ts @@ -10,7 +10,7 @@ import { AxiosAPIService } from './framework/api/axios/axios-api-service'; * @param {string} consumerKey The OAuth consumer key for the API service. * @param {string} consumerSecret The OAuth consumer secret for the API service. */ -export function initializeAPIAdapters( +export function initializeUsingOAuth( registry: ModelRegistry, apiURL: string, consumerKey: string, @@ -26,3 +26,30 @@ export function initializeAPIAdapters( adapter.setAPIService( apiService ); } } + +/** + * Initialize all of the APIAdapters with a client to communicate with the API. + * + * + * + * @param {ModelRegistry} registry The model registry that we want to initialize. + * @param {string} apiURL The base URL for the API. + * @param {string} username The username to use for authentication. + * @param {string} password The password to use for authentication. + */ +export function initializeUsingBasicAuth( + registry: ModelRegistry, + apiURL: string, + username: string, + password: string, +): void { + const adapters = registry.getAdapters( AdapterTypes.API ) as APIAdapter[]; + if ( ! adapters.length ) { + return; + } + + const apiService = AxiosAPIService.createUsingBasicAuth( apiURL, username, password ); + for ( const adapter of adapters ) { + adapter.setAPIService( apiService ); + } +} diff --git a/tests/e2e/utils/components.js b/tests/e2e/utils/components.js index 37b0e99e080..f6aa03b65c3 100644 --- a/tests/e2e/utils/components.js +++ b/tests/e2e/utils/components.js @@ -7,6 +7,12 @@ */ import { StoreOwnerFlow } from './flows'; import { clickTab, uiUnblocked, verifyCheckboxIsUnset } from './index'; +import { + AdapterTypes, + initializeUsingBasicAuth, + ModelRegistry, + registerSimpleProduct, SimpleProduct +} from '@woocommerce/e2e-factories'; const config = require( 'config' ); const simpleProductName = config.get( 'products.simple.name' ); @@ -347,22 +353,19 @@ const completeOldSetupWizard = async () => { * Create simple product. */ const createSimpleProduct = async () => { - // Go to "add product" page - await StoreOwnerFlow.openNewProduct(); - - // Make sure we're on the add order page - await expect( page.title() ).resolves.toMatch( 'Add new product' ); - - // Set product data - await expect( page ).toFill( '#title', simpleProductName ); - await clickTab( 'General' ); - await expect( page ).toFill( '#_regular_price', '9.99' ); - - await verifyAndPublish(); - - const simplePostId = await page.$( '#post_ID' ); - let simplePostIdValue = ( await ( await simplePostId.getProperty( 'value' ) ).jsonValue() ); - return simplePostIdValue; + const registry = new ModelRegistry() + registerSimpleProduct( registry ); + initializeUsingBasicAuth( registry, + config.get( 'url' ) + '/wp-json', + config.get( 'users.admin.username' ), + config.get( 'users.admin.password' ) + ); + registry.changeAllFactoryAdapters( AdapterTypes.API ); + const product = await registry.getFactory( SimpleProduct ).create( { + Name: config.get( 'products.simple.name' ), + RegularPrice: '9.99' + } ); + return product.ID; } ; /** From f1a616e026417fb138e5850b0f4bb73df55e896a Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 10:56:21 -0700 Subject: [PATCH 286/440] Made the model properties compliant with code style --- .../src/framework/api/api-adapter.spec.ts | 8 ++++---- .../factories/src/framework/api/api-adapter.ts | 6 +++--- .../factories/src/framework/model-factory.spec.ts | 10 +++++----- tests/e2e/factories/src/framework/model.ts | 15 +++------------ tests/e2e/factories/src/models/product.ts | 4 ++-- tests/e2e/factories/src/models/simple-product.ts | 4 ++-- 6 files changed, 19 insertions(+), 28 deletions(-) diff --git a/tests/e2e/factories/src/framework/api/api-adapter.spec.ts b/tests/e2e/factories/src/framework/api/api-adapter.spec.ts index cc046b12752..117121b6fc0 100644 --- a/tests/e2e/factories/src/framework/api/api-adapter.spec.ts +++ b/tests/e2e/factories/src/framework/api/api-adapter.spec.ts @@ -27,7 +27,7 @@ describe( 'APIModelCreator', () => { const result = await adapter.create( new SimpleProduct() ); expect( result ).toBeInstanceOf( SimpleProduct ); - expect( result.ID ).toBe( 1 ); + expect( result.id ).toBe( 1 ); expect( mockService.post.mock.calls[ 0 ][ 0 ] ).toBe( '/wc/v3/product' ); expect( mockService.post.mock.calls[ 0 ][ 1 ] ).toBe( 'test' ); } ); @@ -42,9 +42,9 @@ describe( 'APIModelCreator', () => { expect( result ).toBeInstanceOf( Array ); expect( result ).toHaveLength( 3 ); - expect( result[ 0 ].ID ).toBe( 1 ); - expect( result[ 1 ].ID ).toBe( 2 ); - expect( result[ 2 ].ID ).toBe( 3 ); + expect( result[ 0 ].id ).toBe( 1 ); + expect( result[ 1 ].id ).toBe( 2 ); + expect( result[ 2 ].id ).toBe( 3 ); expect( mockService.post.mock.calls[ 0 ][ 0 ] ).toBe( '/wc/v3/product' ); expect( mockService.post.mock.calls[ 0 ][ 1 ] ).toBe( 'test' ); expect( mockService.post.mock.calls[ 1 ][ 0 ] ).toBe( '/wc/v3/product' ); diff --git a/tests/e2e/factories/src/framework/api/api-adapter.ts b/tests/e2e/factories/src/framework/api/api-adapter.ts index c8b2a3cd038..e12938323cc 100644 --- a/tests/e2e/factories/src/framework/api/api-adapter.ts +++ b/tests/e2e/factories/src/framework/api/api-adapter.ts @@ -1,4 +1,4 @@ -import { APIService } from './api-service'; +import { APIResponse, APIService } from './api-service'; import { Model } from '../model'; import { Adapter } from '../adapter'; @@ -64,8 +64,8 @@ export class APIAdapter implements Adapter { return this.apiService!.post( this.endpoint, this.transformer( model ), - ).then( ( data ) => { - model.onCreated( data.data ); + ).then( ( data: APIResponse ) => { + model.setID( data.data.id ); return model; } ); } diff --git a/tests/e2e/factories/src/framework/model-factory.spec.ts b/tests/e2e/factories/src/framework/model-factory.spec.ts index 4850f77b854..cbc166ccce2 100644 --- a/tests/e2e/factories/src/framework/model-factory.spec.ts +++ b/tests/e2e/factories/src/framework/model-factory.spec.ts @@ -27,15 +27,15 @@ describe( 'ModelFactory', () => { it( 'should create using adapter', async () => { factory.setAdapter( mockAdapter ); - const expectedModel = new SimpleProduct( { Name: 'test2' } ); - expectedModel.onCreated( { id: 1 } ); + const expectedModel = new SimpleProduct( { name: 'test2' } ); + expectedModel.setID( 1 ); mockAdapter.create.mockReturnValueOnce( Promise.resolve( expectedModel ) ); - const created = await factory.create( { Name: 'test' } ); + const created = await factory.create( { name: 'test' } ); expect( mockAdapter.create.mock.calls ).toHaveLength( 1 ); expect( created ).toBeInstanceOf( Product ); - expect( created.ID ).toBe( 1 ); - expect( created.Name ).toBe( 'test2' ); + expect( created.id ).toBe( 1 ); + expect( created.name ).toBe( 'test2' ); } ); } ); diff --git a/tests/e2e/factories/src/framework/model.ts b/tests/e2e/factories/src/framework/model.ts index 103d4b1535c..80d071818ae 100644 --- a/tests/e2e/factories/src/framework/model.ts +++ b/tests/e2e/factories/src/framework/model.ts @@ -10,20 +10,11 @@ export abstract class Model { Object.assign( this, partial ); } - public get ID(): number { + public get id(): number { return this._id; } - /** - * A handler to be called after the model has been created. - * - * @param {*} created The model that was created on the server. - */ - public onCreated( created: any ): void { - if ( this._id ) { - throw new Error( 'The model has been created already.' ); - } - - this._id = created.id; + public setID( id: number ): void { + this._id = id; } } diff --git a/tests/e2e/factories/src/models/product.ts b/tests/e2e/factories/src/models/product.ts index 12d6b83c5d9..857495cb749 100644 --- a/tests/e2e/factories/src/models/product.ts +++ b/tests/e2e/factories/src/models/product.ts @@ -5,8 +5,8 @@ import { DeepPartial } from 'fishery'; * The base class for all product types. */ export abstract class Product extends Model { - public readonly Name: string = ''; - public readonly RegularPrice: string = ''; + public readonly name: string = ''; + public readonly regularPrice: string = ''; protected constructor( partial: DeepPartial = {} ) { super( partial ); diff --git a/tests/e2e/factories/src/models/simple-product.ts b/tests/e2e/factories/src/models/simple-product.ts index 14f96f4567e..7f258852265 100644 --- a/tests/e2e/factories/src/models/simple-product.ts +++ b/tests/e2e/factories/src/models/simple-product.ts @@ -33,8 +33,8 @@ export function registerSimpleProduct( registry: ModelRegistry ): void { ( model ) => { return { type: 'simple', - name: model.Name, - regular_price: model.RegularPrice, + name: model.name, + regular_price: model.regularPrice, }; }, ); From 9b18a95f936b86c755e87739d7748e07ab3ccc68 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 11:50:04 -0700 Subject: [PATCH 287/440] Adjusted the build:packages command to allow each package to build itself --- package.json | 4 +- tests/e2e/bin/build.js | 32 ++++-------- tests/e2e/bin/get-packages.js | 83 -------------------------------- tests/e2e/env/package.json | 4 ++ tests/e2e/factories/package.json | 7 ++- 5 files changed, 21 insertions(+), 109 deletions(-) delete mode 100644 tests/e2e/bin/get-packages.js diff --git a/package.json b/package.json index cf829f7d5a3..d7f695e4599 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "build": "grunt && npm run makepot", "build-watch": "grunt watch", - "build:packages": "node ./tests/e2e/bin/build.js", + "build:packages": "lerna run build", "build:zip": "./bin/build-zip.sh", "lint:js": "eslint assets/js --ext=js", "docker:up": "npm explore @woocommerce/e2e-environment -- npm run docker:up", @@ -21,7 +21,7 @@ "test:e2e-dev": "npm explore @woocommerce/e2e-environment -- npm run test:e2e-dev", "makepot": "composer run-script makepot", "packages:fix:textdomain": "node ./bin/package-update-textdomain.js", - "publish-packages": "npm run build:packages && lerna publish from-package", + "publish-packages": "lerna publish from-package", "git:update-hooks": "rm -r .git/hooks && mkdir -p .git/hooks && node ./node_modules/husky/husky.js install" }, "devDependencies": { diff --git a/tests/e2e/bin/build.js b/tests/e2e/bin/build.js index 1f8a94d1da0..064e2590f37 100755 --- a/tests/e2e/bin/build.js +++ b/tests/e2e/bin/build.js @@ -19,13 +19,13 @@ const deasync = require( 'deasync' ); /** * Internal dependencies */ -const getPackages = require( './get-packages' ); const getBabelConfig = require( './get-babel-config' ); /** * Module Constants */ -const PACKAGES_DIR = path.resolve( __dirname, '../' ); +const PACKAGE_DIR = process.cwd(); +const PACKAGE_NAME = PACKAGE_DIR.split( path.sep ).pop(); const SRC_DIR = 'src'; const BUILD_DIR = { main: 'build', @@ -33,16 +33,6 @@ const BUILD_DIR = { }; const DONE = chalk.reset.inverse.bold.green( ' DONE ' ); -/** - * Get the package name for a specified file - * - * @param {string} file File name - * @return {string} Package name - */ -function getPackageName( file ) { - return path.relative( PACKAGES_DIR, file ).split( path.sep )[ 0 ]; -} - const isJsFile = ( filepath ) => { return /.\.js$/.test( filepath ); }; @@ -55,9 +45,8 @@ const isJsFile = ( filepath ) => { * @return {string} Build path */ function getBuildPath( file, buildFolder ) { - const pkgName = getPackageName( file ); - const pkgSrcPath = path.resolve( PACKAGES_DIR, pkgName, SRC_DIR ); - const pkgBuildPath = path.resolve( PACKAGES_DIR, pkgName, buildFolder ); + const pkgSrcPath = path.resolve( PACKAGE_DIR, SRC_DIR ); + const pkgBuildPath = path.resolve( PACKAGE_DIR, buildFolder ); const relativeToSrcPath = path.relative( pkgSrcPath, file ); return path.resolve( pkgBuildPath, relativeToSrcPath ); } @@ -121,9 +110,9 @@ function buildJsFileFor( file, silent, environment ) { if ( ! silent ) { process.stdout.write( chalk.green( ' \u2022 ' ) + - path.relative( PACKAGES_DIR, file ) + + path.relative( PACKAGE_DIR, file ) + chalk.green( ' \u21D2 ' ) + - path.relative( PACKAGES_DIR, destPath ) + + path.relative( PACKAGE_DIR, destPath ) + '\n' ); } @@ -136,6 +125,9 @@ function buildJsFileFor( file, silent, environment ) { */ function buildPackage( packagePath ) { const srcDir = path.resolve( packagePath, SRC_DIR ); + + process.stdout.write( chalk.inverse( `>> Building package: ${ PACKAGE_NAME }\n` ) ); + const jsFiles = glob.sync( `${ srcDir }/**/*.js`, { ignore: [ `${ srcDir }/**/test/**/*.js`, @@ -144,8 +136,6 @@ function buildPackage( packagePath ) { nodir: true, } ); - process.stdout.write( `${ path.basename( packagePath ) }\n` ); - // Build js files individually. jsFiles.forEach( ( file ) => buildJsFile( file, true ) ); @@ -157,7 +147,5 @@ const files = process.argv.slice( 2 ); if ( files.length ) { buildFiles( files ); } else { - process.stdout.write( chalk.inverse( '>> Building packages \n' ) ); - getPackages().forEach( buildPackage ); - process.stdout.write( '\n' ); + buildPackage( PACKAGE_DIR ); } diff --git a/tests/e2e/bin/get-packages.js b/tests/e2e/bin/get-packages.js deleted file mode 100644 index dc6eaeb0ea8..00000000000 --- a/tests/e2e/bin/get-packages.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * External dependencies - */ -const fs = require( 'fs' ); -const path = require( 'path' ); -const { overEvery, compact, includes, negate } = require( 'lodash' ); - -/** - * Absolute path to packages directory. - * - * @type {string} - */ -const PACKAGES_DIR = path.resolve( __dirname, '../' ); - -const { - /** - * Comma-separated string of packages to include in build. - * - * @type {string} - */ - INCLUDE_PACKAGES, - - /** - * Comma-separated string of packages to exclude from build. - * - * @type {string} - */ - EXCLUDE_PACKAGES, -} = process.env; - -/** - * Given a comma-separated string, returns a filter function which returns true - * if the item is contained within as a comma-separated entry. - * - * @param {Function} filterFn Filter function to call with item to test. - * @param {string} list Comma-separated list of items. - * - * @return {Function} Filter function. - */ -const createCommaSeparatedFilter = ( filterFn, list ) => { - const listItems = list.split( ',' ); - return ( item ) => filterFn( listItems, item ); -}; - -/** - * Returns true if the given base file name for a file within the packages - * directory is itself a directory. - * - * @param {string} file Packages directory file. - * - * @return {boolean} Whether file is a directory. - */ -function isDirectory( file ) { - return fs.lstatSync( path.resolve( PACKAGES_DIR, file ) ).isDirectory(); -} - -/** - * Filter predicate, returning true if the given base file name is to be - * included in the build. - * - * @param {string} pkg File base name to test. - * - * @return {boolean} Whether to include file in build. - */ -const filterPackages = overEvery( compact( [ - isDirectory, - INCLUDE_PACKAGES && createCommaSeparatedFilter( includes, INCLUDE_PACKAGES ), - EXCLUDE_PACKAGES && createCommaSeparatedFilter( negate( includes ), EXCLUDE_PACKAGES ), -] ) ); - -/** - * Returns the absolute path of all WordPress packages - * - * @return {Array} Package paths - */ -function getPackages() { - return fs - .readdirSync( PACKAGES_DIR ) - .filter( filterPackages ) - .map( ( file ) => path.resolve( PACKAGES_DIR, file ) ); -} - -module.exports = getPackages; diff --git a/tests/e2e/env/package.json b/tests/e2e/env/package.json index f23629feff1..e4a9d0a1c31 100644 --- a/tests/e2e/env/package.json +++ b/tests/e2e/env/package.json @@ -41,6 +41,10 @@ "access": "public" }, "scripts": { + "clean": "rm -rf ./build ./build-module", + "compile": "node ./../bin/build.js", + "build": "npm run clean && npm run compile", + "prepare": "npm run build", "docker:up": "./bin/docker-compose.js up", "docker:down": "./bin/docker-compose.js down", "docker:clear-all": "docker rmi --force $(docker images -q)", diff --git a/tests/e2e/factories/package.json b/tests/e2e/factories/package.json index f7e5a95e85f..c09bfee742a 100644 --- a/tests/e2e/factories/package.json +++ b/tests/e2e/factories/package.json @@ -25,8 +25,11 @@ ], "sideEffects": false, "scripts": { - "build": "tsc", - "test": "jest" + "test": "jest", + "clean": "rm -rf ./dist ./tsconfig.tsbuildinfo", + "compile": "tsc -b", + "build": "npm run clean && npm run compile", + "prepare": "npm run build" }, "dependencies": { "axios": "0.19.2", From 4373c7be1b20ecfddd1bcf7650907fc3ac209c41 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 13:13:23 -0700 Subject: [PATCH 288/440] Moved the factory package init into a common utility --- tests/e2e/utils/components.js | 24 ++++++------------------ tests/e2e/utils/factories.js | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 tests/e2e/utils/factories.js diff --git a/tests/e2e/utils/components.js b/tests/e2e/utils/components.js index f6aa03b65c3..3fe4712675a 100644 --- a/tests/e2e/utils/components.js +++ b/tests/e2e/utils/components.js @@ -7,12 +7,8 @@ */ import { StoreOwnerFlow } from './flows'; import { clickTab, uiUnblocked, verifyCheckboxIsUnset } from './index'; -import { - AdapterTypes, - initializeUsingBasicAuth, - ModelRegistry, - registerSimpleProduct, SimpleProduct -} from '@woocommerce/e2e-factories'; +import modelRegistry from './factories'; +import { SimpleProduct } from '@woocommerce/e2e-factories'; const config = require( 'config' ); const simpleProductName = config.get( 'products.simple.name' ); @@ -353,19 +349,11 @@ const completeOldSetupWizard = async () => { * Create simple product. */ const createSimpleProduct = async () => { - const registry = new ModelRegistry() - registerSimpleProduct( registry ); - initializeUsingBasicAuth( registry, - config.get( 'url' ) + '/wp-json', - config.get( 'users.admin.username' ), - config.get( 'users.admin.password' ) - ); - registry.changeAllFactoryAdapters( AdapterTypes.API ); - const product = await registry.getFactory( SimpleProduct ).create( { - Name: config.get( 'products.simple.name' ), - RegularPrice: '9.99' + const product = await modelRegistry.getFactory( SimpleProduct ).create( { + name: simpleProductName, + regularPrice: '9.99' } ); - return product.ID; + return product.id; } ; /** diff --git a/tests/e2e/utils/factories.js b/tests/e2e/utils/factories.js new file mode 100644 index 00000000000..8091d9286d7 --- /dev/null +++ b/tests/e2e/utils/factories.js @@ -0,0 +1,24 @@ +import { + AdapterTypes, + initializeUsingBasicAuth, + ModelRegistry, + registerSimpleProduct +} from '@woocommerce/e2e-factories'; + +const config = require( 'config' ); + +const modelRegistry = new ModelRegistry() + +// Register all of the different factories that we're going to need. +registerSimpleProduct( modelRegistry ); + +// Make sure to perform the initialization AFTER registering all of the factories, otherwise the adapters might be +// missed on subsequent registrations. +initializeUsingBasicAuth( modelRegistry, + config.get( 'url' ) + '/wp-json', + config.get( 'users.admin.username' ), + config.get( 'users.admin.password' ) +); +modelRegistry.changeAllFactoryAdapters( AdapterTypes.API ); + +export default modelRegistry; From d8beef56b510fc39c1e4bd7dadb0b2d2a7aa2398 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 13:33:30 -0700 Subject: [PATCH 289/440] Added support for faker to populate models with dummy data --- tests/e2e/factories/package-lock.json | 11 +++++++++++ tests/e2e/factories/package.json | 2 ++ tests/e2e/factories/src/models/simple-product.ts | 8 +++++++- tests/e2e/factories/tsconfig.json | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/e2e/factories/package-lock.json b/tests/e2e/factories/package-lock.json index fec2ecbee22..5b51716d93a 100644 --- a/tests/e2e/factories/package-lock.json +++ b/tests/e2e/factories/package-lock.json @@ -720,6 +720,12 @@ "@types/node": "*" } }, + "@types/faker": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-4.1.12.tgz", + "integrity": "sha512-0MEyzJrLLs1WaOCx9ULK6FzdCSj2EuxdSP9kvuxxdBEGujZYUOZ4vkPXdgu3dhyg/pOdn7VCatelYX7k0YShlA==", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", @@ -1851,6 +1857,11 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, + "faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=" + }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", diff --git a/tests/e2e/factories/package.json b/tests/e2e/factories/package.json index c09bfee742a..208fe0542f5 100644 --- a/tests/e2e/factories/package.json +++ b/tests/e2e/factories/package.json @@ -34,11 +34,13 @@ "dependencies": { "axios": "0.19.2", "create-hmac": "1.1.7", + "faker": "4.1.0", "fishery": "1.0.0", "oauth-1.0a": "2.2.6" }, "devDependencies": { "@types/create-hmac": "1.1.0", + "@types/faker": "4.1.12", "@types/jest": "25.2.1", "@types/moxios": "0.4.9", "@types/node": "13.13.5", diff --git a/tests/e2e/factories/src/models/simple-product.ts b/tests/e2e/factories/src/models/simple-product.ts index 7f258852265..e225970e988 100644 --- a/tests/e2e/factories/src/models/simple-product.ts +++ b/tests/e2e/factories/src/models/simple-product.ts @@ -3,6 +3,7 @@ import { Product } from './product'; import { AdapterTypes, ModelRegistry } from '../framework/model-registry'; import { ModelFactory } from '../framework/model-factory'; import { APIAdapter } from '../framework/api/api-adapter'; +import faker from 'faker/locale/en'; export class SimpleProduct extends Product { public constructor( partial: DeepPartial = {} ) { @@ -23,7 +24,12 @@ export function registerSimpleProduct( registry: ModelRegistry ): void { const factory = ModelFactory.define>( ( { params } ) => { - return new SimpleProduct( params ); + return new SimpleProduct( + { + name: params.name ?? faker.commerce.productName(), + regularPrice: params.regularPrice ?? faker.commerce.price(), + }, + ); }, ); registry.registerFactory( SimpleProduct, factory ); diff --git a/tests/e2e/factories/tsconfig.json b/tests/e2e/factories/tsconfig.json index b7f881ff66b..b94b7d7b9ba 100644 --- a/tests/e2e/factories/tsconfig.json +++ b/tests/e2e/factories/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../../../tsconfig.base.json", "compilerOptions": { - "types": [ "node", "jest", "axios", "moxios", "create-hmac" ], + "types": [ "node", "jest", "faker", "axios", "moxios", "create-hmac" ], "rootDir": "src", "outDir": "dist" }, From 5652025d28f47f96bf34197147d1918a0caab118 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 13:54:34 -0700 Subject: [PATCH 290/440] Removed unused adapter types --- tests/e2e/factories/src/framework/model-registry.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/e2e/factories/src/framework/model-registry.ts b/tests/e2e/factories/src/framework/model-registry.ts index c31a8ef122a..abf7a3934a9 100644 --- a/tests/e2e/factories/src/framework/model-registry.ts +++ b/tests/e2e/factories/src/framework/model-registry.ts @@ -9,12 +9,10 @@ type Registry = { [key: string ]: T }; * * @typedef AdapterTypes * @property {string} API "api" - * @property {string} Database "database" * @property {string} Custom "custom" */ export enum AdapterTypes { API = 'api', - Database = 'database', Custom = 'custom' } @@ -25,7 +23,6 @@ export class ModelRegistry { private readonly factories: Registry> = {}; private readonly adapters: { [key in AdapterTypes]: Registry> } = { api: {}, - database: {}, custom: {}, }; From 822179e4ac7949319eb27880d94d4534aa9751d5 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 14:16:01 -0700 Subject: [PATCH 291/440] Renamed the e2e-factories package to better reflect its usage-agnostic design --- package-lock.json | 9 +- package.json | 2 +- tests/e2e/bin/build.js | 9 +- tests/e2e/factories/package-lock.json | 716 +++++++++++++------------- tests/e2e/factories/package.json | 4 +- tests/e2e/utils/components.js | 2 +- tests/e2e/utils/factories.js | 2 +- 7 files changed, 374 insertions(+), 370 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3ec4a93f00f..1a5bf7885af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7247,7 +7247,7 @@ } } }, - "@woocommerce/e2e-factories": { + "@woocommerce/model-factories": { "version": "file:tests/e2e/factories", "dev": true, "requires": { @@ -7901,6 +7901,7 @@ }, "@types/create-hmac": { "version": "1.1.0", + "resolved": false, "integrity": "sha512-BNYNdzdhOZZQWCOpwvIll3FSvgo3e55Y2M6s/jOY6TuOCwqt3cLmQsK4tSmJ5fayDot8EG4k3+hcZagfww9JlQ==", "requires": { "@types/node": "*" @@ -7938,6 +7939,7 @@ }, "@types/jest": { "version": "25.2.1", + "resolved": false, "integrity": "sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA==", "requires": { "jest-diff": "^25.2.1", @@ -7946,6 +7948,7 @@ }, "@types/moxios": { "version": "0.4.9", + "resolved": false, "integrity": "sha512-Sd1b24QRW2N194j2LEDPQAZK1h0TBtpN+2EIH+rERCgm38qm14JZwC7NlpE7n3jULhlCIPZBG8uNcbjF8KcCaQ==", "requires": { "axios": "^0.19.0" @@ -9443,6 +9446,7 @@ }, "jest": { "version": "25.5.4", + "resolved": false, "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==", "requires": { "@jest/core": "^25.5.4", @@ -10202,6 +10206,7 @@ }, "moxios": { "version": "0.4.0", + "resolved": false, "integrity": "sha1-/A2ixlR31yXKa5Z51YNw7QxS9Ts=" }, "ms": { @@ -11394,6 +11399,7 @@ }, "ts-jest": { "version": "25.5.0", + "resolved": false, "integrity": "sha512-govrjbOk1UEzcJ5cX5k8X8IUtFuP3lp3mrF3ZuKtCdAOQzdeCM7qualhb/U8s8SWFwEDutOqfF5PLkJ+oaYD4w==", "requires": { "bs-logger": "0.x", @@ -11449,6 +11455,7 @@ }, "typescript": { "version": "3.8.3", + "resolved": false, "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==" }, "union-value": { diff --git a/package.json b/package.json index d7f695e4599..cd91ea283ed 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@typescript-eslint/eslint-plugin": "3.1.0", "@typescript-eslint/parser": "3.1.0", "@woocommerce/e2e-environment": "file:tests/e2e/env", - "@woocommerce/e2e-factories": "file:tests/e2e/factories", + "@woocommerce/model-factories": "file:tests/e2e/factories", "@wordpress/babel-plugin-import-jsx-pragma": "1.1.3", "@wordpress/babel-preset-default": "3.0.2", "@wordpress/e2e-test-utils": "4.6.0", diff --git a/tests/e2e/bin/build.js b/tests/e2e/bin/build.js index 064e2590f37..6b336b3c26d 100755 --- a/tests/e2e/bin/build.js +++ b/tests/e2e/bin/build.js @@ -25,7 +25,6 @@ const getBabelConfig = require( './get-babel-config' ); * Module Constants */ const PACKAGE_DIR = process.cwd(); -const PACKAGE_NAME = PACKAGE_DIR.split( path.sep ).pop(); const SRC_DIR = 'src'; const BUILD_DIR = { main: 'build', @@ -126,7 +125,13 @@ function buildJsFileFor( file, silent, environment ) { function buildPackage( packagePath ) { const srcDir = path.resolve( packagePath, SRC_DIR ); - process.stdout.write( chalk.inverse( `>> Building package: ${ PACKAGE_NAME }\n` ) ); + let packageName; + try { + packageName = require( path.resolve( PACKAGE_DIR, 'package.json' ) ).name; + } catch ( e ) { + packageName = PACKAGE_DIR.split( path.sep ).pop(); + } + process.stdout.write( chalk.inverse( `>> Building package: ${ packageName }\n` ) ); const jsFiles = glob.sync( `${ srcDir }/**/*.js`, { ignore: [ diff --git a/tests/e2e/factories/package-lock.json b/tests/e2e/factories/package-lock.json index 5b51716d93a..645ae0e5ea3 100644 --- a/tests/e2e/factories/package-lock.json +++ b/tests/e2e/factories/package-lock.json @@ -1,32 +1,32 @@ { - "name": "@woocommerce/e2e-factories", + "name": "@woocommerce/model-factories", "version": "0.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "requires": { - "@babel/highlight": "^7.10.1" + "@babel/highlight": "^7.10.4" } }, "@babel/core": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", - "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.4.tgz", + "integrity": "sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.2", - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helpers": "^7.10.1", - "@babel/parser": "^7.10.2", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.2", + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -37,149 +37,178 @@ "source-map": "^0.5.0" }, "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", + "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", "dev": true, "requires": { - "@babel/types": "^7.10.2", + "@babel/types": "^7.10.4", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", - "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", + "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.4" } }, "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.4" } }, "@babel/helper-module-transforms": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", - "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", + "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4", "lodash": "^4.17.13" } }, "@babel/helper-optimise-call-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", - "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.4" } }, "@babel/helper-plugin-utils": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", - "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true }, "@babel/helper-replace-supers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", - "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-simple-access": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", - "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", "dev": true, "requires": { - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", "dev": true, "requires": { - "@babel/types": "^7.10.1" + "@babel/types": "^7.10.4" } }, "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "@babel/helpers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", - "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", "dev": true, "requires": { - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.1", + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -237,9 +266,9 @@ } }, "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", + "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -261,12 +290,21 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", - "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-json-strings": { @@ -279,12 +317,12 @@ } }, "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.1.tgz", - "integrity": "sha512-XyHIFa9kdrgJS91CUH+ccPVTnJShr8nLGc5bG2IhGXv5p1Rd+8BleGE5yzIg2Nc1QZAdHDa0Qp4m6066OL96Iw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-nullish-coalescing-operator": { @@ -297,12 +335,12 @@ } }, "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", - "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.1" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -332,49 +370,68 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "@babel/runtime-corejs3": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", + "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" } }, "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", + "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" }, "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.1", + "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -406,14 +463,6 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } } }, "@istanbuljs/schema": { @@ -469,26 +518,6 @@ "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "@jest/environment": { @@ -557,14 +586,6 @@ "string-length": "^3.1.0", "terminal-link": "^2.0.0", "v8-to-istanbul": "^4.1.3" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "@jest/source-map": { @@ -576,14 +597,6 @@ "callsites": "^3.0.0", "graceful-fs": "^4.2.4", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "@jest/test-result": { @@ -633,14 +646,6 @@ "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "@jest/types": { @@ -665,9 +670,9 @@ } }, "@types/babel__core": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", - "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==", + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -736,9 +741,9 @@ } }, "@types/istanbul-lib-coverage": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz", - "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, "@types/istanbul-lib-report": { @@ -825,9 +830,9 @@ "dev": true }, "acorn": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", - "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", "dev": true }, "acorn-globals": { @@ -1048,14 +1053,15 @@ } }, "babel-preset-current-node-syntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", - "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", "dev": true, "requires": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1312,17 +1318,6 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "co": { @@ -1390,6 +1385,14 @@ "dev": true, "requires": { "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, "copy-descriptor": { @@ -1398,6 +1401,12 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1447,6 +1456,15 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -1494,19 +1512,21 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", + "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", + "dev": true, + "requires": { + "xregexp": "^4.2.4" + } }, "decode-uri-component": { "version": "0.2.0", @@ -1604,6 +1624,12 @@ "safer-buffer": "^2.1.0" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -1629,9 +1655,9 @@ "dev": true }, "escodegen": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.2.tgz", - "integrity": "sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, "requires": { "esprima": "^4.0.1", @@ -1639,15 +1665,6 @@ "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } } }, "esprima": { @@ -1736,12 +1753,6 @@ "requires": { "is-extendable": "^0.1.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -1863,9 +1874,9 @@ "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=" }, "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-json-stable-stringify": { @@ -1910,7 +1921,8 @@ }, "fishery": { "version": "1.0.0", - "resolved": "github:thoughtbot/fishery#b45f86d2073513aac9d9f577b4581b3de4ee75f3", + "resolved": "https://registry.npmjs.org/fishery/-/fishery-1.0.0.tgz", + "integrity": "sha512-DLQtxcSPlLQYY6J0tL/dl7DfPhrULHCAO6fFDGnrXqA830J6AW124fHarYOLnfvcSXNBEooBS/g65N/HecQYjQ==", "requires": { "lodash.merge": "^4.6.2" } @@ -1921,21 +1933,6 @@ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", "requires": { "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } } }, "for-in": { @@ -2039,6 +2036,12 @@ "path-is-absolute": "^1.0.0" } }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -2134,13 +2137,6 @@ "inherits": "^2.0.4", "readable-stream": "^3.6.0", "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } } }, "hosted-git-info": { @@ -2439,10 +2435,19 @@ "source-map": "^0.6.1" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -2582,15 +2587,6 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, @@ -2708,17 +2704,6 @@ "sane": "^4.0.3", "walker": "^1.0.7", "which": "^2.0.2" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, "jest-jasmine2": { @@ -2794,9 +2779,9 @@ } }, "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true }, "jest-regex-util": { @@ -3297,10 +3282,9 @@ "dev": true }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nanomatch": { "version": "1.2.13", @@ -3357,6 +3341,18 @@ "semver": "^6.3.0", "shellwords": "^0.1.1", "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "normalize-package-data": { @@ -3727,6 +3723,12 @@ "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", "dev": true }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -3855,16 +3857,14 @@ "dev": true, "requires": { "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } } }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -3877,6 +3877,15 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -3893,9 +3902,9 @@ "dev": true }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-regex": { "version": "1.1.0", @@ -4189,10 +4198,10 @@ "is-extendable": "^0.1.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } @@ -4269,9 +4278,9 @@ } }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "source-map-resolve": { @@ -4295,14 +4304,6 @@ "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "source-map-url": { @@ -4416,6 +4417,23 @@ "requires": { "astral-regex": "^1.0.0", "strip-ansi": "^5.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, "string-width": { @@ -4427,23 +4445,6 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "string_decoder": { @@ -4452,30 +4453,15 @@ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "requires": { "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } + "ansi-regex": "^5.0.0" } }, "strip-bom": { @@ -4876,9 +4862,9 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -4905,17 +4891,6 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "wrappy": { @@ -4954,6 +4929,15 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "dev": true, + "requires": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", @@ -4961,13 +4945,13 @@ "dev": true }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz", + "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==", "dev": true, "requires": { "cliui": "^6.0.0", - "decamelize": "^1.2.0", + "decamelize": "^3.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", @@ -4976,7 +4960,7 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" } }, "yargs-parser": { @@ -4987,6 +4971,14 @@ "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" + }, + "dependencies": { + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + } } } } diff --git a/tests/e2e/factories/package.json b/tests/e2e/factories/package.json index 208fe0542f5..e0a827e1979 100644 --- a/tests/e2e/factories/package.json +++ b/tests/e2e/factories/package.json @@ -1,8 +1,8 @@ { - "name": "@woocommerce/e2e-factories", + "name": "@woocommerce/model-factories", "version": "0.1.0", "author": "Automattic", - "description": "Factories for generating test data for use in WooCommerce End-To-End tests.", + "description": "A simple interface for generating models of different types.", "homepage": "https://github.com/woocommerce/woocommerce/tree/master/tests/e2e/factories/README.md", "repository": { "type": "git", diff --git a/tests/e2e/utils/components.js b/tests/e2e/utils/components.js index 3fe4712675a..644deab292a 100644 --- a/tests/e2e/utils/components.js +++ b/tests/e2e/utils/components.js @@ -8,7 +8,7 @@ import { StoreOwnerFlow } from './flows'; import { clickTab, uiUnblocked, verifyCheckboxIsUnset } from './index'; import modelRegistry from './factories'; -import { SimpleProduct } from '@woocommerce/e2e-factories'; +import { SimpleProduct } from '@woocommerce/model-factories'; const config = require( 'config' ); const simpleProductName = config.get( 'products.simple.name' ); diff --git a/tests/e2e/utils/factories.js b/tests/e2e/utils/factories.js index 8091d9286d7..f80d552513f 100644 --- a/tests/e2e/utils/factories.js +++ b/tests/e2e/utils/factories.js @@ -3,7 +3,7 @@ import { initializeUsingBasicAuth, ModelRegistry, registerSimpleProduct -} from '@woocommerce/e2e-factories'; +} from '@woocommerce/model-factories'; const config = require( 'config' ); From b5e1e1cc8a2884631035ff60321edf390af899af Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 14:39:18 -0700 Subject: [PATCH 292/440] Added a readme documenting the usage of the model factory package --- tests/e2e/factories/README.md | 58 +++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tests/e2e/factories/README.md diff --git a/tests/e2e/factories/README.md b/tests/e2e/factories/README.md new file mode 100644 index 00000000000..ae23c24129f --- /dev/null +++ b/tests/e2e/factories/README.md @@ -0,0 +1,58 @@ +# Model Factories + +A simple interface for generating models of different types. + +## Installation + +``bash +npm install @woocommerce/model-factories --save +`` + +## Usage + +Consumers of this package should rely on an instance of `ModelRegistry` to access the factories. +Here is an example of how to initialize and use the package to generate a simple product: + +```javascript +import { + AdapterTypes, + initializeUsingBasicAuth, + ModelRegistry, + registerSimpleProduct, + SimpleProduct +} from '@woocommerce/model-factories'; + +// The ModelRegistry instance is where all of the factories and adapters are stored in an easy-to-access way. +const modelRegistry = new ModelRegistry() + +// Call the register functions to add a kind of factory to the model registry. +// This will also add any adapters we've created for the factory, allowing it +// to be created on the server. +registerSimpleProduct( modelRegistry ); + +// Before you can use the included API adapter you need to initialize it using one of the utility methods. +// If you do not initialize the API adapters they will not be able to make requests to the API. +// Note that these utility functions only set up adapters that have been registered already +// and so further calls to `registeryXXX` functions will have adapters that aren't ready. +initializeUsingBasicAuth( modelRegistry, 'https://test.test/wp-json', 'admin', 'password' ); +initializeUsingOAuth( modelRegistry, 'https://test.test/wp-json', 'consumer_key', 'consumer_secret' ); + +// In order to actually create the models on the server, each registered factory must have an adapter set. +// You can do this on a per-factory basis using +modelRegistry.changeFactoryAdapter( SimpleProduct, AdapterTypes.API ); +// You can do this to all factories registered using +modelRegistry.changeAllFactoryAdapters( AdapterTypes.API ); + +// Once all of the initialization has been taken care of you can create models! +// Any fields that are not defined will be filled out by random data. +const product = await modelRegistry.getFactory( SimpleProduct ).create( { name: 'Test Product' } ); +// You can now access the ID of the created model using `product.id`! + +// You can also create models in bulk! +const poducts = await modelRegistry.getFactory( SimpleProduct ).createList( 5 ); +// You now have an array of products to work with! +``` + +## Custom Models + +## Custom Adapters From 3e1d07dd970bb3dc2b57a7df9678ae18258fcbef Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 14:44:36 -0700 Subject: [PATCH 293/440] Updated the package-lock.json after fixing merge conflicts --- package-lock.json | 8494 ++++++++++++++++++++++++++++++++------------- 1 file changed, 6157 insertions(+), 2337 deletions(-) diff --git a/package-lock.json b/package-lock.json index 340dd04d9cb..9ee7b95ecd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -320,28 +320,37 @@ } }, "@babel/helper-builder-react-jsx": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz", - "integrity": "sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz", + "integrity": "sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/types": "^7.9.0" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/types": "^7.10.4" }, "dependencies": { + "@babel/helper-annotate-as-pure": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", + "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -355,29 +364,47 @@ } }, "@babel/helper-builder-react-jsx-experimental": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.5.tgz", - "integrity": "sha512-HAagjAC93tk748jcXpZ7oYRZH485RCq/+yEv9SIWezHRPv9moZArTnkUNciUNzvwHUABmiWKlcxJvMcu59UwTg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.4.tgz", + "integrity": "sha512-LyacH/kgQPgLAuaWrvvq1+E7f5bLyT8jXCh7nM67sRsy2cpIGfgWJ+FCnAKQXfY+F0tXUaN6FqLkp4JiCzdK8Q==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-module-imports": "^7.8.3", - "@babel/types": "^7.9.5" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-module-imports": "^7.10.4", + "@babel/types": "^7.10.4" }, "dependencies": { + "@babel/helper-annotate-as-pure": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", + "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -1851,18 +1878,18 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", - "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", + "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true } } @@ -2566,21 +2593,21 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.4.tgz", - "integrity": "sha512-Mjqf3pZBNLt854CK0C/kRuXAnE6H/bo7xYojP+WGtX8glDGSibcwnsWwhwoSuRg0+EBnxPC1ouVnuetUIlPSAw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz", + "integrity": "sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A==", "dev": true, "requires": { - "@babel/helper-builder-react-jsx": "^7.9.0", - "@babel/helper-builder-react-jsx-experimental": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.8.3" + "@babel/helper-builder-react-jsx": "^7.10.4", + "@babel/helper-builder-react-jsx-experimental": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-jsx": "^7.10.4" }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true } } @@ -2612,21 +2639,53 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.6.tgz", - "integrity": "sha512-qcmiECD0mYOjOIt8YHNsAP1SxPooC/rDmfmiSK9BNY72EitdSc7l44WTEklaWuFtbOEBjNhWWyph/kOImbNJ4w==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.4.tgz", + "integrity": "sha512-8ULlGv8p+Vuxu+kz2Y1dk6MYS2b/Dki+NO6/0ZlfSj5tMalfDL7jI/o/2a+rrWLqSXvnadEqc2WguB4gdQIxZw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", "resolve": "^1.8.1", "semver": "^5.5.1" }, "dependencies": { + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true } } @@ -2888,6 +2947,24 @@ "regenerator-runtime": "^0.13.2" } }, + "@babel/runtime-corejs3": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", + "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, "@babel/template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", @@ -3121,9 +3198,9 @@ } }, "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "tar": { @@ -5103,194 +5180,12 @@ "whatwg-url": "^7.0.0" }, "dependencies": { - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -5836,152 +5731,6 @@ "write-json-file": "^3.2.0" }, "dependencies": { - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", @@ -5995,27 +5744,6 @@ "type-fest": "^0.3.0" } }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", @@ -6032,29 +5760,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -6308,17 +6013,6 @@ "@lerna/query-graph": "3.18.5", "figgy-pudding": "^3.5.1", "p-queue": "^4.0.0" - }, - "dependencies": { - "p-queue": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-4.0.0.tgz", - "integrity": "sha512-3cRXXn3/O0o3+eVmUroJPSj/esxoEFIm0ZOno/T+NzG/VZgPOqQ8WKmlNqubSEpZmCIngEy34unkHGg83ZIBmg==", - "dev": true, - "requires": { - "eventemitter3": "^3.1.0" - } - } } }, "@lerna/symlink-binary": { @@ -6528,38 +6222,29 @@ } }, "@octokit/auth-token": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.0.tgz", - "integrity": "sha512-eoOVMjILna7FVQf96iWc3+ZtE/ZT6y8ob8ZzcqKY1ibSQCnu4O/B7pJvzMx5cyZ/RjAff6DAdEb0O0Cjcxidkg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.2.tgz", + "integrity": "sha512-jE/lE/IKIz2v1+/P0u4fJqv0kYwXOTujKemJMFr6FeopsxlIK3+wKDCJGnysg81XID5TgZQbIfuJ5J0lnTiuyQ==", "dev": true, "requires": { - "@octokit/types": "^2.0.0" + "@octokit/types": "^5.0.0" } }, "@octokit/endpoint": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz", - "integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.3.tgz", + "integrity": "sha512-Y900+r0gIz+cWp6ytnkibbD95ucEzDSKzlEnaWS52hbCDNcCJYO5mRmWW7HRAnDc7am+N/5Lnd8MppSaTYx1Yg==", "dev": true, "requires": { - "@octokit/types": "^2.11.1", + "@octokit/types": "^5.0.0", "is-plain-object": "^3.0.0", "universal-user-agent": "^5.0.0" }, "dependencies": { "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "dev": true, - "requires": { - "isobject": "^4.0.0" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", "dev": true }, "universal-user-agent": { @@ -6586,6 +6271,17 @@ "dev": true, "requires": { "@octokit/types": "^2.0.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } } }, "@octokit/plugin-request-log": { @@ -6602,17 +6298,28 @@ "requires": { "@octokit/types": "^2.0.1", "deprecation": "^2.3.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } } }, "@octokit/request": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz", - "integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.5.tgz", + "integrity": "sha512-atAs5GAGbZedvJXXdjtKljin+e2SltEs48B3naJjqWupYl2IUBbB/CJisyjbNHcKpHzb3E+OYEZ46G8eakXgQg==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", "@octokit/request-error": "^2.0.0", - "@octokit/types": "^2.11.1", + "@octokit/types": "^5.0.0", "deprecation": "^2.0.0", "is-plain-object": "^3.0.0", "node-fetch": "^2.3.0", @@ -6621,29 +6328,20 @@ }, "dependencies": { "@octokit/request-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.0.tgz", - "integrity": "sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.2.tgz", + "integrity": "sha512-2BrmnvVSV1MXQvEkrb9zwzP0wXFNbPJij922kYBTLIlIafukrGOb+ABBT2+c6wZiuyWDH1K1zmjGQ0toN/wMWw==", "dev": true, "requires": { - "@octokit/types": "^2.0.0", + "@octokit/types": "^5.0.1", "deprecation": "^2.0.0", "once": "^1.4.0" } }, "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "dev": true, - "requires": { - "isobject": "^4.0.0" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", "dev": true }, "node-fetch": { @@ -6672,12 +6370,23 @@ "@octokit/types": "^2.0.0", "deprecation": "^2.0.0", "once": "^1.4.0" + }, + "dependencies": { + "@octokit/types": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "dev": true, + "requires": { + "@types/node": ">= 8" + } + } } }, "@octokit/rest": { - "version": "16.43.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.1.tgz", - "integrity": "sha512-gfFKwRT/wFxq5qlNjnW2dh+qh74XgTQ2B179UX5K1HYCluioWj8Ndbgqw2PVqa1NnVJkGHp2ovMpVn/DImlmkw==", + "version": "16.43.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz", + "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==", "dev": true, "requires": { "@octokit/auth-token": "^2.4.0", @@ -6699,9 +6408,9 @@ } }, "@octokit/types": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz", - "integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.0.1.tgz", + "integrity": "sha512-GorvORVwp244fGKEt3cgt/P+M0MGy4xEDbckw+K5ojEezxyMDgCaYPKVct+/eWQfZXOT7uq0xRpmrl/+hliabA==", "dev": true, "requires": { "@types/node": ">= 8" @@ -6769,6 +6478,12 @@ "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } + }, + "p-queue": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz", + "integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng==", + "dev": true } } }, @@ -6850,6 +6565,12 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -6919,12 +6640,24 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, "@types/node": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.0.tgz", "integrity": "sha512-Jrb/x3HT4PTJp6a4avhmJCDEVrPdqLfl3e8GGMbpkGGdwAV5UGlIs4vVEfsHHfylZVOKZWpOqmqFH8CbfOZ6kg==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, "@types/p-queue": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz", @@ -6990,6 +6723,104 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.1.0.tgz", + "integrity": "sha512-D52KwdgkjYc+fmTZKW7CZpH5ZBJREJKZXRrveMiRCmlzZ+Rw9wRVJ1JAmHQ9b/+Ehy1ZeaylofDB9wwXUt83wg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "3.1.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz", + "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz", + "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@typescript-eslint/experimental-utils": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.26.0.tgz", @@ -7013,6 +6844,97 @@ } } }, + "@typescript-eslint/parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.1.0.tgz", + "integrity": "sha512-NcDSJK8qTA2tPfyGiPes9HtVKLbksmuYjlgGAUs7Ld2K0swdWibnCq9IJx9kJN8JJdgUJSorFiGaPHBgH81F/Q==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "3.1.0", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz", + "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz", + "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@typescript-eslint/typescript-estree": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.26.0.tgz", @@ -7325,6 +7247,4486 @@ } } }, + "@woocommerce/model-factories": { + "version": "file:tests/e2e/factories", + "dev": true, + "requires": { + "axios": "0.19.2", + "create-hmac": "1.1.7", + "faker": "4.1.0", + "fishery": "1.0.0", + "oauth-1.0a": "2.2.6" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.4.tgz", + "integrity": "sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/generator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", + "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", + "requires": { + "@babel/types": "^7.10.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", + "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", + "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", + "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==" + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/runtime-corejs3": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", + "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", + "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@babel/types": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + }, + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz", + "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/reporters": "^25.5.1", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^25.5.0", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-resolve-dependencies": "^25.5.4", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "jest-watcher": "^25.5.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "realpath-native": "^2.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + } + }, + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "requires": { + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", + "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "@types/create-hmac": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/create-hmac/-/create-hmac-1.1.0.tgz", + "integrity": "sha512-BNYNdzdhOZZQWCOpwvIll3FSvgo3e55Y2M6s/jOY6TuOCwqt3cLmQsK4tSmJ5fayDot8EG4k3+hcZagfww9JlQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/faker": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-4.1.12.tgz", + "integrity": "sha512-0MEyzJrLLs1WaOCx9ULK6FzdCSj2EuxdSP9kvuxxdBEGujZYUOZ4vkPXdgu3dhyg/pOdn7VCatelYX7k0YShlA==" + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.1.tgz", + "integrity": "sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA==", + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "@types/moxios": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@types/moxios/-/moxios-0.4.9.tgz", + "integrity": "sha512-Sd1b24QRW2N194j2LEDPQAZK1h0TBtpN+2EIH+rERCgm38qm14JZwC7NlpE7n3jULhlCIPZBG8uNcbjF8KcCaQ==", + "requires": { + "axios": "^0.19.0" + } + }, + "@types/node": { + "version": "13.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz", + "integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==" + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==" + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" + } + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", + "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", + "requires": { + "xregexp": "^4.2.4" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==" + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==" + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "requires": { + "bser": "2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fishery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fishery/-/fishery-1.0.0.tgz", + "integrity": "sha512-DLQtxcSPlLQYY6J0tL/dl7DfPhrULHCAO6fFDGnrXqA830J6AW124fHarYOLnfvcSXNBEooBS/g65N/HecQYjQ==", + "dev": true, + "requires": { + "lodash.merge": "^4.6.2" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-25.5.4.tgz", + "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==", + "requires": { + "@jest/core": "^25.5.4", + "import-local": "^3.0.2", + "jest-cli": "^25.5.4" + }, + "dependencies": { + "jest-cli": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz", + "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==", + "requires": { + "@jest/core": "^25.5.4", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^25.5.4", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "prompts": "^2.0.1", + "realpath-native": "^2.0.0", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz", + "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==", + "requires": { + "@jest/types": "^25.5.0", + "execa": "^3.2.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + } + } + }, + "jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + } + }, + "jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" + } + }, + "jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } + }, + "jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "requires": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "requires": { + "@jest/types": "^25.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz", + "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==", + "requires": { + "@jest/types": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-snapshot": "^25.5.1" + } + }, + "jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + } + }, + "jest-watcher": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz", + "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==", + "requires": { + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "jest-util": "^25.5.0", + "string-length": "^3.1.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "requires": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "moxios": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/moxios/-/moxios-0.4.0.tgz", + "integrity": "sha1-/A2ixlR31yXKa5Z51YNw7QxS9Ts=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" + }, + "node-notifier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", + "shellwords": "^0.1.1", + "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, + "oauth-1.0a": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-2.2.6.tgz", + "integrity": "sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "requires": { + "lodash": "^4.17.15" + } + }, + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "requires": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "requires": { + "xmlchars": "^2.1.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "^2.1.0" + } + }, + "ts-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.5.0.tgz", + "integrity": "sha512-govrjbOk1UEzcJ5cX5k8X8IUtFuP3lp3mrF3ZuKtCdAOQzdeCM7qualhb/U8s8SWFwEDutOqfF5PLkJ+oaYD4w==", + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "micromatch": "4.x", + "mkdirp": "0.x", + "semver": "6.x", + "yargs-parser": "18.x" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==" + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "requires": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz", + "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^3.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + } + } + } + } + }, "@wordpress/babel-plugin-import-jsx-pragma": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-1.1.3.tgz", @@ -7352,9 +11754,9 @@ } }, "@wordpress/browserslist-config": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.6.0.tgz", - "integrity": "sha512-vRgzGoxhcNVChBP30XZlyK4w6r/9ZpO+Fi1dzmButp31lUEb1pT5WBxTIQl3HE0JZ9YTEJ00WWGO5sjGi5MHZA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.7.0.tgz", + "integrity": "sha512-pB45JlfmHuEigNFZ1X+CTgIsOT3/TTb9iZxw1DHXge/7ytY8FNhtcNwTfF9IgnS6/xaFRZBqzw4DyH4sP1Lyxg==", "dev": true }, "@wordpress/e2e-test-utils": { @@ -7371,115 +11773,69 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, - "@tannin/compile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@tannin/compile/-/compile-1.1.0.tgz", - "integrity": "sha512-n8m9eNDfoNZoxdvWiTfW/hSPhehzLJ3zW7f8E7oT6mCROoMNWCB4TYtv041+2FMAxweiE0j7i1jubQU4MEC/Gg==", - "dev": true, - "requires": { - "@tannin/evaluate": "^1.2.0", - "@tannin/postfix": "^1.1.0" - } - }, - "@tannin/evaluate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@tannin/evaluate/-/evaluate-1.2.0.tgz", - "integrity": "sha512-3ioXvNowbO/wSrxsDG5DKIMxC81P0QrQTYai8zFNY+umuoHWRPbQ/TuuDEOju9E+jQDXmj6yI5GyejNuh8I+eg==", - "dev": true - }, - "@tannin/plural-forms": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@tannin/plural-forms/-/plural-forms-1.1.0.tgz", - "integrity": "sha512-xl9R2mDZO/qiHam1AgMnAES6IKIg7OBhcXqy6eDsRCdXuxAFPcjrej9HMjyCLE0DJ/8cHf0i5OQTstuBRhpbHw==", - "dev": true, - "requires": { - "@tannin/compile": "^1.1.0" - } - }, - "@tannin/postfix": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.1.0.tgz", - "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==", - "dev": true - }, - "@wordpress/i18n": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.12.0.tgz", - "integrity": "sha512-QkdHd2Z2yTFItBnnzzjMW4IXJlofWMivct4BkgwRivrG7kLxE7nd2xMG3+hFkkdYGdzE67u8vmin0gmQ+14yPA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "gettext-parser": "^1.3.1", - "lodash": "^4.17.15", - "memize": "^1.1.0", - "sprintf-js": "^1.1.1", - "tannin": "^1.2.0" - } - }, - "@wordpress/keycodes": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.12.0.tgz", - "integrity": "sha512-7fUwfquRLmE4CvJahZTHdNn31heoDcyZ4acgEQR4iKYsKjX6dF1coZjUe693xbf/4r8GmsOg0/uYDImMdDm+1Q==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "@wordpress/i18n": "^3.12.0", - "lodash": "^4.17.15" - } - }, - "@wordpress/url": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.14.0.tgz", - "integrity": "sha512-TSp6vDpmBTiYTwhlc5mleT4g3mOsw2w5bu5AcqiX344o48rju+ktuTZBQofNIhl3m04zYtl6YR14M1dsXKTsNQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "lodash": "^4.17.15", - "qs": "^6.5.2", - "react-native-url-polyfill": "^1.1.2" - } - }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, - "memize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", - "integrity": "sha512-K4FcPETOMTwe7KL2LK0orMhpOmWD2wRGwWWpbZy0fyArwsyIKR8YJVz8+efBAh3BO4zPqlSICu4vsLTRRqtFAg==", - "dev": true - }, "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", "dev": true + } + } + }, + "@wordpress/eslint-plugin": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-7.1.0.tgz", + "integrity": "sha512-FTrKkpEa8vZg7/7M6GBhd1YW24hnh5rFGzKgKX4MGyB0Jw8GGSwld9J23eRbQ5JQWGFP/tmOMeiu6W1/arxy7Q==", + "dev": true, + "requires": { + "@wordpress/prettier-config": "^0.3.0", + "babel-eslint": "^10.1.0", + "eslint-config-prettier": "^6.10.1", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-jsdoc": "^26.0.0", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-react": "^7.20.0", + "eslint-plugin-react-hooks": "^4.0.4", + "globals": "^12.0.0", + "prettier": "npm:wp-prettier@2.0.5", + "requireindex": "^1.2.0" + }, + "dependencies": { + "eslint-plugin-react-hooks": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.5.tgz", + "integrity": "sha512-3YLSjoArsE2rUwL8li4Yxx1SUg3DQWp+78N3bcJQGWVZckcp+yeQGsap/MSq05+thJk57o+Ww4PtZukXGL02TQ==", + "dev": true }, - "tannin": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tannin/-/tannin-1.2.0.tgz", - "integrity": "sha512-U7GgX/RcSeUETbV7gYgoz8PD7Ni4y95pgIP/Z6ayI3CfhSujwKEBlGFTCRN+Aqnuyf4AN2yHL+L8x+TCGjb9uA==", + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { - "@tannin/plural-forms": "^1.1.0" + "type-fest": "^0.8.1" } } } }, "@wordpress/i18n": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.13.0.tgz", - "integrity": "sha512-eMlOvg2vYKmGV4C1vPrWuOEyskxMeCGoQJ0N3mQ6t7iWKs4bKWAJGlGL5QXMwN7xJJ863h3L7mrbLM3zKVrF1g==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.14.0.tgz", + "integrity": "sha512-FQbSggdvkdS+IWMNhTl3n1nThqfzAPxORvoFpjDma7DOwuRKOA8iPyomwacfeG/krAeaurj1DIDzDvZh9Ex79w==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -7491,9 +11847,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", - "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -7514,9 +11870,9 @@ } }, "@wordpress/jest-console": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.6.0.tgz", - "integrity": "sha512-0XpvIvgjdmVYYAA0l2XUktq+Z18upDhvaMFDdK8JDxu+vsso0XyFee5VNyHd/PvjInPrTXHoqGj0tx48uUqxhQ==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.7.0.tgz", + "integrity": "sha512-+PLH0jbY7xuKJckrkbtRk7zfyg4YDHFVulqydEBzSiU+LsZ2f/9hdRbb4/JDUneG7NpROO2smqxmaACxu5o9gw==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -7525,9 +11881,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -7810,9 +12166,9 @@ } }, "@types/yargs": { - "version": "13.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", - "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", + "version": "13.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", + "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -7824,12 +12180,6 @@ "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, "babel-jest": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", @@ -7905,12 +12255,6 @@ } } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "cssom": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", @@ -8104,15 +12448,6 @@ "pretty-format": "^24.9.0" } }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, "jest-each": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", @@ -8153,12 +12488,6 @@ "jest-util": "^24.9.0" } }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", - "dev": true - }, "jest-haste-map": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", @@ -8374,20 +12703,6 @@ "source-map": "^0.6.0" } }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" - } - }, "jest-worker": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", @@ -8438,12 +12753,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -8514,12 +12823,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -8535,18 +12838,6 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -8648,20 +12939,20 @@ } }, "@wordpress/keycodes": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.13.0.tgz", - "integrity": "sha512-Bm3N4Qf5qLXds+eflM+JXD15VEW/7IQ7eqWt9/UhsssuDTMTMbXnYjxOAh5zoVi2toAMSMs8EYpV28V+Qv0ZjA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.14.0.tgz", + "integrity": "sha512-R/0orMutajuQ1d1kFFIvksXKR5C5TtszEkbnxSfdNlKaOW7p9Srv8+8m2QqM+AKNvEGMaq6cn7BfDtTbZ33Dbw==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", - "@wordpress/i18n": "^3.13.0", + "@wordpress/i18n": "^3.14.0", "lodash": "^4.17.15" }, "dependencies": { "@babel/runtime": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", - "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -8681,10 +12972,16 @@ } } }, + "@wordpress/prettier-config": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-0.3.0.tgz", + "integrity": "sha512-wL1ztV+so5Ttwz23lDmb8ZmREmND96sf+Dh/kbP2nyAw/DWt3K8uj31qbczVmjwfoetTiRoH9Z1CasgPs4bccg==", + "dev": true + }, "@wordpress/url": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.16.0.tgz", - "integrity": "sha512-xja1pOwIEt7DgqSSyRP1oVAQtayoCcvcCyj4yvq/8qiRpkNlzn0HNWmzKL/qBkAJhPGM4Q6D4ehvOfK4x4/Qtw==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.17.0.tgz", + "integrity": "sha512-4OBUy8IKZlobXe41GASw+p5xP/Nvh+HSzfhTN+BU0OggnIsXvZpf0iBYRYGp6M60ne8MkeEoQg9rMM22Osh9Cg==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -8694,9 +12991,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.10.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", - "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -8834,21 +13131,28 @@ } }, "airbnb-prop-types": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz", - "integrity": "sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz", + "integrity": "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==", "dev": true, "requires": { - "array.prototype.find": "^2.1.0", - "function.prototype.name": "^1.1.1", - "has": "^1.0.3", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", + "array.prototype.find": "^2.1.1", + "function.prototype.name": "^1.1.2", + "is-regex": "^1.1.0", + "object-is": "^1.1.2", "object.assign": "^4.1.0", - "object.entries": "^1.1.0", + "object.entries": "^1.1.2", "prop-types": "^15.7.2", "prop-types-exact": "^1.2.0", - "react-is": "^16.9.0" + "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + } } }, "ajv": { @@ -9079,6 +13383,33 @@ } } }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -9127,6 +13458,17 @@ "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -9168,6 +13510,17 @@ "es-abstract": "^1.17.0-next.1" } }, + "array.prototype.flatmap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", + "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -9245,6 +13598,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -9309,27 +13668,27 @@ }, "dependencies": { "browserslist": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.1.tgz", - "integrity": "sha512-WMjXwFtPskSW1pQUDJRxvRKRkeCr7usN0O/Za76N+F4oadaTdQHotSGcX9jT/Hs7mSKPkyMFNvqawB/1HzYDKQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.2.tgz", + "integrity": "sha512-MfZaeYqR8StRZdstAK9hCKDd2StvePCYp5rHzQCPicUjfFliDgmuaBNPHYUTpAywBN8+Wc/d7NYVFkO0aqaBUw==", "dev": true, "requires": { "caniuse-lite": "^1.0.30001088", - "electron-to-chromium": "^1.3.481", + "electron-to-chromium": "^1.3.483", "escalade": "^3.0.1", "node-releases": "^1.1.58" } }, "caniuse-lite": { - "version": "1.0.30001088", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001088.tgz", - "integrity": "sha512-6eYUrlShRYveyqKG58HcyOfPgh3zb2xqs7NvT2VVtP3hEUeeWvc3lqhpeMTxYWBBeeaT9A4bKsrtjATm66BTHg==", + "version": "1.0.30001093", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001093.tgz", + "integrity": "sha512-0+ODNoOjtWD5eS9aaIpf4K0gQqZfILNY4WSNuYzeT1sXni+lMrrVjc0odEobJt6wrODofDZUX8XYi/5y7+xl8g==", "dev": true }, "electron-to-chromium": { - "version": "1.3.483", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.483.tgz", - "integrity": "sha512-+05RF8S9rk8S0G8eBCqBRBaRq7+UN3lDs2DAvnG8SBSgQO3hjy0+qt4CmRk5eiuGbTcaicgXfPmBi31a+BD3lg==", + "version": "1.3.484", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.484.tgz", + "integrity": "sha512-esh5mmjAGl6HhAaYgHlDZme+jCIc+XIrLrBTwxviE+pM64UBmdLUIHLlrPzJGbit7hQI1TR/oGDQWCvQZ5yrFA==", "dev": true }, "node-releases": { @@ -9369,6 +13728,12 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, + "axe-core": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.5.5.tgz", + "integrity": "sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==", + "dev": true + }, "axios": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", @@ -9378,6 +13743,12 @@ "follow-redirects": "1.5.10" } }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -10767,6 +15138,17 @@ "htmlparser2": "^3.9.1", "lodash": "^4.15.0", "parse5": "^3.0.1" + }, + "dependencies": { + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "dev": true, + "requires": { + "@types/node": "*" + } + } } }, "chokidar": { @@ -10897,12 +15279,6 @@ "safe-buffer": "^5.0.1" } }, - "cjk-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cjk-regex/-/cjk-regex-1.0.2.tgz", - "integrity": "sha512-NwSMtwULPLk8Ka9DEUcoFXhMRnV/bpyKDnoyDiVw/Qy5przhvHTvXLcsKaOmx13o8J4XEsPVT1baoCUj5zQs3w==", - "dev": true - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -11247,6 +15623,12 @@ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true }, + "comment-parser": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.5.tgz", + "integrity": "sha512-iH9YA35ccw94nx5244GVkpyC9eVTsL71jZz6iz5w6RIf79JLF2AsXHXq9p6Oaohyl3sx5qSMnGsWUDFIAfWL4w==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -11254,9 +15636,9 @@ "dev": true }, "compare-func": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", - "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz", + "integrity": "sha512-sq2sWtrqKPkEXAC8tEJA1+BqAH9GbFkGBtUOqrUX57VSfwp8xyktctk+uLoRy5eccTdxzDcVIztlYDpKs3Jv1Q==", "dev": true, "requires": { "array-ify": "^1.0.0", @@ -11348,9 +15730,9 @@ "dev": true }, "conventional-changelog-angular": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.6.tgz", - "integrity": "sha512-QDEmLa+7qdhVIv8sFZfVxU1VSyVvnXPsxq8Vam49mKUcO1Z8VTLEJk9uI21uiJUsnmm0I4Hrsdc9TgkOQo9WSA==", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.10.tgz", + "integrity": "sha512-k7RPPRs0vp8+BtPsM9uDxRl6KcgqtCJmzRD1wRtgqmhQ96g8ifBGo9O/TZBG23jqlXS/rg8BKRDELxfnQQGiaA==", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -11393,6 +15775,12 @@ "locate-path": "^2.0.0" } }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -11498,55 +15886,70 @@ "dev": true }, "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", "dev": true, "requires": { + "inherits": "^2.0.4", "readable-stream": "2 || 3" } } } }, "conventional-changelog-preset-loader": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.0.tgz", - "integrity": "sha512-/rHb32J2EJnEXeK4NpDgMaAVTFZS3o1ExmjKMtYVgIC4MQn0vkNSbYpdGRotkfGGRWiqk3Ri3FBkiZGbAfIfOQ==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", "dev": true }, "conventional-changelog-writer": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.11.tgz", - "integrity": "sha512-g81GQOR392I+57Cw3IyP1f+f42ME6aEkbR+L7v1FBBWolB0xkjKTeCWVguzRrp6UiT1O6gBpJbEy2eq7AnV1rw==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.16.tgz", + "integrity": "sha512-jmU1sDJDZpm/dkuFxBeRXvyNcJQeKhGtVcFFkwTphUAzyYWcwz2j36Wcv+Mv2hU3tpvLMkysOPXJTLO55AUrYQ==", "dev": true, "requires": { "compare-func": "^1.3.1", - "conventional-commits-filter": "^2.0.2", + "conventional-commits-filter": "^2.0.6", "dateformat": "^3.0.0", - "handlebars": "^4.4.0", + "handlebars": "^4.7.6", "json-stringify-safe": "^5.0.1", "lodash": "^4.17.15", - "meow": "^5.0.0", + "meow": "^7.0.0", "semver": "^6.0.0", "split": "^1.0.0", "through2": "^3.0.0" }, "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", "dev": true }, "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } }, "dateformat": { @@ -11556,40 +15959,53 @@ "dev": true }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "handlebars": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" } }, "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -11599,112 +16015,137 @@ "dev": true }, "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", + "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", "dev": true, "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" + "@types/minimist": "^1.2.0", + "arrify": "^2.0.1", + "camelcase": "^6.0.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { - "p-try": "^1.0.0" + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" } }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } } }, "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } } }, "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, "semver": { @@ -11713,48 +16154,61 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { + "min-indent": "^1.0.0" + } + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", "readable-stream": "2 || 3" } }, "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "dev": true + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } } } }, "conventional-commits-filter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz", - "integrity": "sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.6.tgz", + "integrity": "sha512-4g+sw8+KA50/Qwzfr0hL5k5NWxqtrOVw4DDk3/h6L85a9Gz0/Eqp3oP+CWCNfesBvZZZEFHF7OTEbRe+yYSyKw==", "dev": true, "requires": { "lodash.ismatch": "^4.4.0", @@ -11762,72 +16216,86 @@ } }, "conventional-commits-parser": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.8.tgz", - "integrity": "sha512-YcBSGkZbYp7d+Cr3NWUeXbPDFUN6g3SaSIzOybi8bjHL5IJ5225OSCxJJ4LgziyEJ7AaJtE9L2/EU6H7Nt/DDQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", + "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", "dev": true, "requires": { "JSONStream": "^1.0.4", "is-text-path": "^1.0.1", "lodash": "^4.17.15", - "meow": "^5.0.0", + "meow": "^7.0.0", "split2": "^2.0.0", "through2": "^3.0.0", "trim-off-newlines": "^1.0.0" }, "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", "dev": true }, "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -11837,148 +16305,180 @@ "dev": true }, "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", + "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", "dev": true, "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" + "@types/minimist": "^1.2.0", + "arrify": "^2.0.1", + "camelcase": "^6.0.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { - "p-try": "^1.0.0" + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" } }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } } }, "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } } }, "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { + "min-indent": "^1.0.0" + } + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", "readable-stream": "2 || 3" } }, "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "dev": true + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } } } @@ -12264,6 +16764,12 @@ } } }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -12503,6 +17009,12 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "dev": true + }, "dargs": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", @@ -12521,12 +17033,6 @@ "assert-plus": "^1.0.0" } }, - "dashify": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz", - "integrity": "sha1-agdBWgHJH69KMuONnfunH2HLIP4=", - "dev": true - }, "data-urls": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", @@ -12972,42 +17478,6 @@ "safer-buffer": "^2.1.0" } }, - "editorconfig": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.14.2.tgz", - "integrity": "sha512-tghjvKwo1gakrhFiZWlbo5ILWAfnuOu1JFztW0li+vzbnInN0CMZuF4F0T/Pnn9UWpT7Mr1aFTWdHVuxiR9K9A==", - "dev": true, - "requires": { - "bluebird": "^3.0.5", - "commander": "^2.9.0", - "lru-cache": "^3.2.0", - "semver": "^5.1.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "lru-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", - "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", - "dev": true, - "requires": { - "pseudomap": "^1.0.1" - } - } - } - }, - "editorconfig-to-prettier": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.0.6.tgz", - "integrity": "sha512-Ysw+hBdwhPFruYmLapKRm7Or5XgMzhasbqu4AN07V2l/AkqpgooWm2xtTQPzTD6S0tq54A+WbSxNt6qmsO3hoA==", - "dev": true - }, "electron-to-chromium": { "version": "1.3.392", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.392.tgz", @@ -13186,9 +17656,9 @@ } }, "enzyme-to-json": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.4.4.tgz", - "integrity": "sha512-50LELP/SCPJJGic5rAARvU7pgE3m1YaNj7JLM+Qkhl5t7PAs6fiyc8xzc50RnkKPFQCv0EeFVjEWdIFRGPWMsA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.5.0.tgz", + "integrity": "sha512-clusXRsiaQhG7+wtyc4t7MU8N3zCOgf4eY9+CeSenYzKlFST4lxerfOvnWd4SNaToKhkuba+w6m242YpQOS7eA==", "dev": true, "requires": { "lodash": "^4.17.15", @@ -13238,22 +17708,22 @@ } }, "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" }, "dependencies": { "has-symbols": { @@ -13427,6 +17897,23 @@ } } }, + "eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, "eslint-config-wpcalypso": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-config-wpcalypso/-/eslint-config-wpcalypso-5.0.0.tgz", @@ -13445,6 +17932,150 @@ "@typescript-eslint/experimental-utils": "^2.5.0" } }, + "eslint-plugin-jsdoc": { + "version": "26.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-26.0.2.tgz", + "integrity": "sha512-KtZjqtM3Z8x84vQBFKGUyBbZRGXYHVWSJ2XyYSUTc8KhfFrvzQ/GXPp6f1M1/YCNzP3ImD5RuDNcr+OVvIZcBA==", + "dev": true, + "requires": { + "comment-parser": "^0.7.4", + "debug": "^4.1.1", + "jsdoctypeparser": "^6.1.0", + "lodash": "^4.17.15", + "regextras": "^0.7.1", + "semver": "^6.3.0", + "spdx-expression-parse": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.3.1.tgz", + "integrity": "sha512-i1S+P+c3HOlBJzMFORRbC58tHa65Kbo8b52/TwCwSKLohwvpfT5rm2GjGWzOHTEuq4xxf2aRlHHTtmExDQOP+g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^3.5.4", + "axobject-query": "^2.1.2", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1", + "language-tags": "^1.0.5" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "emoji-regex": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.0.0.tgz", + "integrity": "sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-react": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz", + "integrity": "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1", + "object.entries": "^1.1.2", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.17.0", + "string.prototype.matchall": "^4.0.2" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, "eslint-plugin-react-hooks": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.3.0.tgz", @@ -13817,6 +18448,12 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", @@ -13851,15 +18488,6 @@ "reusify": "^1.0.0" } }, - "fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "dev": true, - "requires": { - "format": "^0.2.0" - } - }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -14123,18 +18751,6 @@ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", - "dev": true - }, - "flow-parser": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.59.0.tgz", - "integrity": "sha1-9uvK5h/6GH5CCZnUDOCoAfObJjU=", - "dev": true - }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -14197,12 +18813,6 @@ "mime-types": "^2.1.12" } }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "dev": true - }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -14281,628 +18891,14 @@ "dev": true }, "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "optional": true, "requires": { "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": false, - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": false, - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": false, - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "resolved": false, - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": false, - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": false, - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "resolved": false, - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": false, - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": false, - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": false, - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "resolved": false, - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": false, - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": false, - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "resolved": false, - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": false, - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": false, - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "resolved": false, - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": false, - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "resolved": false, - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": false, - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": false, - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "resolved": false, - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "optional": true - }, - "needle": { - "version": "2.4.0", - "resolved": false, - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "resolved": false, - "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": false, - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.7", - "resolved": false, - "integrity": "sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": false, - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": false, - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": false, - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "resolved": false, - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "resolved": false, - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": false, - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": false, - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": false, - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "resolved": false, - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "resolved": false, - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": false, - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": false, - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": false, - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "resolved": false, - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": false, - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "resolved": false, - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "optional": true - } + "nan": "^2.12.1" } }, "fstream": { @@ -15640,22 +19636,191 @@ "dev": true }, "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", "dev": true, "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" }, "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true } } @@ -15700,15 +19865,6 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, - "graphql": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz", - "integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==", - "dev": true, - "requires": { - "iterall": "^1.1.0" - } - }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -16333,6 +20489,12 @@ "har-schema": "^2.0.0" } }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -16973,6 +21135,17 @@ } } }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + } + }, "interpret": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", @@ -17065,9 +21238,9 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-ci": { @@ -17242,12 +21415,20 @@ "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } } }, "is-regexp": { @@ -17514,12 +21695,6 @@ "handlebars": "^4.0.3" } }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", - "dev": true - }, "jest": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz", @@ -18150,9 +22325,9 @@ } }, "jest-docblock": { - "version": "21.3.0-beta.11", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.3.0-beta.11.tgz", - "integrity": "sha512-sxSwZUm7JyCO8dverup5g/OKJhjYRrBdgEdezIO1qAmMGWuza7ewovpfDmxp+JLvlm0i2WRFKUQNNIMGmPGTVg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", "dev": true, "requires": { "detect-newline": "^2.1.0" @@ -18339,9 +22514,9 @@ } }, "jest-get-type": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", - "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", "dev": true }, "jest-haste-map": { @@ -19329,15 +23504,45 @@ } }, "jest-validate": { - "version": "21.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.1.0.tgz", - "integrity": "sha512-xS0cyErNWpsLFlGkn/b87pk/Mv7J+mCTs8hQ4KmtOIIoM1sHYobXII8AtkoN8FC7E3+Ptxjo+/3xWk6LK1dKcw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", "dev": true, "requires": { + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", "chalk": "^2.0.1", - "jest-get-type": "^21.0.2", - "leven": "^2.1.0", - "pretty-format": "^21.1.0" + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "pretty-format": "^24.9.0" + }, + "dependencies": { + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@types/yargs": { + "version": "13.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", + "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } }, "jest-watcher": { @@ -19470,6 +23675,12 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "jsdoctypeparser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", + "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", + "dev": true + }, "jsdom": { "version": "15.2.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", @@ -19609,6 +23820,16 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", + "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "object.assign": "^4.1.0" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -19630,6 +23851,21 @@ "integrity": "sha512-Vi3nxDGMm/z+lAaCjvAR1u+7fiv+sG6gU/iYDj5QOF8h76ytK9EW/EKfF0NeTyiGBi8Jy6Hklty/vxISrLox3w==", "dev": true }, + "language-subtag-registry": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz", + "integrity": "sha512-KPMwROklF4tEx283Xw0pNKtfTj1gZ4UByp4EsIFWLgBavJltF4TiYPc39k06zSTsLzxTVXXDSpbwaQXaFB4Qeg==", + "dev": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -19723,9 +23959,9 @@ } }, "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, "levenary": { @@ -20241,12 +24477,6 @@ "lodash._reinterpolate": "^3.0.0" } }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", - "dev": true - }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -20348,9 +24578,9 @@ } }, "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.0.tgz", + "integrity": "sha512-ko6deozZYiAkqa/0gmcsz+p4jSy3gY7/ZsCEokPaYd8k+6/aXGkiTgr61+Owup7Sf+xjqW8u2ElhoM9SEcEfuA==", "dev": true }, "make-dir": { @@ -20577,15 +24807,6 @@ "unist-util-visit": "^1.1.0" } }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "memize": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", @@ -20704,6 +24925,12 @@ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -20875,12 +25102,6 @@ "yargs-unparser": "1.6.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, "anymatch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", @@ -20892,9 +25113,9 @@ } }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, "camelcase": { @@ -20919,17 +25140,6 @@ "readdirp": "~3.2.0" } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -21000,26 +25210,6 @@ "picomatch": "^2.0.4" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, "supports-color": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", @@ -21029,35 +25219,6 @@ "has-flag": "^3.0.0" } }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", @@ -21189,9 +25350,9 @@ "dev": true }, "nearley": { - "version": "2.19.3", - "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.3.tgz", - "integrity": "sha512-FpAy1PmTsUpOtgxr23g4jRNvJHYzZEW2PixXeSzksLR/ykPfwKhAodc2+9wQhY+JneWLcvkDw6q7FJIsIdF/aQ==", + "version": "2.19.4", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.4.tgz", + "integrity": "sha512-oqj3m4oqwKsN77pETa9IPvxHHHLW68KrDc2KYoWMUOhDlrNUo7finubwffQMBRnwNCOXc4kRxCZO0Rvx4L6Zrw==", "dev": true, "requires": { "commander": "^2.19.0", @@ -21222,9 +25383,9 @@ "dev": true }, "node-addon-api": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", - "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", "dev": true }, "node-environment-flags": { @@ -21537,9 +25698,9 @@ } }, "node-gyp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.0.tgz", - "integrity": "sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz", + "integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==", "dev": true, "requires": { "env-paths": "^2.2.0", @@ -21738,33 +25899,6 @@ "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - } } }, "object-keys": { @@ -21803,15 +25937,41 @@ } }, "object.entries": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", - "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", + "es-abstract": "^1.17.5", "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } } }, "object.fromentries": { @@ -22070,10 +26230,13 @@ "dev": true }, "p-queue": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz", - "integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-4.0.0.tgz", + "integrity": "sha512-3cRXXn3/O0o3+eVmUroJPSj/esxoEFIm0ZOno/T+NzG/VZgPOqQ8WKmlNqubSEpZmCIngEy34unkHGg83ZIBmg==", + "dev": true, + "requires": { + "eventemitter3": "^3.1.0" + } }, "p-reduce": { "version": "1.0.0", @@ -22089,6 +26252,14 @@ "requires": { "@types/retry": "^0.12.0", "retry": "^0.12.0" + }, + "dependencies": { + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + } } }, "p-try": { @@ -22204,13 +26375,10 @@ } }, "parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", - "dev": true, - "requires": { - "@types/node": "*" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true }, "pascalcase": { "version": "0.1.1", @@ -22263,21 +26431,6 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", @@ -22558,92 +26711,6 @@ "@babel/core": ">=7.2.2" } }, - "postcss-less": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-1.1.3.tgz", - "integrity": "sha512-WS0wsQxRm+kmN8wEYAGZ3t4lnoNfoyx9EJZrhiPR1K0lMHR0UNWnz52Ya5QRXChHtY75Ef+kDc05FpnBujebgw==", - "dev": true, - "requires": { - "postcss": "^5.2.16" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, "postcss-markdown": { "version": "0.36.0", "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", @@ -22708,48 +26775,6 @@ "postcss": "^7.0.21" } }, - "postcss-scss": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.2.tgz", - "integrity": "sha1-/0XPM1S4ee6JpOtoaA9GrJuxT5Q=", - "dev": true, - "requires": { - "postcss": "^6.0.3" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", - "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", - "dev": true, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "postcss-syntax": { "version": "0.36.2", "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", @@ -22762,17 +26787,6 @@ "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==", "dev": true }, - "postcss-values-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-1.3.1.tgz", - "integrity": "sha512-chFn9CnFAAUpQ3cwrxvVjKB8c0y6BfONv6eapndJoTXJ3h8fr1uAiue8lGP3rUIpBI2KgJGdgCVk9KNvXh0n6A==", - "dev": true, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -22780,163 +26794,18 @@ "dev": true }, "prettier": { - "version": "github:automattic/calypso-prettier#c56b42511ec98ba6d8f72b6c391e0a626e90f531", - "from": "github:automattic/calypso-prettier#c56b4251", + "version": "npm:wp-prettier@2.0.5", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.0.5.tgz", + "integrity": "sha512-5GCgdeevIXwR3cW4Qj5XWC5MO1iSCz8+IPn0mMw6awAt/PBiey8yyO7MhePRsaMqghJAhg6Q3QLYWSnUHWkG6A==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { - "babel-code-frame": "7.0.0-beta.3", - "babylon": "7.0.0-beta.34", - "camelcase": "4.1.0", - "chalk": "2.1.0", - "cjk-regex": "1.0.2", - "cosmiconfig": "3.1.0", - "dashify": "0.2.2", - "diff": "3.2.0", - "editorconfig": "0.14.2", - "editorconfig-to-prettier": "0.0.6", - "emoji-regex": "6.5.1", - "escape-string-regexp": "1.0.5", - "esutils": "2.0.2", - "flow-parser": "0.59.0", - "get-stream": "3.0.0", - "globby": "6.1.0", - "graphql": "0.10.5", - "ignore": "3.3.7", - "jest-docblock": "21.3.0-beta.11", - "jest-validate": "21.1.0", - "leven": "2.1.0", - "mem": "1.1.0", - "minimatch": "3.0.4", - "minimist": "1.2.0", - "parse5": "3.0.3", - "path-root": "0.1.1", - "postcss-less": "1.1.3", - "postcss-media-query-parser": "0.2.3", - "postcss-scss": "1.0.2", - "postcss-selector-parser": "2.2.3", - "postcss-values-parser": "1.3.1", - "remark-frontmatter": "1.1.0", - "remark-parse": "4.0.0", - "semver": "5.4.1", - "string-width": "2.1.1", - "typescript": "2.6.2", - "typescript-eslint-parser": "9.0.1", - "unicode-regex": "1.0.1", - "unified": "6.1.6" - }, - "dependencies": { - "babel-code-frame": { - "version": "7.0.0-beta.3", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-7.0.0-beta.3.tgz", - "integrity": "sha512-flMsJ9eSpShupt2Gwpka84DoMePvE4HlDObzdEc+1iNkacv3+NHlsJ7dMKmbnVA/AT22UhcGEBHwbJLoXWBO6Q==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^3.0.0" - } - }, - "babylon": { - "version": "7.0.0-beta.34", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.34.tgz", - "integrity": "sha512-ribEzWEhWKKjY+1FdKCryo+HiN/1idPjUB8vyR5Yf221MtGzCd5+7OwPvWvYHerHHC2eJLr6MhvumbTocXGY7Q==", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "cosmiconfig": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-3.1.0.tgz", - "integrity": "sha512-zedsBhLSbPBms+kE7AH4vHg6JsKDz6epSv2/+5XHs8ILHlgDciSJfSWf8sX9aQ52Jb7KI7VswUTsLpR/G0cr2Q==", - "dev": true, - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^3.0.0", - "require-from-string": "^2.0.1" - } - }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "emoji-regex": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", - "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "parse-json": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-3.0.0.tgz", - "integrity": "sha1-+m9HsY4jgm6tMvJj50TQ4ehH+xM=", - "dev": true, - "requires": { - "error-ex": "^1.3.1" - } - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } + "fast-diff": "^1.1.2" } }, "pretty-bytes": { @@ -22949,13 +26818,43 @@ } }, "pretty-format": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", - "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "dependencies": { + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@types/yargs": { + "version": "13.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", + "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } } }, "private": { @@ -22996,14 +26895,6 @@ "requires": { "err-code": "^1.0.0", "retry": "^0.10.0" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "dev": true - } } }, "prompts": { @@ -23472,12 +27363,6 @@ } } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "cssom": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", @@ -23779,15 +27664,6 @@ "pretty-format": "^24.9.0" } }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, "jest-each": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", @@ -23828,12 +27704,6 @@ "jest-util": "^24.9.0" } }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", - "dev": true - }, "jest-haste-map": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", @@ -24060,20 +27930,6 @@ "source-map": "^0.6.0" } }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" - } - }, "jest-watcher": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", @@ -24139,12 +27995,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -24230,12 +28080,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -24266,18 +28110,6 @@ "integrity": "sha512-mqAC2r1NDmRjG+z3KCJ/i61tycKlmADIjxnDhQab+KBxSAGbF/W7/zwB2guy/ypIeKrrftNsIYkNZZQKf3vJcg==", "dev": true }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -24850,6 +28682,16 @@ "safe-regex": "^1.1.0" } }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -24870,6 +28712,12 @@ "unicode-match-property-value-ecmascript": "^1.2.0" } }, + "regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", + "dev": true + }, "regjsgen": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", @@ -24963,39 +28811,6 @@ } } }, - "remark-frontmatter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.1.0.tgz", - "integrity": "sha512-mLbYtwP9w1L9TA8dX+I/HyDF5lCpa0dmYvvW9Io+zUPpqEZ49QMKWb0hSpunpLVA+Squy0SowzSzjHVPbxWq1g==", - "dev": true, - "requires": { - "fault": "^1.0.1", - "xtend": "^4.0.1" - } - }, - "remark-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", - "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, "remark-stringify": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", @@ -25121,18 +28936,18 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "resolve": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", @@ -25228,9 +29043,9 @@ "dev": true }, "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", "dev": true }, "reusify": { @@ -25829,11 +29644,15 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" + } }, "signal-exit": { "version": "3.0.2", @@ -26333,6 +30152,28 @@ } } }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } + } + }, "string.prototype.trim": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz", @@ -26344,6 +30185,16 @@ "function-bind": "^1.1.1" } }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "string.prototype.trimleft": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", @@ -26364,6 +30215,16 @@ "function-bind": "^1.1.1" } }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -27470,9 +31331,9 @@ "dev": true }, "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, "requires": { "any-promise": "^1.0.0" @@ -27769,29 +31630,11 @@ } }, "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", "dev": true }, - "typescript-eslint-parser": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-9.0.1.tgz", - "integrity": "sha512-w1jqotvnhLtLukD9H3gQPAlbD0kLf7ZkoQGwiwSIshKIlzRL7i0OY9Y7VIdE1xtytZXThg678eomxMZ1rZXGVQ==", - "dev": true, - "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - } - } - }, "uglify-js": { "version": "3.5.11", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.11.tgz", @@ -27870,27 +31713,6 @@ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", "dev": true }, - "unicode-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-1.0.1.tgz", - "integrity": "sha1-+BngUBkdW5VhozmljdO5CV7ZSzU=", - "dev": true - }, - "unified": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.1.6.tgz", - "integrity": "sha512-pW2f82bCIo2ifuIGYcV12fL96kMMYgw7JKVEgh7ODlrM9rj6vXSY3BV+H6lCcv1ksxynFf582hwWLnA1qRFy4w==", - "dev": true, - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-function": "^1.0.4", - "x-is-string": "^0.1.0" - } - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -28261,18 +32083,6 @@ "extsprintf": "^1.2.0" } }, - "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", - "dev": true, - "requires": { - "is-buffer": "^1.1.4", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - }, "vfile-location": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.4.tgz", @@ -28939,9 +32749,9 @@ } }, "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "dev": true }, "whatwg-encoding": { @@ -29018,9 +32828,9 @@ } }, "windows-release": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz", - "integrity": "sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.1.tgz", + "integrity": "sha512-Pngk/RDCaI/DkuHPlGTdIkDiTAnAkyMjoQMZqRsxydNl1qGXNIoZrB7RK8g53F2tEgQBMqQJHQdYZuQEEAu54A==", "dev": true, "requires": { "execa": "^1.0.0" @@ -29197,12 +33007,6 @@ "async-limiter": "~1.0.0" } }, - "x-is-function": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz", - "integrity": "sha1-XSlNw9Joy90GJYDgxd93o5HR+h4=", - "dev": true - }, "x-is-string": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", @@ -29249,9 +33053,9 @@ } }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -29263,7 +33067,7 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" }, "dependencies": { "ansi-regex": { @@ -29272,6 +33076,12 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -29322,6 +33132,16 @@ "string-width": "^3.0.0", "strip-ansi": "^5.0.0" } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, From e4d90f10c3643dc56d003384b407979ad17c21d4 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 2 Jul 2020 15:28:19 -0700 Subject: [PATCH 294/440] Corrected the tabs in the README.me --- tests/e2e/factories/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/e2e/factories/README.md b/tests/e2e/factories/README.md index ae23c24129f..664feb91a9d 100644 --- a/tests/e2e/factories/README.md +++ b/tests/e2e/factories/README.md @@ -14,11 +14,11 @@ Consumers of this package should rely on an instance of `ModelRegistry` to acces Here is an example of how to initialize and use the package to generate a simple product: ```javascript -import { - AdapterTypes, - initializeUsingBasicAuth, - ModelRegistry, - registerSimpleProduct, +import { + AdapterTypes, + initializeUsingBasicAuth, + ModelRegistry, + registerSimpleProduct, SimpleProduct } from '@woocommerce/model-factories'; From 16c5ac401a9c27fe424c66ec87c798e1809bdfda Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Mon, 13 Jul 2020 10:05:17 -0700 Subject: [PATCH 295/440] Adjusted the publish configuration to respect the @woocommerce scope --- tests/e2e/factories/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e/factories/package.json b/tests/e2e/factories/package.json index e0a827e1979..924c48d8442 100644 --- a/tests/e2e/factories/package.json +++ b/tests/e2e/factories/package.json @@ -48,5 +48,8 @@ "moxios": "0.4.0", "ts-jest": "25.5.0", "typescript": "3.8.3" + }, + "publishConfig": { + "access": "public" } } From 9a5d920bdbbc99764e96138a7561388751073381 Mon Sep 17 00:00:00 2001 From: Damir Ha Date: Thu, 16 Jul 2020 13:52:01 +0200 Subject: [PATCH 296/440] Add postcode validation for Bosnia and Herzegovina --- includes/class-wc-validation.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/class-wc-validation.php b/includes/class-wc-validation.php index d6144e54bfa..5b0248e2e5d 100644 --- a/includes/class-wc-validation.php +++ b/includes/class-wc-validation.php @@ -53,6 +53,9 @@ class WC_Validation { case 'AT': $valid = (bool) preg_match( '/^([0-9]{4})$/', $postcode ); break; + case 'BA': + $valid = (bool) preg_match( '/^([7-8]{1})([0-9]{4})$/', $postcode ); + break; case 'BR': $valid = (bool) preg_match( '/^([0-9]{5})([-])?([0-9]{3})$/', $postcode ); break; From 161eb4a320eb40517c0235d15bb9b4899fd0634e Mon Sep 17 00:00:00 2001 From: Damir Ha Date: Thu, 16 Jul 2020 13:57:44 +0200 Subject: [PATCH 297/440] Add test postcode validation for Bosnia and Herzegovina --- tests/legacy/unit-tests/util/validation.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/legacy/unit-tests/util/validation.php b/tests/legacy/unit-tests/util/validation.php index c4179d7910f..1c08b029582 100644 --- a/tests/legacy/unit-tests/util/validation.php +++ b/tests/legacy/unit-tests/util/validation.php @@ -115,7 +115,15 @@ class WC_Tests_Validation extends WC_Unit_Test_Case { array( false, WC_Validation::is_postcode( '0123', 'SI' ) ), ); - return array_merge( $it, $gb, $us, $ch, $br, $ca, $nl, $si ); + $ba = array( + array( true, WC_Validation::is_postcode( '71000', 'BA' ) ), + array( true, WC_Validation::is_postcode( '78256', 'BA' ) ), + array( true, WC_Validation::is_postcode( '89240', 'BA' ) ), + array( false, WC_Validation::is_postcode( '61000', 'BA' ) ), + array( false, WC_Validation::is_postcode( '7850', 'BA' ) ), + ); + + return array_merge( $it, $gb, $us, $ch, $br, $ca, $nl, $si, $ba ); } /** From 5ee0eccb7bd42e2ef84c1b659ce3ee872eea6fd6 Mon Sep 17 00:00:00 2001 From: Ron Rennick Date: Thu, 16 Jul 2020 17:13:08 -0300 Subject: [PATCH 298/440] add/update correct deprecated notices on existing deprecations --- includes/admin/class-wc-admin-post-types.php | 3 ++- .../class-wc-admin-list-table-products.php | 3 ++- .../meta-boxes/views/html-variation-admin.php | 2 +- includes/admin/views/html-admin-settings.php | 2 +- includes/class-wc-checkout.php | 10 +++++----- includes/class-wc-download-handler.php | 6 ++++-- includes/class-wc-order-item-coupon.php | 6 ++++-- includes/class-wc-order-item-fee.php | 6 ++++-- includes/class-wc-order-item-meta.php | 2 ++ includes/class-wc-order-item-product.php | 6 ++++-- includes/class-wc-order-item-shipping.php | 6 ++++-- includes/class-wc-order-item-tax.php | 6 ++++-- includes/class-woocommerce.php | 2 +- includes/legacy/abstract-wc-legacy-order.php | 5 +++-- includes/legacy/class-wc-legacy-api.php | 7 ++++--- includes/legacy/class-wc-legacy-cart.php | 15 ++++++++------- .../class-wc-shipping-legacy-flat-rate.php | 2 +- includes/wc-deprecated-functions.php | 5 ++--- 18 files changed, 56 insertions(+), 38 deletions(-) diff --git a/includes/admin/class-wc-admin-post-types.php b/includes/admin/class-wc-admin-post-types.php index 94d96bbcaf6..00e891c1c2c 100644 --- a/includes/admin/class-wc-admin-post-types.php +++ b/includes/admin/class-wc-admin-post-types.php @@ -892,9 +892,10 @@ class WC_Admin_Post_Types { * @param int $product_id product identifier. * @param int $variation_id optional product variation identifier. * @param array $downloadable_files newly set files. - * @deprecated and moved to post-data class. + * @deprecated 3.3.0 and moved to post-data class. */ public function process_product_file_download_paths( $product_id, $variation_id, $downloadable_files ) { + wc_deprecated_function( 'WC_Admin_Post_Types::process_product_file_download_paths', '3.3', 'WC_Post_Data::process_product_file_download_paths' ); WC_Post_Data::process_product_file_download_paths( $product_id, $variation_id, $downloadable_files ); } diff --git a/includes/admin/list-tables/class-wc-admin-list-table-products.php b/includes/admin/list-tables/class-wc-admin-list-table-products.php index 8ac403273d5..6bc4ba30eed 100644 --- a/includes/admin/list-tables/class-wc-admin-list-table-products.php +++ b/includes/admin/list-tables/class-wc-admin-list-table-products.php @@ -395,11 +395,12 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table { /** * Search by SKU or ID for products. * - * @deprecated Logic moved to query_filters. + * @deprecated 4.4.0 Logic moved to query_filters. * @param string $where Where clause SQL. * @return string */ public function sku_search( $where ) { + wc_deprecated_function( 'WC_Admin_List_Table_Products::sku_search', '4.4.0', 'Logic moved to query_filters.' ); return $where; } diff --git a/includes/admin/meta-boxes/views/html-variation-admin.php b/includes/admin/meta-boxes/views/html-variation-admin.php index 697d88a265a..bece300402c 100644 --- a/includes/admin/meta-boxes/views/html-variation-admin.php +++ b/includes/admin/meta-boxes/views/html-variation-admin.php @@ -6,7 +6,7 @@ * @var int $variation_id * @var WP_POST $variation * @var WC_Product_Variation $variation_object - * @var array $variation_data array of variation data @deprecated. + * @var array $variation_data array of variation data @deprecated 4.4.0. */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/views/html-admin-settings.php b/includes/admin/views/html-admin-settings.php index 99d589e32d6..823726b1444 100644 --- a/includes/admin/views/html-admin-settings.php +++ b/includes/admin/views/html-admin-settings.php @@ -38,7 +38,7 @@ if ( ! $tab_exists ) { self::show_messages(); do_action( 'woocommerce_settings_' . $current_tab ); - do_action( 'woocommerce_settings_tabs_' . $current_tab ); // @deprecated hook. @todo remove in 4.0. + do_action( 'woocommerce_settings_tabs_' . $current_tab ); // @deprecated 3.4.0 hook. @todo remove in 4.6.0. ?>

diff --git a/includes/class-wc-checkout.php b/includes/class-wc-checkout.php index 6645d1f06cf..955efb49726 100644 --- a/includes/class-wc-checkout.php +++ b/includes/class-wc-checkout.php @@ -454,8 +454,8 @@ class WC_Checkout { */ $item = apply_filters( 'woocommerce_checkout_create_order_line_item_object', new WC_Order_Item_Product(), $cart_item_key, $values, $order ); $product = $values['data']; - $item->legacy_values = $values; // @deprecated For legacy actions. - $item->legacy_cart_item_key = $cart_item_key; // @deprecated For legacy actions. + $item->legacy_values = $values; // @deprecated 4.4.0 For legacy actions. + $item->legacy_cart_item_key = $cart_item_key; // @deprecated 4.4.0 For legacy actions. $item->set_props( array( 'quantity' => $values['quantity'], @@ -502,8 +502,8 @@ class WC_Checkout { public function create_order_fee_lines( &$order, $cart ) { foreach ( $cart->get_fees() as $fee_key => $fee ) { $item = new WC_Order_Item_Fee(); - $item->legacy_fee = $fee; // @deprecated For legacy actions. - $item->legacy_fee_key = $fee_key; // @deprecated For legacy actions. + $item->legacy_fee = $fee; // @deprecated 4.4.0 For legacy actions. + $item->legacy_fee_key = $fee_key; // @deprecated 4.4.0 For legacy actions. $item->set_props( array( 'name' => $fee->name, @@ -541,7 +541,7 @@ class WC_Checkout { if ( isset( $chosen_shipping_methods[ $package_key ], $package['rates'][ $chosen_shipping_methods[ $package_key ] ] ) ) { $shipping_rate = $package['rates'][ $chosen_shipping_methods[ $package_key ] ]; $item = new WC_Order_Item_Shipping(); - $item->legacy_package_key = $package_key; // @deprecated For legacy actions. + $item->legacy_package_key = $package_key; // @deprecated 4.4.0 For legacy actions. $item->set_props( array( 'method_title' => $shipping_rate->label, diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index b956d945424..f3d5eb345b3 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -191,10 +191,12 @@ class WC_Download_Handler { /** * Count download. * - * @deprecated unknown + * @deprecated 4.4.0 * @param array $download_data Download data. */ - public static function count_download( $download_data ) {} + public static function count_download( $download_data ) { + wc_deprecated_function( 'WC_Download_Handler::count_download', '4.4.0', '' ); + } /** * Download a file - hook into init function. diff --git a/includes/class-wc-order-item-coupon.php b/includes/class-wc-order-item-coupon.php index ef075e92db2..5aada6cb307 100644 --- a/includes/class-wc-order-item-coupon.php +++ b/includes/class-wc-order-item-coupon.php @@ -136,11 +136,12 @@ class WC_Order_Item_Coupon extends WC_Order_Item { /** * OffsetGet for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Offset. * @return mixed */ public function offsetGet( $offset ) { + wc_deprecated_function( 'WC_Order_Item_Coupon::offsetGet', '4.4.0', '' ); if ( 'discount_amount' === $offset ) { $offset = 'discount'; } elseif ( 'discount_amount_tax' === $offset ) { @@ -152,11 +153,12 @@ class WC_Order_Item_Coupon extends WC_Order_Item { /** * OffsetSet for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Offset. * @param mixed $value Value. */ public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Coupon::offsetSet', '4.4.0', '' ); if ( 'discount_amount' === $offset ) { $offset = 'discount'; } elseif ( 'discount_amount_tax' === $offset ) { diff --git a/includes/class-wc-order-item-fee.php b/includes/class-wc-order-item-fee.php index e0703c9430d..b9b6a3cfec8 100644 --- a/includes/class-wc-order-item-fee.php +++ b/includes/class-wc-order-item-fee.php @@ -290,11 +290,12 @@ class WC_Order_Item_Fee extends WC_Order_Item { /** * OffsetGet for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Offset. * @return mixed */ public function offsetGet( $offset ) { + wc_deprecated_function( 'WC_Order_Item_Fee::offsetGet', '4.4.0', '' ); if ( 'line_total' === $offset ) { $offset = 'total'; } elseif ( 'line_tax' === $offset ) { @@ -308,11 +309,12 @@ class WC_Order_Item_Fee extends WC_Order_Item { /** * OffsetSet for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Offset. * @param mixed $value Value. */ public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Fee::offsetSet', '4.4.0', '' ); if ( 'line_total' === $offset ) { $offset = 'total'; } elseif ( 'line_tax' === $offset ) { diff --git a/includes/class-wc-order-item-meta.php b/includes/class-wc-order-item-meta.php index 2d2f72f03f9..a00fb5d9e6d 100644 --- a/includes/class-wc-order-item-meta.php +++ b/includes/class-wc-order-item-meta.php @@ -163,11 +163,13 @@ class WC_Order_Item_Meta { * Return an array of formatted item meta in format e.g. * Handles @deprecated args. * + * @deprecated 4.4.0 * @param string $hideprefix Hide prefix. * * @return array */ public function get_formatted_legacy( $hideprefix = '_' ) { + wc_deprecated_function( 'WC_Order_Item_Product::get_formatted_legacy', '4.4.0', '' ); if ( ! is_ajax() ) { wc_deprecated_argument( 'WC_Order_Item_Meta::get_formatted', '2.4', 'Item Meta Data is being called with legacy arguments' ); } diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php index 718fe3344b7..3140892c7e2 100644 --- a/includes/class-wc-order-item-product.php +++ b/includes/class-wc-order-item-product.php @@ -425,11 +425,12 @@ class WC_Order_Item_Product extends WC_Order_Item { /** * OffsetGet for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Offset. * @return mixed */ public function offsetGet( $offset ) { + wc_deprecated_function( 'WC_Order_Item_Shipping::offsetGet', '4.4.0', '' ); if ( 'line_subtotal' === $offset ) { $offset = 'subtotal'; } elseif ( 'line_subtotal_tax' === $offset ) { @@ -449,11 +450,12 @@ class WC_Order_Item_Product extends WC_Order_Item { /** * OffsetSet for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Offset. * @param mixed $value Value. */ public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Shipping::offsetSet', '4.4.0', '' ); if ( 'line_subtotal' === $offset ) { $offset = 'subtotal'; } elseif ( 'line_subtotal_tax' === $offset ) { diff --git a/includes/class-wc-order-item-shipping.php b/includes/class-wc-order-item-shipping.php index d66036270f4..a99118a1228 100644 --- a/includes/class-wc-order-item-shipping.php +++ b/includes/class-wc-order-item-shipping.php @@ -276,11 +276,12 @@ class WC_Order_Item_Shipping extends WC_Order_Item { /** * Offset get: for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Key. * @return mixed */ public function offsetGet( $offset ) { + wc_deprecated_function( 'WC_Order_Item_Shipping::offsetGet', '4.4.0', '' ); if ( 'cost' === $offset ) { $offset = 'total'; } @@ -290,11 +291,12 @@ class WC_Order_Item_Shipping extends WC_Order_Item { /** * Offset set: for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Key. * @param mixed $value Value to set. */ public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Shipping::offsetSet', '4.4.0', '' ); if ( 'cost' === $offset ) { $offset = 'total'; } diff --git a/includes/class-wc-order-item-tax.php b/includes/class-wc-order-item-tax.php index e1fa89eb756..f2e6cf965de 100644 --- a/includes/class-wc-order-item-tax.php +++ b/includes/class-wc-order-item-tax.php @@ -244,11 +244,12 @@ class WC_Order_Item_Tax extends WC_Order_Item { /** * O for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Offset. * @return mixed */ public function offsetGet( $offset ) { + wc_deprecated_function( 'WC_Order_Item_Tax::offsetGet', '4.4.0', '' ); if ( 'tax_amount' === $offset ) { $offset = 'tax_total'; } elseif ( 'shipping_tax_amount' === $offset ) { @@ -260,11 +261,12 @@ class WC_Order_Item_Tax extends WC_Order_Item { /** * OffsetSet for ArrayAccess/Backwards compatibility. * - * @deprecated Add deprecation notices in future release. + * @deprecated 4.4.0 * @param string $offset Offset. * @param mixed $value Value. */ public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Tax::offsetSet', '4.4.0', '' ); if ( 'tax_amount' === $offset ) { $offset = 'tax_total'; } elseif ( 'shipping_tax_amount' === $offset ) { diff --git a/includes/class-woocommerce.php b/includes/class-woocommerce.php index 019b8bc2f9f..b3472ee6a85 100644 --- a/includes/class-woocommerce.php +++ b/includes/class-woocommerce.php @@ -653,7 +653,7 @@ final class WooCommerce { /** * Legacy image sizes. * - * @deprecated These sizes will be removed in 4.0. + * @deprecated 3.3.0 These sizes will be removed in 4.6.0. */ add_image_size( 'shop_catalog', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] ); add_image_size( 'shop_single', $single['width'], $single['height'], $single['crop'] ); diff --git a/includes/legacy/abstract-wc-legacy-order.php b/includes/legacy/abstract-wc-legacy-order.php index 50ede58e943..ea7729f5833 100644 --- a/includes/legacy/abstract-wc-legacy-order.php +++ b/includes/legacy/abstract-wc-legacy-order.php @@ -312,11 +312,12 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { /** * Get a product (either product or variation). - * @deprecated Add deprecation notices in future release. Replaced with $item->get_product() + * @deprecated 4.4.0 * @param object $item * @return WC_Product|bool */ public function get_product_from_item( $item ) { + wc_deprecated_function( 'WC_Abstract_Legacy_Order::get_product_from_item', '4.4.0', '$item->get_product()' ); if ( is_callable( array( $item, 'get_product' ) ) ) { $product = $item->get_product(); } else { @@ -461,7 +462,7 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * has_meta function for order items. This is different to the WC_Data * version and should be removed in future versions. * - * @deprecated + * @deprecated 3.0 * * @param int $order_item_id * diff --git a/includes/legacy/class-wc-legacy-api.php b/includes/legacy/class-wc-legacy-api.php index f99eae731d5..4bb14fa0b62 100644 --- a/includes/legacy/class-wc-legacy-api.php +++ b/includes/legacy/class-wc-legacy-api.php @@ -274,14 +274,14 @@ class WC_Legacy_API { /** * Rest API Init. * - * @deprecated since 3.7.0 - REST API clases autoload. + * @deprecated 3.7.0 - REST API clases autoload. */ public function rest_api_init() {} /** * Include REST API classes. * - * @deprecated since 3.7.0 - REST API clases autoload. + * @deprecated 3.7.0 - REST API clases autoload. */ public function rest_api_includes() { $this->rest_api_init(); @@ -289,9 +289,10 @@ class WC_Legacy_API { /** * Register REST API routes. * - * @deprecated since 3.7.0 - Not used. + * @deprecated 3.7.0 */ public function register_rest_routes() { + wc_deprecated_function( 'WC_Legacy_API::register_rest_routes', '3.7.0', '' ); $this->register_wp_admin_settings(); } } diff --git a/includes/legacy/class-wc-legacy-cart.php b/includes/legacy/class-wc-legacy-cart.php index 42844d6a6a2..4a5b14e0518 100644 --- a/includes/legacy/class-wc-legacy-cart.php +++ b/includes/legacy/class-wc-legacy-cart.php @@ -326,7 +326,7 @@ abstract class WC_Legacy_Cart { /** * Function to apply discounts to a product and get the discounted price (before tax is applied). * - * @deprecated Calculation and coupon logic is handled in WC_Cart_Totals. + * @deprecated 3.2.0 Calculation and coupon logic is handled in WC_Cart_Totals. * @param mixed $values Cart item. * @param mixed $price Price of item. * @param bool $add_totals Legacy. @@ -377,17 +377,18 @@ abstract class WC_Legacy_Cart { /** * Coupons enabled function. Filterable. * - * @deprecated 2.5.0 in favor to wc_coupons_enabled() + * @deprecated 2.5.0 * @return bool */ public function coupons_enabled() { + wc_deprecated_function( 'WC_Legacy_Cart::coupons_enabled', '2.5.0', 'wc_coupons_enabled' ); return wc_coupons_enabled(); } /** * Gets the total (product) discount amount - these are applied before tax. * - * @deprecated Order discounts (after tax) removed in 2.3 so multiple methods for discounts are no longer required. + * @deprecated 2.3.0 Order discounts (after tax) removed in 2.3 so multiple methods for discounts are no longer required. * @return mixed formatted price or false if there are none. */ public function get_discounts_before_tax() { @@ -403,7 +404,7 @@ abstract class WC_Legacy_Cart { /** * Get the total of all order discounts (after tax discounts). * - * @deprecated Order discounts (after tax) removed in 2.3. + * @deprecated 2.3.0 Order discounts (after tax) removed in 2.3. * @return int */ public function get_order_discount_total() { @@ -414,7 +415,7 @@ abstract class WC_Legacy_Cart { /** * Function to apply cart discounts after tax. * - * @deprecated Coupons can not be applied after tax. + * @deprecated 2.3.0 Coupons can not be applied after tax. * @param $values * @param $price */ @@ -425,7 +426,7 @@ abstract class WC_Legacy_Cart { /** * Function to apply product discounts after tax. * - * @deprecated Coupons can not be applied after tax. + * @deprecated 2.3.0 Coupons can not be applied after tax. * * @param $values * @param $price @@ -437,7 +438,7 @@ abstract class WC_Legacy_Cart { /** * Gets the order discount amount - these are applied after tax. * - * @deprecated Coupons can not be applied after tax. + * @deprecated 2.3.0 Coupons can not be applied after tax. */ public function get_discounts_after_tax() { wc_deprecated_function( 'get_discounts_after_tax', '2.3' ); diff --git a/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php b/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php index 2b4c6154fbe..c5d78a8c227 100644 --- a/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php +++ b/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php @@ -78,7 +78,7 @@ class WC_Shipping_Legacy_Flat_Rate extends WC_Shipping_Method { $this->tax_status = $this->get_option( 'tax_status' ); $this->cost = $this->get_option( 'cost' ); $this->type = $this->get_option( 'type', 'class' ); - $this->options = $this->get_option( 'options', false ); // @deprecated in 2.4.0 + $this->options = $this->get_option( 'options', false ); // @deprecated 2.4.0 } /** diff --git a/includes/wc-deprecated-functions.php b/includes/wc-deprecated-functions.php index 80a31ae4620..ea5f57f7191 100644 --- a/includes/wc-deprecated-functions.php +++ b/includes/wc-deprecated-functions.php @@ -885,8 +885,7 @@ function woocommerce_track_product_view() { } /** - * @since 2.3 - * @deprecated has no replacement + * @deprecated 2.3 has no replacement */ function woocommerce_compile_less_styles() { wc_deprecated_function( 'woocommerce_compile_less_styles', '2.3' ); @@ -895,7 +894,7 @@ function woocommerce_compile_less_styles() { /** * woocommerce_calc_shipping was an option used to determine if shipping was enabled prior to version 2.6.0. This has since been replaced with wc_shipping_enabled() function and * the woocommerce_ship_to_countries setting. - * @since 2.6.0 + * @deprecated 2.6.0 * @return string */ function woocommerce_calc_shipping_backwards_compatibility( $value ) { From eefd29e40ab2f2033e152308020dde2652d6b8a9 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 17 Jul 2020 10:22:44 +0200 Subject: [PATCH 299/440] add empty states array for liechtenstein add empty states array for country liechtenstein --- i18n/states.php | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/states.php b/i18n/states.php index a4a0ca5ccfc..c19136f8b20 100644 --- a/i18n/states.php +++ b/i18n/states.php @@ -837,6 +837,7 @@ return array( 'XS' => __( 'Xaisomboun', 'woocommerce' ), ), 'LB' => array(), + 'LI' => array(), 'LR' => array( // Liberia provinces. 'BM' => __( 'Bomi', 'woocommerce' ), 'BN' => __( 'Bong', 'woocommerce' ), From 601c7263b80ad4259432112caec41956479a4cf5 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 17 Jul 2020 10:26:48 +0200 Subject: [PATCH 300/440] hide state for liechtenstein hide the state field for liechtenstein --- includes/class-wc-countries.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-countries.php b/includes/class-wc-countries.php index b3e045136f3..749e0df424c 100644 --- a/includes/class-wc-countries.php +++ b/includes/class-wc-countries.php @@ -1245,8 +1245,8 @@ class WC_Countries { 'priority' => 65, ), 'state' => array( - 'label' => __( 'Municipality', 'woocommerce' ), 'required' => false, + 'hidden' => true, ), ), 'LK' => array( From d37a82fec8f59f166af223facd10d4cc62c37238 Mon Sep 17 00:00:00 2001 From: Damir Ha Date: Fri, 17 Jul 2020 13:04:20 +0200 Subject: [PATCH 301/440] Add Locale info and Hide state --- i18n/locale-info.php | 9 +++++++++ includes/class-wc-countries.php | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/i18n/locale-info.php b/i18n/locale-info.php index 08866ca44b1..3b499cc14c1 100644 --- a/i18n/locale-info.php +++ b/i18n/locale-info.php @@ -18,6 +18,15 @@ return array( 'weight_unit' => 'kg', 'dimension_unit' => 'cm', ), + 'BA' => array( + 'currency_code' => 'BAM', + 'currency_pos' => 'right', + 'thousand_sep' => '.', + 'decimal_sep' => ',', + 'num_decimals' => 2, + 'weight_unit' => 'kg', + 'dimension_unit' => 'cm', + ), 'BD' => array( 'currency_code' => 'BDT', 'currency_pos' => 'left', diff --git a/includes/class-wc-countries.php b/includes/class-wc-countries.php index b3e045136f3..ba2a8a66a3c 100644 --- a/includes/class-wc-countries.php +++ b/includes/class-wc-countries.php @@ -820,6 +820,19 @@ class WC_Countries { 'required' => false, ), ), + 'BA' => array( + 'country' => array( + 'label' => __('Country'), + ), + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'label' => __( 'Canton', 'woocommerce' ), + 'required' => false, + 'hidden' => true, + ), + ), 'BD' => array( 'postcode' => array( 'required' => false, From 5e2bae2a7d36bd3daac00e999bbdaa44b9385407 Mon Sep 17 00:00:00 2001 From: Damir Ha Date: Fri, 17 Jul 2020 13:06:40 +0200 Subject: [PATCH 302/440] Update currency_pos fix --- i18n/locale-info.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/locale-info.php b/i18n/locale-info.php index 3b499cc14c1..197e7591d5f 100644 --- a/i18n/locale-info.php +++ b/i18n/locale-info.php @@ -20,7 +20,7 @@ return array( ), 'BA' => array( 'currency_code' => 'BAM', - 'currency_pos' => 'right', + 'currency_pos' => 'right_space', 'thousand_sep' => '.', 'decimal_sep' => ',', 'num_decimals' => 2, From d3ab19b7cf3092048d36056bf655f9d20eb9973c Mon Sep 17 00:00:00 2001 From: Ron Rennick Date: Fri, 17 Jul 2020 17:14:26 -0300 Subject: [PATCH 303/440] eliminate internal use of deprecated functions - remove deprecation of offsetGet as it is used throught abstract order - eliminate use of offsetGet in unit tests, structured data, order functions - --- includes/class-wc-order-item-fee.php | 2 -- includes/class-wc-order-item-product.php | 4 +-- includes/class-wc-order-item-shipping.php | 2 -- includes/class-wc-order-item-tax.php | 2 -- includes/class-wc-order.php | 3 +- includes/class-wc-structured-data.php | 10 +++---- includes/wc-order-functions.php | 2 +- .../class-wc-tests-order-item-product.php | 29 +++++++++---------- 8 files changed, 21 insertions(+), 33 deletions(-) diff --git a/includes/class-wc-order-item-fee.php b/includes/class-wc-order-item-fee.php index b9b6a3cfec8..7b280f05795 100644 --- a/includes/class-wc-order-item-fee.php +++ b/includes/class-wc-order-item-fee.php @@ -290,12 +290,10 @@ class WC_Order_Item_Fee extends WC_Order_Item { /** * OffsetGet for ArrayAccess/Backwards compatibility. * - * @deprecated 4.4.0 * @param string $offset Offset. * @return mixed */ public function offsetGet( $offset ) { - wc_deprecated_function( 'WC_Order_Item_Fee::offsetGet', '4.4.0', '' ); if ( 'line_total' === $offset ) { $offset = 'total'; } elseif ( 'line_tax' === $offset ) { diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php index 3140892c7e2..24e8aab66ce 100644 --- a/includes/class-wc-order-item-product.php +++ b/includes/class-wc-order-item-product.php @@ -425,12 +425,10 @@ class WC_Order_Item_Product extends WC_Order_Item { /** * OffsetGet for ArrayAccess/Backwards compatibility. * - * @deprecated 4.4.0 * @param string $offset Offset. * @return mixed */ public function offsetGet( $offset ) { - wc_deprecated_function( 'WC_Order_Item_Shipping::offsetGet', '4.4.0', '' ); if ( 'line_subtotal' === $offset ) { $offset = 'subtotal'; } elseif ( 'line_subtotal_tax' === $offset ) { @@ -455,7 +453,7 @@ class WC_Order_Item_Product extends WC_Order_Item { * @param mixed $value Value. */ public function offsetSet( $offset, $value ) { - wc_deprecated_function( 'WC_Order_Item_Shipping::offsetSet', '4.4.0', '' ); + wc_deprecated_function( 'WC_Order_Item_Product::offsetSet', '4.4.0', '' ); if ( 'line_subtotal' === $offset ) { $offset = 'subtotal'; } elseif ( 'line_subtotal_tax' === $offset ) { diff --git a/includes/class-wc-order-item-shipping.php b/includes/class-wc-order-item-shipping.php index a99118a1228..c5ca078127d 100644 --- a/includes/class-wc-order-item-shipping.php +++ b/includes/class-wc-order-item-shipping.php @@ -276,12 +276,10 @@ class WC_Order_Item_Shipping extends WC_Order_Item { /** * Offset get: for ArrayAccess/Backwards compatibility. * - * @deprecated 4.4.0 * @param string $offset Key. * @return mixed */ public function offsetGet( $offset ) { - wc_deprecated_function( 'WC_Order_Item_Shipping::offsetGet', '4.4.0', '' ); if ( 'cost' === $offset ) { $offset = 'total'; } diff --git a/includes/class-wc-order-item-tax.php b/includes/class-wc-order-item-tax.php index f2e6cf965de..ac34b61eccb 100644 --- a/includes/class-wc-order-item-tax.php +++ b/includes/class-wc-order-item-tax.php @@ -244,12 +244,10 @@ class WC_Order_Item_Tax extends WC_Order_Item { /** * O for ArrayAccess/Backwards compatibility. * - * @deprecated 4.4.0 * @param string $offset Offset. * @return mixed */ public function offsetGet( $offset ) { - wc_deprecated_function( 'WC_Order_Item_Tax::offsetGet', '4.4.0', '' ); if ( 'tax_amount' === $offset ) { $offset = 'tax_total'; } elseif ( 'shipping_tax_amount' === $offset ) { diff --git a/includes/class-wc-order.php b/includes/class-wc-order.php index ea0c874c1b8..e364c84144c 100644 --- a/includes/class-wc-order.php +++ b/includes/class-wc-order.php @@ -1411,8 +1411,7 @@ class WC_Order extends WC_Abstract_Order { $needs_address = false; foreach ( $this->get_shipping_methods() as $shipping_method ) { - // Remove any instance IDs after ":". - $shipping_method_id = current( explode( ':', $shipping_method['method_id'] ) ); + $shipping_method_id = $shipping_method->get_method_id(); if ( ! in_array( $shipping_method_id, $hide, true ) ) { $needs_address = true; diff --git a/includes/class-wc-structured-data.php b/includes/class-wc-structured-data.php index b7fcc1c4827..3c2354c5a5b 100644 --- a/includes/class-wc-structured-data.php +++ b/includes/class-wc-structured-data.php @@ -216,7 +216,7 @@ class WC_Structured_Data { if ( '' !== $product->get_price() ) { // Assume prices will be valid until the end of next year, unless on sale and there is an end date. - $price_valid_until = date( 'Y-12-31', time() + YEAR_IN_SECONDS ); + $price_valid_until = gmdate( 'Y-12-31', time() + YEAR_IN_SECONDS ); if ( $product->is_type( 'variable' ) ) { $lowest = $product->get_variation_price( 'min', false ); @@ -243,7 +243,7 @@ class WC_Structured_Data { } } else { if ( $product->is_on_sale() && $product->get_date_on_sale_to() ) { - $price_valid_until = date( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ); + $price_valid_until = gmdate( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ); } $markup_offer = array( '@type' => 'Offer', @@ -459,7 +459,7 @@ class WC_Structured_Data { continue; } - $product = $order->get_product_from_item( $item ); + $product = $item->get_product(); $product_exists = is_object( $product ); $is_visible = $product_exists && $product->is_visible(); @@ -472,12 +472,12 @@ class WC_Structured_Data { 'priceCurrency' => $order->get_currency(), 'eligibleQuantity' => array( '@type' => 'QuantitativeValue', - 'value' => apply_filters( 'woocommerce_email_order_item_quantity', $item['qty'], $item ), + 'value' => apply_filters( 'woocommerce_email_order_item_quantity', $item->get_quantity(), $item ), ), ), 'itemOffered' => array( '@type' => 'Product', - 'name' => apply_filters( 'woocommerce_order_item_name', $item['name'], $item, $is_visible ), + 'name' => apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, $is_visible ), 'sku' => $product_exists ? $product->get_sku() : '', 'image' => $product_exists ? wp_get_attachment_image_url( $product->get_image_id() ) : '', 'url' => $is_visible ? get_permalink( $product->get_id() ) : get_home_url(), diff --git a/includes/wc-order-functions.php b/includes/wc-order-functions.php index 5ec7373deda..cb0d87db52d 100644 --- a/includes/wc-order-functions.php +++ b/includes/wc-order-functions.php @@ -822,7 +822,7 @@ function wc_update_total_sales_counts( $order_id ) { if ( $product_id ) { $data_store = WC_Data_Store::load( 'product' ); - $data_store->update_product_sales( $product_id, absint( $item['qty'] ), 'increase' ); + $data_store->update_product_sales( $product_id, absint( $item->get_quantity() ), 'increase' ); } } } diff --git a/tests/legacy/unit-tests/order-items/class-wc-tests-order-item-product.php b/tests/legacy/unit-tests/order-items/class-wc-tests-order-item-product.php index 363dc16aaeb..d253bf59332 100644 --- a/tests/legacy/unit-tests/order-items/class-wc-tests-order-item-product.php +++ b/tests/legacy/unit-tests/order-items/class-wc-tests-order-item-product.php @@ -222,33 +222,35 @@ class WC_Tests_Order_Item_Product extends WC_Unit_Test_Case { // Test line_subtotal. $this->assertTrue( isset( $item['line_subtotal'] ) ); - $item['line_subtotal'] = 50; + $item->set_subtotal( 50 ); $this->assertEquals( 50, $item->get_subtotal() ); $this->assertEquals( $item->get_subtotal(), $item['line_subtotal'] ); // Test line_subtotal_tax. $this->assertTrue( isset( $item['line_subtotal_tax'] ) ); - $item['line_subtotal_tax'] = 5; + $item->set_subtotal_tax( 5 ); $this->assertEquals( 5, $item->get_subtotal_tax() ); $this->assertEquals( $item->get_subtotal_tax(), $item['line_subtotal_tax'] ); // Test line_total. $this->assertTrue( isset( $item['line_total'] ) ); - $item['line_total'] = 55; + $item->set_total( 55 ); $this->assertEquals( 55, $item->get_total() ); $this->assertEquals( $item->get_total(), $item['line_total'] ); // Test line_tax. $this->assertTrue( isset( $item['line_tax'] ) ); - $item['line_tax'] = 5; + $item->set_total_tax( 5 ); $this->assertEquals( 5, $item->get_total_tax() ); $this->assertEquals( $item->get_total_tax(), $item['line_tax'] ); // Test line_tax_data. $this->assertTrue( isset( $item['line_tax_data'] ) ); - $item['line_tax_data'] = array( - 'total' => array( 5 ), - 'subtotal' => array( 5 ), + $item->set_taxes( + array( + 'total' => array( 5 ), + 'subtotal' => array( 5 ), + ) ); $this->assertEquals( array( @@ -261,26 +263,21 @@ class WC_Tests_Order_Item_Product extends WC_Unit_Test_Case { // Test qty. $this->assertTrue( isset( $item['qty'] ) ); - $item['qty'] = 150; + $item->set_quantity( 150 ); $this->assertEquals( 150, $item->get_quantity() ); $this->assertEquals( $item->get_quantity(), $item['qty'] ); // Test item_meta_array. $this->assertTrue( isset( $item['item_meta_array'] ) ); - $item['item_meta_array'] = array( - 0 => (object) array( - 'key' => 'test', - 'value' => 'val', - ), - ); + $item->update_meta_data( 'test', 'val', 0 ); $this->assertInstanceOf( 'WC_Meta_Data', current( $item->get_meta_data() ) ); $this->assertEquals( current( $item->get_meta_data() ), $item['item_meta_array'][''] ); unset( $item['item_meta_array'] ); $this->assertEquals( array(), $item->get_meta_data() ); // Test default. - $this->assertFalse( isset( $item['foo'] ) ); - $item['foo'] = 'bar'; + $this->assertFalse( $item->meta_exists( 'foo' ) ); + $item->add_meta_data( 'foo', 'bar' ); $this->assertEquals( 'bar', $item->get_meta( 'foo' ) ); } } From 4c7a0f158010bad26941a6c4724f1fe920057877 Mon Sep 17 00:00:00 2001 From: Damir Ha Date: Mon, 20 Jul 2020 18:18:14 +0200 Subject: [PATCH 304/440] Remove country label --- includes/class-wc-countries.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/includes/class-wc-countries.php b/includes/class-wc-countries.php index ba2a8a66a3c..81d10198f2f 100644 --- a/includes/class-wc-countries.php +++ b/includes/class-wc-countries.php @@ -821,9 +821,6 @@ class WC_Countries { ), ), 'BA' => array( - 'country' => array( - 'label' => __('Country'), - ), 'postcode' => array( 'priority' => 65, ), From f758b2bb317c8021d6ee1d74eabdc9ef94bbd980 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 20 Jul 2020 18:08:02 -0300 Subject: [PATCH 305/440] Fixed coding standards --- includes/class-wc-countries.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-countries.php b/includes/class-wc-countries.php index 81d10198f2f..e210adb20a4 100644 --- a/includes/class-wc-countries.php +++ b/includes/class-wc-countries.php @@ -827,7 +827,7 @@ class WC_Countries { 'state' => array( 'label' => __( 'Canton', 'woocommerce' ), 'required' => false, - 'hidden' => true, + 'hidden' => true, ), ), 'BD' => array( From a37628e94b41670aa3db4e1a9555fd03f45f623a Mon Sep 17 00:00:00 2001 From: Stamoulis Zamanis Date: Sat, 19 Oct 2019 02:10:40 +0300 Subject: [PATCH 306/440] Include modified in orderby filter --- .../Version3/class-wc-rest-crud-controller.php | 1 + .../Version3/class-wc-rest-customers-controller.php | 12 ++++++++++++ .../Version3/class-wc-rest-posts-controller.php | 1 + 3 files changed, 14 insertions(+) diff --git a/src/Controllers/Version3/class-wc-rest-crud-controller.php b/src/Controllers/Version3/class-wc-rest-crud-controller.php index ec9eb34b793..c12186ed387 100644 --- a/src/Controllers/Version3/class-wc-rest-crud-controller.php +++ b/src/Controllers/Version3/class-wc-rest-crud-controller.php @@ -584,6 +584,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'include', 'title', 'slug', + 'modified', ), 'validate_callback' => 'rest_validate_request_arg', ); diff --git a/src/Controllers/Version3/class-wc-rest-customers-controller.php b/src/Controllers/Version3/class-wc-rest-customers-controller.php index 65ce592cd55..770803f1587 100644 --- a/src/Controllers/Version3/class-wc-rest-customers-controller.php +++ b/src/Controllers/Version3/class-wc-rest-customers-controller.php @@ -304,4 +304,16 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { return $this->add_additional_fields_schema( $schema ); } + + /** + * Add new options for 'orderby' to the collection params. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'modified' ) ); + + return $params; + } } diff --git a/src/Controllers/Version3/class-wc-rest-posts-controller.php b/src/Controllers/Version3/class-wc-rest-posts-controller.php index 7c04b058923..0db471b87a3 100644 --- a/src/Controllers/Version3/class-wc-rest-posts-controller.php +++ b/src/Controllers/Version3/class-wc-rest-posts-controller.php @@ -673,6 +673,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { 'include', 'title', 'slug', + 'modified', ), 'validate_callback' => 'rest_validate_request_arg', ); From 7d335c5eabdf06721c2445ac6073b64fde479451 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 21 Jul 2020 18:22:16 +0530 Subject: [PATCH 307/440] Remove `modified` enum from customer because its not supported. Customers are based on `users` table which does not have a modified or similar column to track last modified timestamp, so this param cannot be supported at this time. --- .../Version3/class-wc-rest-customers-controller.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Controllers/Version3/class-wc-rest-customers-controller.php b/src/Controllers/Version3/class-wc-rest-customers-controller.php index 770803f1587..65ce592cd55 100644 --- a/src/Controllers/Version3/class-wc-rest-customers-controller.php +++ b/src/Controllers/Version3/class-wc-rest-customers-controller.php @@ -304,16 +304,4 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { return $this->add_additional_fields_schema( $schema ); } - - /** - * Add new options for 'orderby' to the collection params. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'modified' ) ); - - return $params; - } } From 0576b142a4d71bdc39e4688daedda54d24801b9c Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 21 Jul 2020 19:02:27 +0530 Subject: [PATCH 308/440] Add unit tests --- unit-tests/Tests/Version3/orders.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/unit-tests/Tests/Version3/orders.php b/unit-tests/Tests/Version3/orders.php index eb7b057c9e6..6ebb7477ae0 100644 --- a/unit-tests/Tests/Version3/orders.php +++ b/unit-tests/Tests/Version3/orders.php @@ -60,6 +60,33 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case { $this->assertEquals( 10, count( $orders ) ); } + /** + * Test getting all orders sorted by modified date. + */ + public function test_get_items_ordered_by_modified() { + wp_set_current_user( $this->user ); + + $order1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); + $order2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); + + $order1->set_status( 'completed' ); + $order1->save(); + sleep( 1 ); + $order2->set_status( 'completed' ); + $order2->save(); + + $request = new WP_REST_Request( 'GET', '/wc/v3/orders' ); + $request->set_query_params( array( 'orderby' => 'modified', 'order' => 'asc' ) ); + $response = $this->server->dispatch( $request ); + $orders = $response->get_data(); + $this->assertEquals( $order1->get_id(), $orders[0]['id'] ); + + $request->set_query_params( array( 'orderby' => 'modified', 'order' => 'desc' ) ); + $response = $this->server->dispatch( $request ); + $orders = $response->get_data(); + $this->assertEquals( $order2->get_id(), $orders[0]['id'] ); + } + /** * Tests to make sure orders cannot be viewed without valid permissions. * From bc52dbad89bb924b6e9575d20ef28734223ccd7a Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Tue, 21 Jul 2020 19:16:25 +0530 Subject: [PATCH 309/440] Fix tests in response to Core 25630 --- unit-tests/Tests/Version2/settings.php | 8 ++++---- unit-tests/Tests/Version3/settings.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/unit-tests/Tests/Version2/settings.php b/unit-tests/Tests/Version2/settings.php index 98d58c80dfc..12baa1aca4e 100644 --- a/unit-tests/Tests/Version2/settings.php +++ b/unit-tests/Tests/Version2/settings.php @@ -546,10 +546,10 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { array( 'id' => 'subject', 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', + 'description' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', 'type' => 'text', 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', + 'tip' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', 'value' => '', ), $setting @@ -569,10 +569,10 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { array( 'id' => 'subject', 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', + 'description' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', 'type' => 'text', 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', + 'tip' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', 'value' => 'This is my subject', ), $setting diff --git a/unit-tests/Tests/Version3/settings.php b/unit-tests/Tests/Version3/settings.php index 48d5934af37..4c764de1f6c 100644 --- a/unit-tests/Tests/Version3/settings.php +++ b/unit-tests/Tests/Version3/settings.php @@ -547,10 +547,10 @@ class Settings extends WC_REST_Unit_Test_Case { array( 'id' => 'subject', 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', + 'description' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', 'type' => 'text', 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', + 'tip' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', 'value' => '', 'group_id' => 'email_new_order', ), @@ -571,10 +571,10 @@ class Settings extends WC_REST_Unit_Test_Case { array( 'id' => 'subject', 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', + 'description' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', 'type' => 'text', 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {site_address}, {order_date}, {order_number}', + 'tip' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', 'value' => 'This is my subject', 'group_id' => 'email_new_order', ), From 0aac20b404ffc2326fdd1cbbba5c80aa8cb6a657 Mon Sep 17 00:00:00 2001 From: Mindaugas Budreika Date: Thu, 14 May 2020 09:54:49 +0400 Subject: [PATCH 310/440] forward query params (product variations) --- .../Version2/class-wc-rest-product-variations-v2-controller.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php index 81c8e7884c6..392098a7b94 100644 --- a/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php @@ -585,6 +585,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr public function batch_items( $request ) { $items = array_filter( $request->get_params() ); $params = $request->get_url_params(); + $query = $request->get_query_params(); $product_id = $params['product_id']; $body_params = array(); @@ -604,6 +605,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $request = new WP_REST_Request( $request->get_method() ); $request->set_body_params( $body_params ); + $request->set_query_params( $query ); return parent::batch_items( $request ); } From 0c366c5a75bf91fc892516d8aca7e47c7ede6516 Mon Sep 17 00:00:00 2001 From: Csaba Maulis Date: Tue, 28 Apr 2020 11:32:50 +0800 Subject: [PATCH 311/440] Fix `date_expire` and `expiry_date` field schema definitions Coupon controller for all API versions --- .../Version1/class-wc-rest-coupons-v1-controller.php | 2 +- .../Version2/class-wc-rest-coupons-v2-controller.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php b/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php index 5290c9f153c..06ca52b6047 100644 --- a/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php @@ -453,7 +453,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { ), 'expiry_date' => array( 'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'usage_count' => array( diff --git a/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php b/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php index 5f3ac9fcbab..7dbcaa1c2ae 100644 --- a/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php @@ -385,12 +385,12 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { ), 'date_expires' => array( 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_expires_gmt' => array( 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'string', + 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'usage_count' => array( From 1387725088813f06eabc6e86876c5c74a79c3402 Mon Sep 17 00:00:00 2001 From: Andrew Minion Date: Fri, 17 Apr 2020 13:56:27 -0500 Subject: [PATCH 312/440] add X-WP-Total headers to product attribute API calls --- .../class-wc-rest-product-attributes-v1-controller.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php index 3c9fa646a84..88e67708da9 100644 --- a/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php +++ b/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php @@ -228,7 +228,13 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { $data[] = $attribute; } - return rest_ensure_response( $data ); + $response = rest_ensure_response( $data ); + + // This API call always returns all product attributes due to retrieval from the object cache. + $response->header( 'X-WP-Total', count( $data ) ); + $response->header( 'X-WP-TotalPages', 1 ); + + return $response; } /** From 2f53fac78c0056f2ed06bcc31980e6913f4ef669 Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Tue, 7 Apr 2020 09:52:26 +0200 Subject: [PATCH 313/440] Update jetpack autoloader to ^1.6 --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index cfacbd52c0b..537262ed3c2 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "prefer-stable": true, "minimum-stability": "dev", "require": { - "automattic/jetpack-autoloader": "^1.2.0" + "automattic/jetpack-autoloader": "^1.6.0" }, "require-dev": { "phpunit/phpunit": "6.5.14", diff --git a/composer.lock b/composer.lock index 8fbba808a1f..35c89885f43 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2959ea86936fa65d0ea8f25e4f0e7fdb", + "content-hash": "18fc7a15ab7921e538dea77490edd41b", "packages": [ { "name": "automattic/jetpack-autoloader", - "version": "v1.3.5", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "efa1cec37282cf60efaf57724ae2532c7c21bf94" + "reference": "3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/efa1cec37282cf60efaf57724ae2532c7c21bf94", - "reference": "efa1cec37282cf60efaf57724ae2532c7c21bf94", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7", + "reference": "3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7", "shasum": "" }, "require": { @@ -40,7 +40,7 @@ "GPL-2.0-or-later" ], "description": "Creates a custom autoloader for a plugin or theme.", - "time": "2019-11-25T12:37:57+00:00" + "time": "2020-03-26T07:57:53+00:00" } ], "packages-dev": [ From c843455b0b83d2f7da30f6672e344b527814bd7d Mon Sep 17 00:00:00 2001 From: Dhruvin Date: Fri, 20 Mar 2020 19:21:53 +0530 Subject: [PATCH 314/440] Clear Action Scheduler Transients Currently when Clear Transients action is performed via System Tools, the Action Scheduler Transients are not cleared resulting in incorrect comment counts. --- .../Version2/class-wc-rest-system-status-tools-v2-controller.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index a418b35844b..ee62d186b82 100644 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -442,6 +442,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { wc_delete_product_transients(); wc_delete_shop_order_transients(); delete_transient( 'wc_count_comments' ); + delete_transient( 'as_comment_count' ); $attribute_taxonomies = wc_get_attribute_taxonomies(); From 5335083922d350e73eaf0e8370d8335e1b076b55 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Wed, 22 Jul 2020 23:55:16 +0530 Subject: [PATCH 315/440] Keep only unit test files for merge into core. --- .editorconfig | 24 - .gitattributes | 7 - .gitignore | 35 - .scrutinizer.yml | 118 - .travis.yml | 26 - README.md | 67 - composer.json | 46 - composer.lock | 1934 ------------ package-lock.json | 1618 ---------- package.json | 31 - phpcs.xml | 40 - phpunit.xml | 17 - .../class-wc-rest-coupons-v1-controller.php | 580 ---- ...-rest-customer-downloads-v1-controller.php | 252 -- .../class-wc-rest-customers-v1-controller.php | 924 ------ ...lass-wc-rest-order-notes-v1-controller.php | 439 --- ...ss-wc-rest-order-refunds-v1-controller.php | 530 ---- .../class-wc-rest-orders-v1-controller.php | 1631 ---------- ...-product-attribute-terms-v1-controller.php | 241 -- ...-rest-product-attributes-v1-controller.php | 592 ---- ...-rest-product-categories-v1-controller.php | 271 -- ...-wc-rest-product-reviews-v1-controller.php | 578 ---- ...product-shipping-classes-v1-controller.php | 134 - ...ass-wc-rest-product-tags-v1-controller.php | 134 - .../class-wc-rest-products-v1-controller.php | 2641 ----------------- ...ass-wc-rest-report-sales-v1-controller.php | 397 --- ...-rest-report-top-sellers-v1-controller.php | 174 -- .../class-wc-rest-reports-v1-controller.php | 184 -- ...lass-wc-rest-tax-classes-v1-controller.php | 321 -- .../class-wc-rest-taxes-v1-controller.php | 709 ----- ...-rest-webhook-deliveries-v1-controller.php | 314 -- .../class-wc-rest-webhooks-v1-controller.php | 763 ----- .../class-wc-rest-coupons-v2-controller.php | 542 ---- ...-rest-customer-downloads-v2-controller.php | 165 - .../class-wc-rest-customers-v2-controller.php | 364 --- ...s-wc-rest-network-orders-v2-controller.php | 174 -- ...lass-wc-rest-order-notes-v2-controller.php | 182 -- ...ss-wc-rest-order-refunds-v2-controller.php | 584 ---- .../class-wc-rest-orders-v2-controller.php | 1711 ----------- ...wc-rest-payment-gateways-v2-controller.php | 466 --- ...-product-attribute-terms-v2-controller.php | 27 - ...-rest-product-attributes-v2-controller.php | 27 - ...-rest-product-categories-v2-controller.php | 212 -- ...-wc-rest-product-reviews-v2-controller.php | 199 -- ...product-shipping-classes-v2-controller.php | 27 - ...ass-wc-rest-product-tags-v2-controller.php | 27 - ...-rest-product-variations-v2-controller.php | 996 ------- .../class-wc-rest-products-v2-controller.php | 2209 -------------- ...ass-wc-rest-report-sales-v2-controller.php | 27 - ...-rest-report-top-sellers-v2-controller.php | 27 - .../class-wc-rest-reports-v2-controller.php | 27 - ...-wc-rest-setting-options-v2-controller.php | 581 ---- .../class-wc-rest-settings-v2-controller.php | 232 -- ...wc-rest-shipping-methods-v2-controller.php | 231 -- ...-shipping-zone-locations-v2-controller.php | 190 -- ...st-shipping-zone-methods-v2-controller.php | 541 ---- ...s-wc-rest-shipping-zones-v2-controller.php | 304 -- ...rest-system-status-tools-v2-controller.php | 618 ---- ...ss-wc-rest-system-status-v2-controller.php | 1259 -------- ...lass-wc-rest-tax-classes-v2-controller.php | 27 - .../class-wc-rest-taxes-v2-controller.php | 27 - ...-rest-webhook-deliveries-v2-controller.php | 153 - .../class-wc-rest-webhooks-v2-controller.php | 182 -- .../Version3/class-wc-rest-controller.php | 503 ---- .../class-wc-rest-coupons-controller.php | 27 - .../class-wc-rest-crud-controller.php | 628 ---- ...-wc-rest-customer-downloads-controller.php | 27 - .../class-wc-rest-customers-controller.php | 307 -- ...ass-wc-rest-data-continents-controller.php | 357 --- .../class-wc-rest-data-controller.php | 184 -- ...lass-wc-rest-data-countries-controller.php | 240 -- ...ass-wc-rest-data-currencies-controller.php | 221 -- ...lass-wc-rest-network-orders-controller.php | 27 - .../class-wc-rest-order-notes-controller.php | 167 -- ...class-wc-rest-order-refunds-controller.php | 86 - .../class-wc-rest-orders-controller.php | 271 -- ...ss-wc-rest-payment-gateways-controller.php | 226 -- .../class-wc-rest-posts-controller.php | 724 ----- ...est-product-attribute-terms-controller.php | 27 - ...-wc-rest-product-attributes-controller.php | 27 - ...-wc-rest-product-categories-controller.php | 271 -- ...ass-wc-rest-product-reviews-controller.php | 1164 -------- ...st-product-shipping-classes-controller.php | 27 - .../class-wc-rest-product-tags-controller.php | 27 - ...-wc-rest-product-variations-controller.php | 860 ------ .../class-wc-rest-products-controller.php | 1341 --------- ...-rest-report-coupons-totals-controller.php | 143 - ...est-report-customers-totals-controller.php | 154 - ...c-rest-report-orders-totals-controller.php | 127 - ...rest-report-products-totals-controller.php | 133 - ...-rest-report-reviews-totals-controller.php | 132 - .../class-wc-rest-report-sales-controller.php | 27 - ...-wc-rest-report-top-sellers-controller.php | 27 - .../class-wc-rest-reports-controller.php | 72 - ...ass-wc-rest-setting-options-controller.php | 250 -- .../class-wc-rest-settings-controller.php | 112 - ...ss-wc-rest-shipping-methods-controller.php | 27 - ...est-shipping-zone-locations-controller.php | 27 - ...-rest-shipping-zone-methods-controller.php | 27 - ...wc-rest-shipping-zones-controller-base.php | 125 - ...lass-wc-rest-shipping-zones-controller.php | 27 - ...class-wc-rest-system-status-controller.php | 27 - ...wc-rest-system-status-tools-controller.php | 27 - .../class-wc-rest-tax-classes-controller.php | 27 - .../class-wc-rest-taxes-controller.php | 27 - .../class-wc-rest-terms-controller.php | 806 ----- .../class-wc-rest-webhooks-controller.php | 37 - src/Package.php | 48 - src/Server.php | 181 -- src/Utilities/ImageAttachment.php | 93 - src/Utilities/SingletonTrait.php | 49 - unit-tests/Bootstrap.php | 134 - unit-tests/bin/install.sh | 202 -- unit-tests/bin/phpcs.sh | 11 - unit-tests/bin/phpunit.sh | 2 - woocommerce-rest-api.php | 68 - 116 files changed, 38998 deletions(-) delete mode 100644 .editorconfig delete mode 100644 .gitattributes delete mode 100644 .gitignore delete mode 100644 .scrutinizer.yml delete mode 100644 .travis.yml delete mode 100644 README.md delete mode 100644 composer.json delete mode 100644 composer.lock delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 phpcs.xml delete mode 100644 phpunit.xml delete mode 100644 src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-customers-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-orders-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-products-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-reports-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php delete mode 100644 src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-customers-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-orders-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-products-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-reports-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-settings-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php delete mode 100644 src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-coupons-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-crud-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-customers-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-data-continents-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-data-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-data-countries-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-data-currencies-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-network-orders-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-order-notes-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-order-refunds-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-orders-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-posts-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-product-attributes-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-product-categories-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-product-reviews-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-product-tags-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-product-variations-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-products-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-report-sales-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-reports-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-setting-options-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-settings-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php delete mode 100644 src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-system-status-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-tax-classes-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-taxes-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-terms-controller.php delete mode 100644 src/Controllers/Version3/class-wc-rest-webhooks-controller.php delete mode 100644 src/Package.php delete mode 100644 src/Server.php delete mode 100644 src/Utilities/ImageAttachment.php delete mode 100644 src/Utilities/SingletonTrait.php delete mode 100755 unit-tests/Bootstrap.php delete mode 100755 unit-tests/bin/install.sh delete mode 100755 unit-tests/bin/phpcs.sh delete mode 100755 unit-tests/bin/phpunit.sh delete mode 100644 woocommerce-rest-api.php diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index c3dfa83750f..00000000000 --- a/.editorconfig +++ /dev/null @@ -1,24 +0,0 @@ -# This file is for unifying the coding style for different editors and IDEs -# editorconfig.org - -# WordPress Coding Standards -# https://make.wordpress.org/core/handbook/coding-standards/ - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 4 -tab_width = 4 -indent_style = tab -insert_final_newline = true -trim_trailing_whitespace = true - -[*.txt] -trim_trailing_whitespace = false - -[*.{md,json,yml}] -trim_trailing_whitespace = false -indent_style = space -indent_size = 2 diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index b5d3da03cbb..00000000000 --- a/.gitattributes +++ /dev/null @@ -1,7 +0,0 @@ -/.* export-ignore -/phpcs.xml export-ignore -/phpunit.* export-ignore -/unit-tests export-ignore -/vendor export-ignore -/README.md export-ignore -/readme.txt export-ignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index b19a8d1f0ae..00000000000 --- a/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -# Editors -project.xml -project.properties -/nbproject/private/ -.buildpath -.project -.settings* -.idea -.vscode -*.sublime-project -*.sublime-workspace -.sublimelinterrc - -# Grunt -/node_modules/ -none - -# Sass -.sass-cache/ - -# OS X metadata -.DS_Store - -# Windows junk -Thumbs.db - -# Unit tests -/tmp -/unit-tests/bin/tmp - -# Logs -/logs - -# composer -vendor/ diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 04bbd2b73b4..00000000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,118 +0,0 @@ -tools: - php_code_sniffer: - config: - standard: WordPress - sensiolabs_security_checker: true -checks: - php: - avoid_closing_tag: false - avoid_superglobals: false - coding_standard: - name: WordPress - no_exit: false - no_global_keyword: false - one_class_per_file: false - psr2_class_declaration: false - psr2_control_structure_declaration: false - psr2_switch_declaration: false - variable_existence: false - verify_access_scope_valid: false - verify_argument_usable_as_reference: false - verify_property_names: false -filter: - dependency_paths: - - wordpress/ - - woocommerce/ - excluded_paths: - - src/Controllers/Version1/ - - src/Controllers/Version2/ - - src/Controllers/Version3/ - - tests/ - - vendor/ - - classmap.php -coding_style: - php: - indentation: - general: - use_tabs: true - size: 4 - switch: - indent_case: true - spaces: - around_operators: - concatenation: true - negation: true - within: - brackets: true - grouping: true - function_call: true - function_declaration: true - if: true - for: true - while: true - switch: true - catch: true - before_left_brace: - class: true - function: true - if: true - else: true - for: true - while: true - do: true - switch: true - try: true - catch: true - finally: true - before_keywords: - else: true - while: true - catch: true - finally: true - ternary_operator: - before_condition: true - after_condition: true - before_alternative: true - after_alternative: true - in_short_version: false - other: - before_comma: false - after_comma: true - before_semicolon: false - after_semicolon: true - after_type_cast: true - braces: - classes_functions: - class: end-of-line - function: end-of-line - closure: end-of-line - if: - opening: undefined - always: true - else_on_new_line: false - for: - opening: undefined - always: true - while: - opening: undefined - always: true - do_while: - opening: undefined - always: true - while_on_new_line: false - switch: - opening: undefined - try: - opening: undefined - catch_on_new_line: false - finally_on_new_line: false -build: - tests: - override: - command: "php -v" - nodes: - analysis: - dependencies: - before: - - composer require --dev johnpbloch/wordpress-core - - composer require --dev woocommerce/woocommerce diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c907c8983a9..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: php -dist: trusty -sudo: required -cache: - directories: - - vendor - - $HOME/.composer/cache -matrix: - include: - - name: "PHP 7.2 unit tests, PHP Coding standards check" - php: 7.2 - env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress RUN_PHPCS=1 - - name: "PHP 7.1 unit tests" - php: 7.1 - env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress - -before_script: - - export PATH="$HOME/.composer/vendor/bin:$PATH" - - phpenv config-rm xdebug.ini - - composer install - - composer global require "phpunit/phpunit=4.8.*|6.5.*" - - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION - -script: - - bash unit-tests/bin/phpunit.sh - - bash unit-tests/bin/phpcs.sh diff --git a/README.md b/README.md deleted file mode 100644 index 9a2eff0a244..00000000000 --- a/README.md +++ /dev/null @@ -1,67 +0,0 @@ -WooCommerce REST API -=== - -license -Latest Stable Version -Build Status -Scrutinizer Code Quality - -This repository is home to the WooCommerce REST API package. - -The stable version of this package is bundled with [WooCommerce core](https://github.com/woocommerce/woocommerce) releases, but it can also be used as a standalone plugin so bleeding-edge API features can be tested or used by other feature plugins. - -## Using this package as a plugin - -After checking out the code to your `wp-content/plugins` directory, you'll need to run `composer install` in the plugin directory (`wp-content/plugins/woocommerce-rest-api`) to install dependencies and to enable the autoloader. Without performing this step, if you activate the plugin it will simply show an admin notice. - -## API documentation - -- [Usage documentation for the REST API can be found here](https://github.com/woocommerce/woocommerce/wiki/Getting-started-with-the-REST-API). -- [Contribution documentation can be found here.](https://github.com/woocommerce/woocommerce/wiki/Contributing-to-the-WooCommerce-REST-API) - -### Versions - -| Namespace | Status | Docs | -| -------- | -------- | -------- | -| `wc/v4` | Development | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/) | -| `wc/v3` | Stable | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/) | -| `wc/v2` | Deprecated - October 2020 | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v2.html) | -| `wc/v1` | Deprecated - April 2019 | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v1.html) | - -Note: API Versions are kept around for 2 years after being replaced, and may be removed in the next major version after that date passes. - -## Using this package in other projects - -This package is [hosted on Packagist](https://packagist.org/packages/woocommerce/woocommerce-rest-api) and can be included using composer.json: - -```json -"require": { - "woocommerce/woocommerce-rest-api": "1.0" -}, -``` - -Since multiple versions of this package may be included at the same time, it includes a special package-version autoloader. This dependency is also on Packagist: - -```json - "automattic/jetpack-autoloader": "^1" -``` - -And using this autoloader requires the following include in your codebase: - -``` -$autoloader = __DIR__ . '/vendor/autoload_packages.php'; -``` - -If you choose to use your own autoloader, please note you won't be able to determine which version of the package is running since it could use the version in WooCommerce core or your version. The namespaces would conflict. All of our feature plugins and packages use the package autoloader. - -## Contributing - -Please read the [WooCommerce contributor guidelines](https://github.com/woocommerce/woocommerce/blob/master/.github/CONTRIBUTING.md) for more information how you can contribute to WooCommerce, and [the REST API contribution documentation here](https://github.com/woocommerce/woocommerce/wiki/Contributing-to-the-WooCommerce-REST-API). - -Within this package, namespaces and endpoint classes are located within the `src/RestAPI/` directory. If you need to change the behavior of an endpoint, you can do so in these classes. - -Run tests using `phpunit` in the root of the package. All pull-requests must pass unit tests in order to be accepted. - -## Translation - -For strings located in API endpoints, use `woocommerce` as your text-domain. These endpoints will be translated in the WooCommerce Core PO/MO files. diff --git a/composer.json b/composer.json deleted file mode 100644 index 537262ed3c2..00000000000 --- a/composer.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "woocommerce/woocommerce-rest-api", - "description": "The WooCommerce core REST API.", - "homepage": "https://github.com/woocommerce/woocommerce-rest-api", - "license": "GPL-3.0-or-later", - "type": "wordpress-plugin", - "prefer-stable": true, - "minimum-stability": "dev", - "require": { - "automattic/jetpack-autoloader": "^1.6.0" - }, - "require-dev": { - "phpunit/phpunit": "6.5.14", - "woocommerce/woocommerce-sniffs": "0.0.9" - }, - "scripts": { - "post-install-cmd": [ - "composer dump-autoload" - ], - "post-update-cmd": [ - "composer dump-autoload" - ], - "test": [ - "phpunit" - ], - "phpcs": [ - "phpcs -s -p" - ], - "phpcs-pre-commit": [ - "phpcs -s -p -n" - ], - "phpcbf": [ - "phpcbf -p" - ] - }, - "autoload": { - "classmap": [ - "src/Controllers/Version1", - "src/Controllers/Version2", - "src/Controllers/Version3" - ], - "psr-4": { - "Automattic\\WooCommerce\\RestApi\\": "src" - } - } -} diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 35c89885f43..00000000000 --- a/composer.lock +++ /dev/null @@ -1,1934 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "18fc7a15ab7921e538dea77490edd41b", - "packages": [ - { - "name": "automattic/jetpack-autoloader", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7", - "reference": "3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5" - }, - "type": "composer-plugin", - "extra": { - "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin" - }, - "autoload": { - "psr-4": { - "Automattic\\Jetpack\\Autoloader\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0-or-later" - ], - "description": "Creates a custom autoloader for a plugin or theme.", - "time": "2020-03-26T07:57:53+00:00" - } - ], - "packages-dev": [ - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.5.0", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "e749410375ff6fb7a040a68878c656c2e610b132" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132", - "reference": "e749410375ff6fb7a040a68878c656c2e610b132", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0", - "php": "^5.3|^7", - "squizlabs/php_codesniffer": "^2|^3" - }, - "require-dev": { - "composer/composer": "*", - "phpcompatibility/php-compatibility": "^9.0", - "sensiolabs/security-checker": "^4.1.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "time": "2018-10-26T13:21:45+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2019-10-21T16:45:58+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.9.3", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", - "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "time": "2019-08-09T12:45:53+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" - }, - { - "name": "phar-io/version", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" - }, - { - "name": "phpcompatibility/php-compatibility", - "version": "9.3.4", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "1f37659196e4f3113ea506a7efba201c52303bf1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/1f37659196e4f3113ea506a7efba201c52303bf1", - "reference": "1f37659196e4f3113ea506a7efba201c52303bf1", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" - }, - "conflict": { - "squizlabs/php_codesniffer": "2.6.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "homepage": "https://github.com/wimg", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" - } - ], - "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", - "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", - "keywords": [ - "compatibility", - "phpcs", - "standards" - ], - "time": "2019-11-15T04:12:02+00:00" - }, - { - "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/b862bc32f7e860d0b164b199bd995e690b4b191c", - "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c", - "shasum": "" - }, - "require": { - "phpcompatibility/php-compatibility": "^9.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5", - "paragonie/random_compat": "dev-master", - "paragonie/sodium_compat": "dev-master" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } - ], - "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", - "homepage": "http://phpcompatibility.com/", - "keywords": [ - "compatibility", - "paragonie", - "phpcs", - "polyfill", - "standards" - ], - "time": "2019-11-04T15:17:54+00:00" - }, - { - "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "41bef18ba688af638b7310666db28e1ea9158b2f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/41bef18ba688af638b7310666db28e1ea9158b2f", - "reference": "41bef18ba688af638b7310666db28e1ea9158b2f", - "shasum": "" - }, - "require": { - "phpcompatibility/php-compatibility": "^9.0", - "phpcompatibility/phpcompatibility-paragonie": "^1.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } - ], - "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", - "homepage": "http://phpcompatibility.com/", - "keywords": [ - "compatibility", - "phpcs", - "standards", - "wordpress" - ], - "time": "2019-08-28T14:22:28+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2018-08-07T13:53:10+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-09-12T14:27:41+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "shasum": "" - }, - "require": { - "php": "^7.1", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "^7.1", - "mockery/mockery": "~1", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2019-08-22T18:11:29+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.9.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", - "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2019-10-03T11:07:50+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "5.3.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-xdebug": "^2.5.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2018-04-06T15:36:58+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2017-02-26T11:10:40+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2017-11-27T05:48:46+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "6.5.14", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.9", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.5.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2019-02-01T05:22:47+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.10", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5.11" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "abandoned": true, - "time": "2018-08-09T05:50:03+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" - }, - { - "name": "sebastian/comparator", - "version": "2.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2018-02-01T13:46:46+00:00" - }, - { - "name": "sebastian/diff", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2017-08-03T08:09:46+00:00" - }, - { - "name": "sebastian/environment", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2017-07-01T08:51:00+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2019-09-14T09:02:43+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.5.3", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", - "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2019-12-04T04:46:47+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.13.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.13-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "time": "2019-11-27T13:56:44+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2019-06-13T22:48:21+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "vimeo/psalm": "<3.6.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2019-11-24T13:36:37+00:00" - }, - { - "name": "woocommerce/woocommerce-sniffs", - "version": "0.0.9", - "source": { - "type": "git", - "url": "https://github.com/woocommerce/woocommerce-sniffs.git", - "reference": "7677a84e9a355fe1e088f704090be891e7a6d427" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/7677a84e9a355fe1e088f704090be891e7a6d427", - "reference": "7677a84e9a355fe1e088f704090be891e7a6d427", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "0.5.0", - "php": ">=7.0", - "phpcompatibility/phpcompatibility-wp": "2.1.0", - "wp-coding-standards/wpcs": "2.2.0" - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Claudio Sanches", - "email": "claudio@automattic.com" - } - ], - "description": "WooCommerce sniffs", - "keywords": [ - "phpcs", - "standards", - "woocommerce", - "wordpress" - ], - "time": "2019-11-11T15:48:34+00:00" - }, - { - "name": "wp-coding-standards/wpcs", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/f90e8692ce97b693633db7ab20bfa78d930f536a", - "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.3.1" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", - "phpcompatibility/php-compatibility": "^9.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Contributors", - "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", - "keywords": [ - "phpcs", - "standards", - "wordpress" - ], - "time": "2019-11-11T12:34:03+00:00" - } - ], - "aliases": [], - "minimum-stability": "dev", - "stability-flags": [], - "prefer-stable": true, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] -} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index b1506082765..00000000000 --- a/package-lock.json +++ /dev/null @@ -1,1618 +0,0 @@ -{ - "name": "woocommerce-rest-api", - "version": "1.0.5", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/runtime": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", - "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - } - }, - "@samverschueren/stream-to-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", - "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", - "dev": true, - "requires": { - "any-observable": "^0.3.0" - } - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.5.0.tgz", - "integrity": "sha512-Onhn+z72D2O2Pb2ql2xukJ55rglumsVo1H6Fmyi8mlU9SvKdBk/pUSUAiBY/d9bAOF7VVWajX3sths/+g6ZiAQ==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "any-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", - "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - } - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", - "dev": true, - "requires": { - "slice-ansi": "0.0.4", - "string-width": "^1.0.1" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "date-fns": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", - "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "del": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", - "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", - "dev": true, - "requires": { - "globby": "^10.0.1", - "graceful-fs": "^4.2.2", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.1", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "elegant-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "execa": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", - "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^3.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "fast-glob": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", - "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2" - } - }, - "fastq": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", - "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", - "dev": true, - "requires": { - "reusify": "^1.0.0" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "dev": true - }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "husky": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.0.10.tgz", - "integrity": "sha512-Ptm4k2DqOwxeK/kzu5RaJmNRoGvESrgDXObFcZ8aJZcyXyMBHhM2FqZj6zYKdetadmP3wCwxEHCBuB9xGlRp8A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "ci-info": "^2.0.0", - "cosmiconfig": "^6.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^4.2.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - } - }, - "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "dev": true - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-observable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", - "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", - "dev": true, - "requires": { - "symbol-observable": "^1.1.0" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "dev": true - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "lint-staged": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz", - "integrity": "sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "commander": "^2.20.0", - "cosmiconfig": "^5.2.1", - "debug": "^4.1.1", - "dedent": "^0.7.0", - "del": "^5.0.0", - "execa": "^2.0.3", - "listr": "^0.14.3", - "log-symbols": "^3.0.0", - "micromatch": "^4.0.2", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.1.1", - "string-argv": "^0.3.0", - "stringify-object": "^3.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "listr": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", - "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", - "dev": true, - "requires": { - "@samverschueren/stream-to-observable": "^0.3.0", - "is-observable": "^1.1.0", - "is-promise": "^2.1.0", - "is-stream": "^1.1.0", - "listr-silent-renderer": "^1.1.1", - "listr-update-renderer": "^0.5.0", - "listr-verbose-renderer": "^0.5.0", - "p-map": "^2.0.0", - "rxjs": "^6.3.3" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - } - } - }, - "listr-silent-renderer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", - "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", - "dev": true - }, - "listr-update-renderer": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", - "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "elegant-spinner": "^1.0.1", - "figures": "^1.7.0", - "indent-string": "^3.0.0", - "log-symbols": "^1.0.2", - "log-update": "^2.3.0", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "^1.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "listr-verbose-renderer": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", - "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "cli-cursor": "^2.1.0", - "date-fns": "^1.27.2", - "figures": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "log-update": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", - "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "cli-cursor": "^2.0.0", - "wrap-ansi": "^3.0.1" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", - "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - } - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, - "wrap-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", - "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "yaml": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", - "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.6.3" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 2d17f61330a..00000000000 --- a/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "woocommerce-rest-api", - "title": "WooCommerce REST API", - "version": "1.0.10", - "homepage": "https://woocommerce.com/", - "repository": { - "type": "git", - "url": "https://github.com/woocommerce/woocommerce-rest-api.git" - }, - "license": "GPL-3.0+", - "main": "Gruntfile.js", - "devDependencies": { - "husky": "4.0.10", - "lint-staged": "9.5.0" - }, - "engines": { - "node": ">=10.15.0", - "npm": ">=6.4.1" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "*.php": [ - "php -d display_errors=1 -l", - "composer run-script phpcs-pre-commit" - ] - } -} diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index ceb59896bf8..00000000000 --- a/phpcs.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - WooCommerce dev PHP_CodeSniffer ruleset. - - - tests/ - apigen/ - */node_modules/* - */vendor/* - - - - - - - - - - - - - - - - tests/ - - - - * - - - - tests/ - - - - i18n/ - * - - diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index 9119520176d..00000000000 --- a/phpunit.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - ./unit-tests/Tests - - - diff --git a/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php b/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php deleted file mode 100644 index 06ca52b6047..00000000000 --- a/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php +++ /dev/null @@ -1,580 +0,0 @@ -post_type}_query", array( $this, 'query_args' ), 10, 2 ); - } - - /** - * Register the routes for coupons. - */ - public function register_routes() { - register_rest_route( $this->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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'required' => true, - 'type' => 'string', - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Query args. - * - * @param array $args Query args - * @param WP_REST_Request $request Request data. - * @return array - */ - public function query_args( $args, $request ) { - if ( ! empty( $request['code'] ) ) { - $id = wc_get_coupon_id_by_code( $request['code'] ); - $args['post__in'] = array( $id ); - } - - return $args; - } - - /** - * Prepare a single coupon output for response. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $data - */ - public function prepare_item_for_response( $post, $request ) { - $coupon = new WC_Coupon( (int) $post->ID ); - $_data = $coupon->get_data(); - - $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); - $format_date = array( 'date_created', 'date_modified' ); - $format_date_utc = array( 'date_expires' ); - $format_null = array( 'usage_limit', 'usage_limit_per_user' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $_data[ $key ] = wc_format_decimal( $_data[ $key ], 2 ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ], false ) : null; - } - foreach ( $format_date_utc as $key ) { - $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; - } - - // Format null values. - foreach ( $format_null as $key ) { - $_data[ $key ] = $_data[ $key ] ? $_data[ $key ] : null; - } - - $data = array( - 'id' => $_data['id'], - 'code' => $_data['code'], - 'date_created' => $_data['date_created'], - 'date_modified' => $_data['date_modified'], - 'discount_type' => $_data['discount_type'], - 'description' => $_data['description'], - 'amount' => $_data['amount'], - 'expiry_date' => $_data['date_expires'], - 'usage_count' => $_data['usage_count'], - 'individual_use' => $_data['individual_use'], - 'product_ids' => $_data['product_ids'], - 'exclude_product_ids' => $_data['excluded_product_ids'], - 'usage_limit' => $_data['usage_limit'], - 'usage_limit_per_user' => $_data['usage_limit_per_user'], - 'limit_usage_to_x_items' => $_data['limit_usage_to_x_items'], - 'free_shipping' => $_data['free_shipping'], - 'product_categories' => $_data['product_categories'], - 'excluded_product_categories' => $_data['excluded_product_categories'], - 'exclude_sale_items' => $_data['exclude_sale_items'], - 'minimum_amount' => $_data['minimum_amount'], - 'maximum_amount' => $_data['maximum_amount'], - 'email_restrictions' => $_data['email_restrictions'], - 'used_by' => $_data['used_by'], - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $post, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); - } - - /** - * Only return writable props from schema. - * @param array $schema - * @return bool - */ - protected function filter_writable_props( $schema ) { - return empty( $schema['readonly'] ); - } - - /** - * Prepare a single coupon for create or update. - * - * @param WP_REST_Request $request Request object. - * @return WP_Error|stdClass $data Post object. - */ - protected function prepare_item_for_database( $request ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $coupon = new WC_Coupon( $id ); - $schema = $this->get_item_schema(); - $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - - // Update to schema to make compatible with CRUD schema. - if ( $request['exclude_product_ids'] ) { - $request['excluded_product_ids'] = $request['exclude_product_ids']; - } - if ( $request['expiry_date'] ) { - $request['date_expires'] = $request['expiry_date']; - } - - // Validate required POST fields. - if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { - if ( empty( $request['code'] ) ) { - return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce-rest-api' ), 'code' ), array( 'status' => 400 ) ); - } - } - - // Handle all writable props. - foreach ( $data_keys as $key ) { - $value = $request[ $key ]; - - if ( ! is_null( $value ) ) { - switch ( $key ) { - case 'code' : - $coupon_code = wc_format_coupon_code( $value ); - $id = $coupon->get_id() ? $coupon->get_id() : 0; - $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); - - if ( $id_from_code ) { - return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $coupon->set_code( $coupon_code ); - break; - case 'description' : - $coupon->set_description( wp_filter_post_kses( $value ) ); - break; - case 'expiry_date' : - $coupon->set_date_expires( $value ); - break; - default : - if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { - $coupon->{"set_{$key}"}( $value ); - } - break; - } - } - } - - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for insertion. - * - * @param WC_Coupon $coupon The coupon object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request ); - } - - /** - * Create a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $coupon_id = $this->save_coupon( $request ); - if ( is_wp_error( $coupon_id ) ) { - return $coupon_id; - } - - $post = get_post( $coupon_id ); - $this->update_additional_fields_for_object( $post, $request ); - - $this->add_post_meta_fields( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); - - return $response; - } - - /** - * Update a single coupon. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - try { - $post_id = (int) $request['id']; - - if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $coupon_id = $this->save_coupon( $request ); - if ( is_wp_error( $coupon_id ) ) { - return $coupon_id; - } - - $post = get_post( $coupon_id ); - $this->update_additional_fields_for_object( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - return rest_ensure_response( $response ); - - } catch ( Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Saves a coupon to the database. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|int - */ - protected function save_coupon( $request ) { - try { - $coupon = $this->prepare_item_for_database( $request ); - - if ( is_wp_error( $coupon ) ) { - return $coupon; - } - - $coupon->save(); - return $coupon->get_id(); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Get the Coupon's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the object.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Coupon description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'discount_type' => array( - 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'fixed_cart', - 'enum' => array_keys( wc_get_coupon_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'amount' => array( - 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'expiry_date' => array( - 'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'usage_count' => array( - 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'individual_use' => array( - 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'product_ids' => array( - 'description' => __( "List of product IDs the coupon can be used on.", 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'exclude_product_ids' => array( - 'description' => __( "List of product IDs the coupon cannot be used on.", 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'usage_limit' => array( - 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'usage_limit_per_user' => array( - 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'limit_usage_to_x_items' => array( - 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'free_shipping' => array( - 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'product_categories' => array( - 'description' => __( "List of category IDs the coupon applies to.", 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'excluded_product_categories' => array( - 'description' => __( "List of category IDs the coupon does not apply to.", 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'exclude_sale_items' => array( - 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'minimum_amount' => array( - 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'maximum_amount' => array( - 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email_restrictions' => array( - 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - 'context' => array( 'view', 'edit' ), - ), - 'used_by' => array( - 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['code'] = array( - 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php b/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php deleted file mode 100644 index 0d65f93dff9..00000000000 --- a/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php +++ /dev/null @@ -1,252 +0,0 @@ -/downloads endpoint. - * - * @author WooThemes - * @category API - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * REST API Customers controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Controller - */ -class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'customers/(?P[\d]+)/downloads'; - - /** - * Register the routes for customers. - */ - public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'customer_id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - 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' ), - ) ); - } - - /** - * Check whether a given request has permission to read customers. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - $customer = get_user_by( 'id', (int) $request['customer_id'] ); - - if ( ! $customer ) { - return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_user_permissions( 'read', $customer->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all customer downloads. - * - * @param WP_REST_Request $request - * @return array - */ - public function get_items( $request ) { - $downloads = wc_get_customer_available_downloads( (int) $request['customer_id'] ); - - $data = array(); - foreach ( $downloads as $download_data ) { - $download = $this->prepare_item_for_response( (object) $download_data, $request ); - $download = $this->prepare_response_for_collection( $download ); - $data[] = $download; - } - - return rest_ensure_response( $data ); - } - - /** - * Prepare a single download output for response. - * - * @param stdObject $download Download object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $download, $request ) { - $data = (array) $download; - $data['access_expires'] = $data['access_expires'] ? wc_rest_prepare_date_response( $data['access_expires'] ) : 'never'; - $data['downloads_remaining'] = '' === $data['downloads_remaining'] ? 'unlimited' : $data['downloads_remaining']; - - // Remove "product_name" since it's new in 3.0. - unset( $data['product_name'] ); - - $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( $download, $request ) ); - - /** - * Filter customer download data returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param stdObject $download Download object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); - } - - /** - * Prepare links for the request. - * - * @param stdClass $download Download object. - * @param WP_REST_Request $request Request object. - * @return array Links for the given customer download. - */ - protected function prepare_links( $download, $request ) { - $base = str_replace( '(?P[\d]+)', $request['customer_id'], $this->rest_base ); - $links = array( - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'product' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $download->product_id ) ), - ), - 'order' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $download->order_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Customer Download's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'customer_download', - 'type' => 'object', - 'properties' => array( - 'download_url' => array( - 'description' => __( 'Download file URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'download_id' => array( - 'description' => __( 'Download ID (MD5).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Downloadable product ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'download_name' => array( - 'description' => __( 'Downloadable file name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'downloads_remaining' => array( - 'description' => __( 'Number of downloads remaining.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'access_expires' => array( - 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'file' => array( - 'description' => __( 'File details.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php b/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php deleted file mode 100644 index 8fc2687ca16..00000000000 --- a/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php +++ /dev/null @@ -1,924 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'email' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'New user email address.', 'woocommerce-rest-api' ), - ), - 'username' => array( - 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), - 'description' => __( 'New user username.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - 'password' => array( - 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), - 'description' => __( 'New user password.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - 'reassign' => array( - 'default' => 0, - 'type' => 'integer', - 'description' => __( 'ID to reassign posts to.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read customers. - * - * @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_user_permissions( 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create customers. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_user_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a customer. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = (int) $request['id']; - - if ( ! wc_rest_check_user_permissions( 'read', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access update a customer. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function update_item_permissions_check( $request ) { - $id = (int) $request['id']; - - if ( ! wc_rest_check_user_permissions( 'edit', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a customer. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function delete_item_permissions_check( $request ) { - $id = (int) $request['id']; - - if ( ! wc_rest_check_user_permissions( 'delete', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_user_permissions( 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all customers. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $prepared_args = array(); - $prepared_args['exclude'] = $request['exclude']; - $prepared_args['include'] = $request['include']; - $prepared_args['order'] = $request['order']; - $prepared_args['number'] = $request['per_page']; - if ( ! empty( $request['offset'] ) ) { - $prepared_args['offset'] = $request['offset']; - } else { - $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; - } - $orderby_possibles = array( - 'id' => 'ID', - 'include' => 'include', - 'name' => 'display_name', - 'registered_date' => 'registered', - ); - $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; - $prepared_args['search'] = $request['search']; - - if ( '' !== $prepared_args['search'] ) { - $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; - } - - // Filter by email. - if ( ! empty( $request['email'] ) ) { - $prepared_args['search'] = $request['email']; - $prepared_args['search_columns'] = array( 'user_email' ); - } - - // Filter by role. - if ( 'all' !== $request['role'] ) { - $prepared_args['role'] = $request['role']; - } - - /** - * Filter arguments, before passing to WP_User_Query, when querying users via the REST API. - * - * @see https://developer.wordpress.org/reference/classes/wp_user_query/ - * - * @param array $prepared_args Array of arguments for WP_User_Query. - * @param WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_customer_query', $prepared_args, $request ); - - $query = new WP_User_Query( $prepared_args ); - - $users = array(); - foreach ( $query->results as $user ) { - $data = $this->prepare_item_for_response( $user, $request ); - $users[] = $this->prepare_response_for_collection( $data ); - } - - $response = rest_ensure_response( $users ); - - // Store pagination values for headers then unset for count query. - $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); - - $prepared_args['fields'] = 'ID'; - - $total_users = $query->get_total(); - if ( $total_users < 1 ) { - // Out-of-bounds, run the query again without LIMIT for total count. - unset( $prepared_args['number'] ); - unset( $prepared_args['offset'] ); - $count_query = new WP_User_Query( $prepared_args ); - $total_users = $count_query->get_total(); - } - $response->header( 'X-WP-Total', (int) $total_users ); - $max_pages = ceil( $total_users / $per_page ); - $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; - } - - /** - * Create a single customer. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - try { - if ( ! empty( $request['id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), 400 ); - } - - // Sets the username. - $request['username'] = ! empty( $request['username'] ) ? $request['username'] : ''; - - // Sets the password. - $request['password'] = ! empty( $request['password'] ) ? $request['password'] : ''; - - // Create customer. - $customer = new WC_Customer; - $customer->set_username( $request['username'] ); - $customer->set_password( $request['password'] ); - $customer->set_email( $request['email'] ); - $this->update_customer_meta_fields( $customer, $request ); - $customer->save(); - - if ( ! $customer->get_id() ) { - throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce-rest-api' ), 400 ); - } - - $user_data = get_userdata( $customer->get_id() ); - $this->update_additional_fields_for_object( $user_data, $request ); - - /** - * Fires after a customer is created or updated via the REST API. - * - * @param WP_User $user_data Data used to create the customer. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating customer, false when updating customer. - */ - do_action( 'woocommerce_rest_insert_customer', $user_data, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $user_data, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ) ); - - return $response; - } catch ( Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Get a single customer. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $user_data = get_userdata( $id ); - - if ( empty( $id ) || empty( $user_data->ID ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $customer = $this->prepare_item_for_response( $user_data, $request ); - $response = rest_ensure_response( $customer ); - - return $response; - } - - /** - * Update a single user. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - try { - $id = (int) $request['id']; - $customer = new WC_Customer( $id ); - - if ( ! $customer->get_id() ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), 400 ); - } - - if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->get_email() ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce-rest-api' ), 400 ); - } - - if ( ! empty( $request['username'] ) && $request['username'] !== $customer->get_username() ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce-rest-api' ), 400 ); - } - - // Customer email. - if ( isset( $request['email'] ) ) { - $customer->set_email( sanitize_email( $request['email'] ) ); - } - - // Customer password. - if ( isset( $request['password'] ) ) { - $customer->set_password( $request['password'] ); - } - - $this->update_customer_meta_fields( $customer, $request ); - $customer->save(); - - $user_data = get_userdata( $customer->get_id() ); - $this->update_additional_fields_for_object( $user_data, $request ); - - if ( ! is_user_member_of_blog( $user_data->ID ) ) { - $user_data->add_role( 'customer' ); - } - - /** - * Fires after a customer is created or updated via the REST API. - * - * @param WP_User $customer Data used to create the customer. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating customer, false when updating customer. - */ - do_action( 'woocommerce_rest_insert_customer', $user_data, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $user_data, $request ); - $response = rest_ensure_response( $response ); - return $response; - } catch ( Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Delete a single customer. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $reassign = isset( $request['reassign'] ) ? absint( $request['reassign'] ) : null; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $user_data = get_userdata( $id ); - if ( ! $user_data ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - if ( ! empty( $reassign ) ) { - if ( $reassign === $id || ! get_userdata( $reassign ) ) { - return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $user_data, $request ); - - /** Include admin customer functions to get access to wp_delete_user() */ - require_once ABSPATH . 'wp-admin/includes/user.php'; - - $customer = new WC_Customer( $id ); - - if ( ! is_null( $reassign ) ) { - $result = $customer->delete_and_reassign( $reassign ); - } else { - $result = $customer->delete(); - } - - if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a customer is deleted via the REST API. - * - * @param WP_User $user_data User data. - * @param WP_REST_Response $response The response returned from the API. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_customer', $user_data, $response, $request ); - - return $response; - } - - /** - * Prepare a single customer output for response. - * - * @param WP_User $user_data User object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $user_data, $request ) { - $customer = new WC_Customer( $user_data->ID ); - $_data = $customer->get_data(); - $last_order = wc_get_customer_last_order( $customer->get_id() ); - $format_date = array( 'date_created', 'date_modified' ); - - // Format date values. - foreach ( $format_date as $key ) { - $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; // v1 API used UTC. - } - - $data = array( - 'id' => $_data['id'], - 'date_created' => $_data['date_created'], - 'date_modified' => $_data['date_modified'], - 'email' => $_data['email'], - 'first_name' => $_data['first_name'], - 'last_name' => $_data['last_name'], - 'username' => $_data['username'], - 'last_order' => array( - 'id' => is_object( $last_order ) ? $last_order->get_id() : null, - 'date' => is_object( $last_order ) ? wc_rest_prepare_date_response( $last_order->get_date_created() ) : null, // v1 API used UTC. - ), - 'orders_count' => $customer->get_order_count(), - 'total_spent' => $customer->get_total_spent(), - 'avatar_url' => $customer->get_avatar_url(), - 'billing' => $_data['billing'], - 'shipping' => $_data['shipping'], - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $user_data ) ); - - /** - * Filter customer data returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_User $user_data User object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); - } - - /** - * Update customer meta fields. - * - * @param WC_Customer $customer - * @param WP_REST_Request $request - */ - protected function update_customer_meta_fields( $customer, $request ) { - $schema = $this->get_item_schema(); - - // Customer first name. - if ( isset( $request['first_name'] ) ) { - $customer->set_first_name( wc_clean( $request['first_name'] ) ); - } - - // Customer last name. - if ( isset( $request['last_name'] ) ) { - $customer->set_last_name( wc_clean( $request['last_name'] ) ); - } - - // Customer billing address. - if ( isset( $request['billing'] ) ) { - foreach ( array_keys( $schema['properties']['billing']['properties'] ) as $field ) { - if ( isset( $request['billing'][ $field ] ) && is_callable( array( $customer, "set_billing_{$field}" ) ) ) { - $customer->{"set_billing_{$field}"}( $request['billing'][ $field ] ); - } - } - } - - // Customer shipping address. - if ( isset( $request['shipping'] ) ) { - foreach ( array_keys( $schema['properties']['shipping']['properties'] ) as $field ) { - if ( isset( $request['shipping'][ $field ] ) && is_callable( array( $customer, "set_shipping_{$field}" ) ) ) { - $customer->{"set_shipping_{$field}"}( $request['shipping'][ $field ] ); - } - } - } - } - - /** - * Prepare links for the request. - * - * @param WP_User $customer Customer object. - * @return array Links for the given customer. - */ - protected function prepare_links( $customer ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the Customer's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'customer', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_user', - ), - ), - 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - ), - 'last_order' => array( - 'description' => __( 'Last order data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => array( - 'id' => array( - 'description' => __( 'Last order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date' => array( - 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - 'orders_count' => array( - 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_spent' => array( - 'description' => __( 'Total amount spent.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get role names. - * - * @return array - */ - protected function get_role_names() { - global $wp_roles; - - return array_keys( $wp_roles->role_names ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['context']['default'] = 'view'; - - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'enum' => array( 'asc', 'desc' ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'default' => 'name', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'enum' => array( - 'id', - 'include', - 'name', - 'registered_date', - ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['email'] = array( - 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['role'] = array( - 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'customer', - 'enum' => array_merge( array( 'all' ), $this->get_role_names() ), - 'validate_callback' => 'rest_validate_request_arg', - ); - return $params; - } -} diff --git a/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php deleted file mode 100644 index 785ff4627b4..00000000000 --- a/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php +++ /dev/null @@ -1,439 +0,0 @@ -/notes endpoint. - * - * @author WooThemes - * @category API - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * REST API Order Notes controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Controller - */ -class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'orders/(?P[\d]+)/notes'; - - /** - * Post type. - * - * @var string - */ - protected $post_type = 'shop_order'; - - /** - * Register the routes for order notes. - */ - public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'note' => array( - 'type' => 'string', - 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), - 'required' => true, - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read order 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_post_permissions( $this->post_type, 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create order notes. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a order note. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a order note. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function delete_item_permissions_check( $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get order notes from an order. - * - * @param WP_REST_Request $request - * - * @return array|WP_Error - */ - public function get_items( $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $args = array( - 'post_id' => $order->get_id(), - 'approve' => 'approve', - 'type' => 'order_note', - ); - - remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); - - $notes = get_comments( $args ); - - add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); - - $data = array(); - foreach ( $notes as $note ) { - $order_note = $this->prepare_item_for_response( $note, $request ); - $order_note = $this->prepare_response_for_collection( $order_note ); - $data[] = $order_note; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a single order note. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - // Create the note. - $note_id = $order->add_order_note( $request['note'], $request['customer_note'] ); - - if ( ! $note_id ) { - return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $note = get_comment( $note_id ); - $this->update_additional_fields_for_object( $note, $request ); - - /** - * Fires after a order note is created or updated via the REST API. - * - * @param WP_Comment $note New order note object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $note, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); - - return $response; - } - - /** - * Get a single order note. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $note = get_comment( $id ); - - if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $order_note = $this->prepare_item_for_response( $note, $request ); - $response = rest_ensure_response( $order_note ); - - return $response; - } - - /** - * Delete a single order note. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $note = get_comment( $id ); - - if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $note, $request ); - - $result = wc_delete_order_note( $note->comment_ID ); - - if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), 'order_note' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a order note is deleted or trashed via the REST API. - * - * @param WP_Comment $note The deleted or trashed order note. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_order_note', $note, $response, $request ); - - return $response; - } - - /** - * Prepare a single order note output for response. - * - * @param WP_Comment $note Order note object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $note, $request ) { - $data = array( - 'id' => (int) $note->comment_ID, - 'date_created' => wc_rest_prepare_date_response( $note->comment_date_gmt ), - 'note' => $note->comment_content, - 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), - ); - - $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( $note ) ); - - /** - * Filter order note object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_Comment $note Order note object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); - } - - /** - * Prepare links for the request. - * - * @param WP_Comment $note Delivery order_note object. - * @return array Links for the given order note. - */ - protected function prepare_links( $note ) { - $order_id = (int) $note->comment_post_ID; - $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $note->comment_ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Order Notes schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'order_note', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'note' => array( - 'description' => __( 'Order note.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'customer_note' => array( - 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php b/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php deleted file mode 100644 index 659ffa844ae..00000000000 --- a/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php +++ /dev/null @@ -1,530 +0,0 @@ -/refunds endpoint. - * - * @author WooThemes - * @category API - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * REST API Order Refunds controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Orders_V1_Controller - */ -class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'orders/(?P[\d]+)/refunds'; - - /** - * Post type. - * - * @var string - */ - protected $post_type = 'shop_order_refund'; - - /** - * Order refunds actions. - */ - public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_trashable", '__return_false' ); - add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 ); - } - - /** - * Register the routes for order refunds. - */ - public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => true, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - } - - /** - * Prepare a single order refund output for response. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * - * @return WP_Error|WP_REST_Response - */ - public function prepare_item_for_response( $post, $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); - } - - $refund = wc_get_order( $post ); - - if ( ! $refund || $refund->get_parent_id() !== $order->get_id() ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce-rest-api' ), 404 ); - } - - $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); - - $data = array( - 'id' => $refund->get_id(), - 'date_created' => wc_rest_prepare_date_response( $refund->get_date_created() ), - 'amount' => wc_format_decimal( $refund->get_amount(), $dp ), - 'reason' => $refund->get_reason(), - 'line_items' => array(), - ); - - // Add line items. - foreach ( $refund->get_items() as $item_id => $item ) { - $product = $refund->get_product_from_item( $item ); - $product_id = 0; - $variation_id = 0; - $product_sku = null; - - // Check if the product exists. - if ( is_object( $product ) ) { - $product_id = $item->get_product_id(); - $variation_id = $item->get_variation_id(); - $product_sku = $product->get_sku(); - } - - $item_meta = array(); - - $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; - - foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { - $item_meta[] = array( - 'key' => $formatted_meta->key, - 'label' => $formatted_meta->display_key, - 'value' => wc_clean( $formatted_meta->display_value ), - ); - } - - $line_item = array( - 'id' => $item_id, - 'name' => $item['name'], - 'sku' => $product_sku, - 'product_id' => (int) $product_id, - 'variation_id' => (int) $variation_id, - 'quantity' => wc_stock_amount( $item['qty'] ), - 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', - 'price' => wc_format_decimal( $refund->get_item_total( $item, false, false ), $dp ), - 'subtotal' => wc_format_decimal( $refund->get_line_subtotal( $item, false, false ), $dp ), - 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), - 'total' => wc_format_decimal( $refund->get_line_total( $item, false, false ), $dp ), - 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), - 'taxes' => array(), - 'meta' => $item_meta, - ); - - $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); - if ( isset( $item_line_taxes['total'] ) ) { - $line_tax = array(); - - foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { - $line_tax[ $tax_rate_id ] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => '', - ); - } - - foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { - $line_tax[ $tax_rate_id ]['subtotal'] = $tax; - } - - $line_item['taxes'] = array_values( $line_tax ); - } - - $data['line_items'][] = $line_item; - } - - $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( $refund, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Order_Refund $refund Comment object. - * @param WP_REST_Request $request Request object. - * @return array Links for the given order refund. - */ - protected function prepare_links( $refund, $request ) { - $order_id = $refund->get_parent_id(); - $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $refund->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), - ), - ); - - return $links; - } - - /** - * Query args. - * - * @param array $args Request args. - * @param WP_REST_Request $request Request object. - * @return array - */ - public function query_args( $args, $request ) { - $args['post_status'] = array_keys( wc_get_order_statuses() ); - $args['post_parent__in'] = array( absint( $request['order_id'] ) ); - - return $args; - } - - /** - * Create a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $order_data = get_post( (int) $request['order_id'] ); - - if ( empty( $order_data ) ) { - return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce-rest-api' ), 400 ); - } - - if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); - } - - // Create the refund. - $refund = wc_create_refund( array( - 'order_id' => $order_data->ID, - 'amount' => $request['amount'], - 'reason' => empty( $request['reason'] ) ? null : $request['reason'], - 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, - 'restock_items' => true, - ) ); - - if ( is_wp_error( $refund ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); - } - - if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); - } - - $post = get_post( $refund->get_id() ); - $this->update_additional_fields_for_object( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); - - return $response; - } - - /** - * Get the Order's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'amount' => array( - 'description' => __( 'Refund amount.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'reason' => array( - 'description' => __( 'Reason for refund.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'meta' => array( - 'description' => __( 'Line item meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'Meta label.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - '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 = parent::get_collection_params(); - - $params['dp'] = array( - 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php b/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php deleted file mode 100644 index 502bc2eeb29..00000000000 --- a/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php +++ /dev/null @@ -1,1631 +0,0 @@ -post_type}_query", array( $this, 'query_args' ), 10, 2 ); - } - - /** - * Register the routes for orders. - */ - public function register_routes() { - register_rest_route( $this->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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Prepare a single order output for response. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $data - */ - public function prepare_item_for_response( $post, $request ) { - $order = wc_get_order( $post ); - $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); - - $data = array( - 'id' => $order->get_id(), - 'parent_id' => $order->get_parent_id(), - 'status' => $order->get_status(), - 'order_key' => $order->get_order_key(), - 'number' => $order->get_order_number(), - 'currency' => $order->get_currency(), - 'version' => $order->get_version(), - 'prices_include_tax' => $order->get_prices_include_tax(), - 'date_created' => wc_rest_prepare_date_response( $order->get_date_created() ), // v1 API used UTC. - 'date_modified' => wc_rest_prepare_date_response( $order->get_date_modified() ), // v1 API used UTC. - 'customer_id' => $order->get_customer_id(), - 'discount_total' => wc_format_decimal( $order->get_total_discount(), $dp ), - 'discount_tax' => wc_format_decimal( $order->get_discount_tax(), $dp ), - 'shipping_total' => wc_format_decimal( $order->get_shipping_total(), $dp ), - 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), $dp ), - 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), $dp ), - 'total' => wc_format_decimal( $order->get_total(), $dp ), - 'total_tax' => wc_format_decimal( $order->get_total_tax(), $dp ), - 'billing' => array(), - 'shipping' => array(), - 'payment_method' => $order->get_payment_method(), - 'payment_method_title' => $order->get_payment_method_title(), - 'transaction_id' => $order->get_transaction_id(), - 'customer_ip_address' => $order->get_customer_ip_address(), - 'customer_user_agent' => $order->get_customer_user_agent(), - 'created_via' => $order->get_created_via(), - 'customer_note' => $order->get_customer_note(), - 'date_completed' => wc_rest_prepare_date_response( $order->get_date_completed(), false ), // v1 API used local time. - 'date_paid' => wc_rest_prepare_date_response( $order->get_date_paid(), false ), // v1 API used local time. - 'cart_hash' => $order->get_cart_hash(), - 'line_items' => array(), - 'tax_lines' => array(), - 'shipping_lines' => array(), - 'fee_lines' => array(), - 'coupon_lines' => array(), - 'refunds' => array(), - ); - - // Add addresses. - $data['billing'] = $order->get_address( 'billing' ); - $data['shipping'] = $order->get_address( 'shipping' ); - - // Add line items. - foreach ( $order->get_items() as $item_id => $item ) { - $product = $order->get_product_from_item( $item ); - $product_id = 0; - $variation_id = 0; - $product_sku = null; - - // Check if the product exists. - if ( is_object( $product ) ) { - $product_id = $item->get_product_id(); - $variation_id = $item->get_variation_id(); - $product_sku = $product->get_sku(); - } - - $item_meta = array(); - - $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; - - foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { - $item_meta[] = array( - 'key' => $formatted_meta->key, - 'label' => $formatted_meta->display_key, - 'value' => wc_clean( $formatted_meta->display_value ), - ); - } - - $line_item = array( - 'id' => $item_id, - 'name' => $item['name'], - 'sku' => $product_sku, - 'product_id' => (int) $product_id, - 'variation_id' => (int) $variation_id, - 'quantity' => wc_stock_amount( $item['qty'] ), - 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', - 'price' => wc_format_decimal( $order->get_item_total( $item, false, false ), $dp ), - 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item, false, false ), $dp ), - 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), - 'total' => wc_format_decimal( $order->get_line_total( $item, false, false ), $dp ), - 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), - 'taxes' => array(), - 'meta' => $item_meta, - ); - - $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); - if ( isset( $item_line_taxes['total'] ) ) { - $line_tax = array(); - - foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { - $line_tax[ $tax_rate_id ] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => '', - ); - } - - foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { - $line_tax[ $tax_rate_id ]['subtotal'] = $tax; - } - - $line_item['taxes'] = array_values( $line_tax ); - } - - $data['line_items'][] = $line_item; - } - - // Add taxes. - foreach ( $order->get_items( 'tax' ) as $key => $tax ) { - $tax_line = array( - 'id' => $key, - 'rate_code' => $tax['name'], - 'rate_id' => $tax['rate_id'], - 'label' => isset( $tax['label'] ) ? $tax['label'] : $tax['name'], - 'compound' => (bool) $tax['compound'], - 'tax_total' => wc_format_decimal( $tax['tax_amount'], $dp ), - 'shipping_tax_total' => wc_format_decimal( $tax['shipping_tax_amount'], $dp ), - ); - - $data['tax_lines'][] = $tax_line; - } - - // Add shipping. - foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { - $shipping_line = array( - 'id' => $shipping_item_id, - 'method_title' => $shipping_item['name'], - 'method_id' => $shipping_item['method_id'], - 'total' => wc_format_decimal( $shipping_item['cost'], $dp ), - 'total_tax' => wc_format_decimal( '', $dp ), - 'taxes' => array(), - ); - - $shipping_taxes = $shipping_item->get_taxes(); - - if ( ! empty( $shipping_taxes['total'] ) ) { - $shipping_line['total_tax'] = wc_format_decimal( array_sum( $shipping_taxes['total'] ), $dp ); - - foreach ( $shipping_taxes['total'] as $tax_rate_id => $tax ) { - $shipping_line['taxes'][] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - ); - } - } - - $data['shipping_lines'][] = $shipping_line; - } - - // Add fees. - foreach ( $order->get_fees() as $fee_item_id => $fee_item ) { - $fee_line = array( - 'id' => $fee_item_id, - 'name' => $fee_item['name'], - 'tax_class' => ! empty( $fee_item['tax_class'] ) ? $fee_item['tax_class'] : '', - 'tax_status' => 'taxable', - 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), $dp ), - 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), $dp ), - 'taxes' => array(), - ); - - $fee_line_taxes = maybe_unserialize( $fee_item['line_tax_data'] ); - if ( isset( $fee_line_taxes['total'] ) ) { - $fee_tax = array(); - - foreach ( $fee_line_taxes['total'] as $tax_rate_id => $tax ) { - $fee_tax[ $tax_rate_id ] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => '', - ); - } - - if ( isset( $fee_line_taxes['subtotal'] ) ) { - foreach ( $fee_line_taxes['subtotal'] as $tax_rate_id => $tax ) { - $fee_tax[ $tax_rate_id ]['subtotal'] = $tax; - } - } - - $fee_line['taxes'] = array_values( $fee_tax ); - } - - $data['fee_lines'][] = $fee_line; - } - - // Add coupons. - foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) { - $coupon_line = array( - 'id' => $coupon_item_id, - 'code' => $coupon_item['name'], - 'discount' => wc_format_decimal( $coupon_item['discount_amount'], $dp ), - 'discount_tax' => wc_format_decimal( $coupon_item['discount_amount_tax'], $dp ), - ); - - $data['coupon_lines'][] = $coupon_line; - } - - // Add refunds. - foreach ( $order->get_refunds() as $refund ) { - $data['refunds'][] = array( - 'id' => $refund->get_id(), - 'refund' => $refund->get_reason() ? $refund->get_reason() : '', - 'total' => '-' . wc_format_decimal( $refund->get_amount(), $dp ), - ); - } - - $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( $order, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Order $order Order object. - * @param WP_REST_Request $request Request object. - * @return array Links for the given order. - */ - protected function prepare_links( $order, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $order->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - if ( 0 !== (int) $order->get_user_id() ) { - $links['customer'] = array( - 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $order->get_user_id() ) ), - ); - } - if ( 0 !== (int) $order->get_parent_id() ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order->get_parent_id() ) ), - ); - } - return $links; - } - - /** - * Query args. - * - * @param array $args - * @param WP_REST_Request $request - * @return array - */ - public function query_args( $args, $request ) { - global $wpdb; - - // Set post_status. - if ( 'any' !== $request['status'] ) { - $args['post_status'] = 'wc-' . $request['status']; - } else { - $args['post_status'] = 'any'; - } - - if ( isset( $request['customer'] ) ) { - if ( ! empty( $args['meta_query'] ) ) { - $args['meta_query'] = array(); - } - - $args['meta_query'][] = array( - 'key' => '_customer_user', - 'value' => $request['customer'], - 'type' => 'NUMERIC', - ); - } - - // Search by product. - if ( ! empty( $request['product'] ) ) { - $order_ids = $wpdb->get_col( $wpdb->prepare( " - SELECT order_id - FROM {$wpdb->prefix}woocommerce_order_items - WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) - AND order_item_type = 'line_item' - ", $request['product'] ) ); - - // Force WP_Query return empty if don't found any order. - $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); - - $args['post__in'] = $order_ids; - } - - // Search. - if ( ! empty( $args['s'] ) ) { - $order_ids = wc_order_search( $args['s'] ); - - if ( ! empty( $order_ids ) ) { - unset( $args['s'] ); - $args['post__in'] = array_merge( $order_ids, array( 0 ) ); - } - } - - return $args; - } - - /** - * Prepare a single order for create. - * - * @param WP_REST_Request $request Request object. - * @return WP_Error|WC_Order $data Object. - */ - protected function prepare_item_for_database( $request ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $order = new WC_Order( $id ); - $schema = $this->get_item_schema(); - $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - - // Handle all writable props - foreach ( $data_keys as $key ) { - $value = $request[ $key ]; - - if ( ! is_null( $value ) ) { - switch ( $key ) { - case 'billing' : - case 'shipping' : - $this->update_address( $order, $value, $key ); - break; - case 'line_items' : - case 'shipping_lines' : - case 'fee_lines' : - case 'coupon_lines' : - if ( is_array( $value ) ) { - foreach ( $value as $item ) { - if ( is_array( $item ) ) { - if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { - $order->remove_item( $item['id'] ); - } else { - $this->set_item( $order, $key, $item ); - } - } - } - } - break; - default : - if ( is_callable( array( $order, "set_{$key}" ) ) ) { - $order->{"set_{$key}"}( $value ); - } - break; - } - } - } - - /** - * Filter the data for the insert. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. - * - * @param WC_Order $order The order object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $order, $request ); - } - - /** - * Create base WC Order object. - * @deprecated 3.0.0 - * @param array $data - * @return WC_Order - */ - protected function create_base_order( $data ) { - return wc_create_order( $data ); - } - - /** - * Only return writable props from schema. - * @param array $schema - * @return bool - */ - protected function filter_writable_props( $schema ) { - return empty( $schema['readonly'] ); - } - - /** - * Create order. - * - * @param WP_REST_Request $request Full details about the request. - * @return int|WP_Error - */ - protected function create_order( $request ) { - try { - // Make sure customer exists. - if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] && false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); - } - - // Make sure customer is part of blog. - if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { - add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); - } - - $order = $this->prepare_item_for_database( $request ); - $order->set_created_via( 'rest-api' ); - $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); - $order->calculate_totals(); - $order->save(); - - // Handle set paid. - if ( true === $request['set_paid'] ) { - $order->payment_complete( $request['transaction_id'] ); - } - - return $order->get_id(); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Update order. - * - * @param WP_REST_Request $request Full details about the request. - * @return int|WP_Error - */ - protected function update_order( $request ) { - try { - $order = $this->prepare_item_for_database( $request ); - $order->save(); - - // Handle set paid. - if ( $order->needs_payment() && true === $request['set_paid'] ) { - $order->payment_complete( $request['transaction_id'] ); - } - - // If items have changed, recalculate order totals. - if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { - $order->calculate_totals( true ); - } - - return $order->get_id(); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Update address. - * - * @param WC_Order $order - * @param array $posted - * @param string $type - */ - protected function update_address( $order, $posted, $type = 'billing' ) { - foreach ( $posted as $key => $value ) { - if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { - $order->{"set_{$type}_{$key}"}( $value ); - } - } - } - - /** - * Gets the product ID from the SKU or posted ID. - * - * @throws WC_REST_Exception When SKU or ID is not valid. - * @param array $posted Request data. - * @param string $action 'create' to add line item or 'update' to update it. - * @return int - */ - protected function get_product_id( $posted, $action = 'create' ) { - if ( ! empty( $posted['sku'] ) ) { - $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); - } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { - $product_id = (int) $posted['product_id']; - } elseif ( ! empty( $posted['variation_id'] ) ) { - $product_id = (int) $posted['variation_id']; - } elseif ( 'update' === $action ) { - $product_id = 0; - } else { - throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); - } - return $product_id; - } - - /** - * Maybe set an item prop if the value was posted. - * @param WC_Order_Item $item - * @param string $prop - * @param array $posted Request data. - */ - protected function maybe_set_item_prop( $item, $prop, $posted ) { - if ( isset( $posted[ $prop ] ) ) { - $item->{"set_$prop"}( $posted[ $prop ] ); - } - } - - /** - * Maybe set item props if the values were posted. - * @param WC_Order_Item $item - * @param string[] $props - * @param array $posted Request data. - */ - protected function maybe_set_item_props( $item, $props, $posted ) { - foreach ( $props as $prop ) { - $this->maybe_set_item_prop( $item, $prop, $posted ); - } - } - - /** - * Create or update a line item. - * - * @param array $posted Line item data. - * @param string $action 'create' to add line item or 'update' to update it. - * - * @return WC_Order_Item_Product - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_line_items( $posted, $action = 'create' ) { - $item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ); - $product = wc_get_product( $this->get_product_id( $posted, $action ) ); - - if ( $product && $product !== $item->get_product() ) { - $item->set_product( $product ); - - if ( 'create' === $action ) { - $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; - $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); - $item->set_total( $total ); - $item->set_subtotal( $total ); - } - } - - $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); - - return $item; - } - - /** - * Create or update an order shipping method. - * - * @param $posted $shipping Item data. - * @param string $action 'create' to add shipping or 'update' to update it. - * - * @return WC_Order_Item_Shipping - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_shipping_lines( $posted, $action ) { - $item = new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ); - - if ( 'create' === $action ) { - if ( empty( $posted['method_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce-rest-api' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); - - return $item; - } - - /** - * Create or update an order fee. - * - * @param array $posted Item data. - * @param string $action 'create' to add fee or 'update' to update it. - * - * @return WC_Order_Item_Fee - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_fee_lines( $posted, $action ) { - $item = new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ); - - if ( 'create' === $action ) { - if ( empty( $posted['name'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce-rest-api' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); - - return $item; - } - - /** - * Create or update an order coupon. - * - * @param array $posted Item data. - * @param string $action 'create' to add coupon or 'update' to update it. - * - * @return WC_Order_Item_Coupon - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_coupon_lines( $posted, $action ) { - $item = new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ); - - if ( 'create' === $action ) { - if ( empty( $posted['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); - - return $item; - } - - /** - * Wrapper method to create/update order items. - * When updating, the item ID provided is checked to ensure it is associated - * with the order. - * - * @param WC_Order $order order - * @param string $item_type - * @param array $posted item provided in the request body - * @throws WC_REST_Exception If item ID is not associated with order - */ - protected function set_item( $order, $item_type, $posted ) { - global $wpdb; - - if ( ! empty( $posted['id'] ) ) { - $action = 'update'; - } else { - $action = 'create'; - } - - $method = 'prepare_' . $item_type; - - // Verify provided line item ID is associated with order. - if ( 'update' === $action ) { - $result = $wpdb->get_row( - $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d", - absint( $posted['id'] ), - absint( $order->get_id() ) - ) ); - if ( is_null( $result ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce-rest-api' ), 400 ); - } - } - - // Prepare item data - $item = $this->$method( $posted, $action ); - - /** - * Action hook to adjust item before save. - * @since 3.0.0 - */ - do_action( 'woocommerce_rest_set_order_item', $item, $posted ); - - // Save or add to order - if ( 'create' === $action ) { - $order->add_item( $item ); - } else { - $item->save(); - } - } - - /** - * Helper method to check if the resource ID associated with the provided item is null. - * Items can be deleted by setting the resource ID to null. - * - * @param array $item Item provided in the request body. - * @return bool True if the item resource ID is null, false otherwise. - */ - protected function item_is_null( $item ) { - $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); - - foreach ( $keys as $key ) { - if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { - return true; - } - } - - return false; - } - - /** - * Create a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $order_id = $this->create_order( $request ); - if ( is_wp_error( $order_id ) ) { - return $order_id; - } - - $post = get_post( $order_id ); - $this->update_additional_fields_for_object( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); - - return $response; - } - - /** - * Update a single order. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - try { - $post_id = (int) $request['id']; - - if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $order_id = $this->update_order( $request ); - if ( is_wp_error( $order_id ) ) { - return $order_id; - } - - $post = get_post( $order_id ); - $this->update_additional_fields_for_object( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - return rest_ensure_response( $response ); - - } catch ( Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Get order statuses without prefixes. - * @return array - */ - protected function get_order_statuses() { - $order_statuses = array(); - - foreach ( array_keys( wc_get_order_statuses() ) as $status ) { - $order_statuses[] = str_replace( 'wc-', '', $status ); - } - - return $order_statuses; - } - - /** - * Get the Order's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'parent_id' => array( - 'description' => __( 'Parent order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Order status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'pending', - 'enum' => $this->get_order_statuses(), - 'context' => array( 'view', 'edit' ), - ), - 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'number' => array( - 'description' => __( 'Order number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'currency' => array( - 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => get_woocommerce_currency(), - 'enum' => array_keys( get_woocommerce_currencies() ), - 'context' => array( 'view', 'edit' ), - ), - 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order was created, as GMT.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => 0, - 'context' => array( 'view', 'edit' ), - ), - 'discount_total' => array( - 'description' => __( 'Total discount amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'discount_tax' => array( - 'description' => __( 'Total discount tax amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_total' => array( - 'description' => __( 'Total shipping amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_tax' => array( - 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'cart_tax' => array( - 'description' => __( 'Sum of line item taxes only.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Grand total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Sum of all taxes.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'billing' => array( - 'description' => __( 'Billing address.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping' => array( - 'description' => __( 'Shipping address.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'payment_method' => array( - 'description' => __( 'Payment method ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'payment_method_title' => array( - 'description' => __( 'Payment method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'edit' ), - ), - 'transaction_id' => array( - 'description' => __( 'Unique transaction ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_paid' => array( - 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'cart_hash' => array( - 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'meta' => array( - 'description' => __( 'Line item meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'Meta label.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ), - ), - ), - 'tax_lines' => array( - 'description' => __( 'Tax lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rate_code' => array( - 'description' => __( 'Tax rate code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'Tax rate label.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'compound' => array( - 'description' => __( 'Show if is a compound tax rate.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tax_total' => array( - 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_tax_total' => array( - 'description' => __( 'Shipping tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'shipping_lines' => array( - 'description' => __( 'Shipping lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_title' => array( - 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ), - ), - ), - 'fee_lines' => array( - 'description' => __( 'Fee lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class of fee.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status of fee.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'taxable', 'none' ), - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ), - ), - ), - 'coupon_lines' => array( - 'description' => __( 'Coupons line data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'discount' => array( - 'description' => __( 'Discount total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'discount_tax' => array( - 'description' => __( 'Discount total tax.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'refunds' => array( - 'description' => __( 'List of refunds.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Refund ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reason' => array( - 'description' => __( 'Refund reason.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Refund total.', 'woocommerce-rest-api' ), - 'type' => 'string', - '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 = parent::get_collection_params(); - - $params['status'] = array( - 'default' => 'any', - 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_merge( array( 'any' ), $this->get_order_statuses() ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['customer'] = array( - 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['product'] = array( - 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['dp'] = array( - 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php deleted file mode 100644 index 361febd1dcf..00000000000 --- a/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php +++ /dev/null @@ -1,241 +0,0 @@ -/terms endpoint. - * - * @author WooThemes - * @category API - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * REST API Product Attribute Terms controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Terms_Controller - */ -class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'products/attributes/(?P[\d]+)/terms'; - - /** - * Register the routes for terms. - */ - public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, - array( - 'args' => array( - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'name' => array( - 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), - 'required' => true, - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - )); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - 'args' => array( - 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Prepare a single product attribute term output for response. - * - * @param WP_Term $item Term object. - * @param WP_REST_Request $request - * @return WP_REST_Response $response - */ - public function prepare_item_for_response( $item, $request ) { - // Get term order. - $menu_order = get_term_meta( $item->term_id, 'order_' . $this->taxonomy, true ); - - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'description' => $item->description, - 'menu_order' => (int) $menu_order, - 'count' => (int) $item->count, - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); - } - - /** - * Update term meta fields. - * - * @param WP_Term $term - * @param WP_REST_Request $request - * @return bool|WP_Error - */ - protected function update_term_meta_fields( $term, $request ) { - $id = (int) $term->term_id; - - update_term_meta( $id, 'order_' . $this->taxonomy, $request['menu_order'] ); - - return true; - } - - /** - * Get the Attribute Term's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_attribute_term', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php deleted file mode 100644 index 88e67708da9..00000000000 --- a/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php +++ /dev/null @@ -1,592 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'name' => array( - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'required' => true, - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - )); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => true, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Check if a given request has access to read the attributes. - * - * @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( 'attributes', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create a attribute. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'attributes', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a attribute. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update a attribute. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'attributes', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete a attribute. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'attributes', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all attributes. - * - * @param WP_REST_Request $request - * @return array - */ - public function get_items( $request ) { - $attributes = wc_get_attribute_taxonomies(); - $data = array(); - foreach ( $attributes as $attribute_obj ) { - $attribute = $this->prepare_item_for_response( $attribute_obj, $request ); - $attribute = $this->prepare_response_for_collection( $attribute ); - $data[] = $attribute; - } - - $response = rest_ensure_response( $data ); - - // This API call always returns all product attributes due to retrieval from the object cache. - $response->header( 'X-WP-Total', count( $data ) ); - $response->header( 'X-WP-TotalPages', 1 ); - - return $response; - } - - /** - * Create a single attribute. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function create_item( $request ) { - global $wpdb; - - $id = wc_create_attribute( array( - 'name' => $request['name'], - 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), - 'type' => ! empty( $request['type'] ) ? $request['type'] : 'select', - 'order_by' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', - 'has_archives' => true === $request['has_archives'], - ) ); - - // Checks for errors. - if ( is_wp_error( $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', $id->get_error_message(), array( 'status' => 400 ) ); - } - - $attribute = $this->get_attribute( $id ); - - if ( is_wp_error( $attribute ) ) { - return $attribute; - } - - $this->update_additional_fields_for_object( $attribute, $request ); - - /** - * Fires after a single product attribute is created or updated via the REST API. - * - * @param stdObject $attribute Inserted attribute object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating attribute, false when updating. - */ - do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $attribute, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( '/' . $this->namespace . '/' . $this->rest_base . '/' . $attribute->attribute_id ) ); - - return $response; - } - - /** - * Get a single attribute. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function get_item( $request ) { - $attribute = $this->get_attribute( (int) $request['id'] ); - - if ( is_wp_error( $attribute ) ) { - return $attribute; - } - - $response = $this->prepare_item_for_response( $attribute, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Update a single term from a taxonomy. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function update_item( $request ) { - global $wpdb; - - $id = (int) $request['id']; - $edited = wc_update_attribute( $id, array( - 'name' => $request['name'], - 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), - 'type' => $request['type'], - 'order_by' => $request['order_by'], - 'has_archives' => $request['has_archives'], - ) ); - - // Checks for errors. - if ( is_wp_error( $edited ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', $edited->get_error_message(), array( 'status' => 400 ) ); - } - - $attribute = $this->get_attribute( $id ); - - if ( is_wp_error( $attribute ) ) { - return $attribute; - } - - $this->update_additional_fields_for_object( $attribute, $request ); - - /** - * Fires after a single product attribute is created or updated via the REST API. - * - * @param stdObject $attribute Inserted attribute object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating attribute, false when updating. - */ - do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $attribute, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Delete a single attribute. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error - */ - public function delete_item( $request ) { - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $attribute = $this->get_attribute( (int) $request['id'] ); - - if ( is_wp_error( $attribute ) ) { - return $attribute; - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $attribute, $request ); - - $deleted = wc_delete_attribute( $attribute->attribute_id ); - - if ( false === $deleted ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a single attribute is deleted via the REST API. - * - * @param stdObject $attribute The deleted attribute. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_product_attribute', $attribute, $response, $request ); - - return $response; - } - - /** - * Prepare a single product attribute output for response. - * - * @param obj $item Term object. - * @param WP_REST_Request $request - * @return WP_REST_Response $response - */ - public function prepare_item_for_response( $item, $request ) { - $data = array( - 'id' => (int) $item->attribute_id, - 'name' => $item->attribute_label, - 'slug' => wc_attribute_taxonomy_name( $item->attribute_name ), - 'type' => $item->attribute_type, - 'order_by' => $item->attribute_orderby, - 'has_archives' => (bool) $item->attribute_public, - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item ) ); - - /** - * Filter a attribute item returned from the API. - * - * Allows modification of the product attribute data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param object $item The original attribute object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_product_attribute', $response, $item, $request ); - } - - /** - * Prepare links for the request. - * - * @param object $attribute Attribute object. - * @return array Links for the given attribute. - */ - protected function prepare_links( $attribute ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - $links = array( - 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $attribute->attribute_id ), - ), - 'collection' => array( - 'href' => rest_url( $base ), - ), - ); - - return $links; - } - - /** - * Get the Attribute's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_attribute', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'type' => array( - 'description' => __( 'Type of attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'select', - 'enum' => array_keys( wc_get_attribute_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'order_by' => array( - 'description' => __( 'Default sort order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'menu_order', - 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ), - 'context' => array( 'view', 'edit' ), - ), - 'has_archives' => array( - 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - 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; - } - - /** - * Get attribute name. - * - * @param WP_REST_Request $request Full details about the request. - * @return string - */ - protected function get_taxonomy( $request ) { - if ( '' !== $this->attribute ) { - return $this->attribute; - } - - if ( $request['id'] ) { - $name = wc_attribute_taxonomy_name_by_id( (int) $request['id'] ); - - $this->attribute = $name; - } - - return $this->attribute; - } - - /** - * Get attribute data. - * - * @param int $id Attribute ID. - * @return stdClass|WP_Error - */ - protected function get_attribute( $id ) { - global $wpdb; - - $attribute = $wpdb->get_row( $wpdb->prepare( " - SELECT * - FROM {$wpdb->prefix}woocommerce_attribute_taxonomies - WHERE attribute_id = %d - ", $id ) ); - - if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { - return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - return $attribute; - } - - /** - * Validate attribute slug. - * - * @deprecated 3.2.0 - * @param string $slug - * @param bool $new_data - * @return bool|WP_Error - */ - protected function validate_attribute_slug( $slug, $new_data = true ) { - if ( strlen( $slug ) >= 28 ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); - } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); - } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); - } - - return true; - } - - /** - * Schedule to flush rewrite rules. - * - * @deprecated 3.2.0 - * @since 3.0.0 - */ - protected function flush_rewrite_rules() { - wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php deleted file mode 100644 index 956d5cd43b3..00000000000 --- a/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php +++ /dev/null @@ -1,271 +0,0 @@ -term_id, 'display_type', true ); - - // Get category order. - $menu_order = get_term_meta( $item->term_id, 'order', true ); - - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'parent' => (int) $item->parent, - 'description' => $item->description, - 'display' => $display_type ? $display_type : 'default', - 'image' => null, - 'menu_order' => (int) $menu_order, - 'count' => (int) $item->count, - ); - - // Get category image. - $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); - if ( $image_id ) { - $attachment = get_post( $image_id ); - - $data['image'] = array( - 'id' => (int) $image_id, - 'date_created' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), - 'src' => wp_get_attachment_url( $image_id ), - 'title' => get_the_title( $attachment ), - 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), - ); - } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); - } - - /** - * Update term meta fields. - * - * @param WP_Term $term Term object. - * @param WP_REST_Request $request Request instance. - * @return bool|WP_Error - */ - protected function update_term_meta_fields( $term, $request ) { - $id = (int) $term->term_id; - - if ( isset( $request['display'] ) ) { - update_term_meta( $id, 'display_type', 'default' === $request['display'] ? '' : $request['display'] ); - } - - if ( isset( $request['menu_order'] ) ) { - update_term_meta( $id, 'order', $request['menu_order'] ); - } - - if ( isset( $request['image'] ) ) { - if ( empty( $request['image']['id'] ) && ! empty( $request['image']['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $request['image']['src'] ) ); - - if ( is_wp_error( $upload ) ) { - return $upload; - } - - $image_id = wc_rest_set_uploaded_image_as_attachment( $upload ); - } else { - $image_id = isset( $request['image']['id'] ) ? absint( $request['image']['id'] ) : 0; - } - - // Check if image_id is a valid image attachment before updating the term meta. - if ( $image_id && wp_attachment_is_image( $image_id ) ) { - update_term_meta( $id, 'thumbnail_id', $image_id ); - - // Set the image alt. - if ( ! empty( $request['image']['alt'] ) ) { - update_post_meta( $image_id, '_wp_attachment_image_alt', wc_clean( $request['image']['alt'] ) ); - } - - // Set the image title. - if ( ! empty( $request['image']['title'] ) ) { - wp_update_post( array( - 'ID' => $image_id, - 'post_title' => wc_clean( $request['image']['title'] ), - ) ); - } - } else { - delete_term_meta( $id, 'thumbnail_id' ); - } - } - - return true; - } - - /** - * Get the Category schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'default', - 'enum' => array( 'default', 'products', 'subcategories', 'both' ), - 'context' => array( 'view', 'edit' ), - ), - 'image' => array( - 'description' => __( 'Image data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'title' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php deleted file mode 100644 index e4d9b93075b..00000000000 --- a/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php +++ /dev/null @@ -1,578 +0,0 @@ -/reviews. - * - * @author WooThemes - * @category API - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * REST API Product Reviews Controller Class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Controller - */ -class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'products/(?P[\d]+)/reviews'; - - /** - * Register the routes for product reviews. - */ - public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'review' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce-rest-api' ), - ), - 'name' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce-rest-api' ), - ), - 'email' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce-rest-api' ), - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read webhook deliveries. - * - * @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_post_permissions( 'product', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $post = get_post( (int) $request['product_id'] ); - - if ( $post && ! wc_rest_check_post_permissions( 'product', 'read', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create a new product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - $post = get_post( (int) $request['product_id'] ); - if ( $post && ! wc_rest_check_post_permissions( 'product', 'create', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to update a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $post = get_post( (int) $request['product_id'] ); - if ( $post && ! wc_rest_check_post_permissions( 'product', 'edit', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to delete a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $post = get_post( (int) $request['product_id'] ); - if ( $post && ! wc_rest_check_post_permissions( 'product', 'delete', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Get all reviews from a product. - * - * @param WP_REST_Request $request - * - * @return array|WP_Error - */ - public function get_items( $request ) { - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $reviews = get_approved_comments( $product_id ); - $data = array(); - foreach ( $reviews as $review_data ) { - $review = $this->prepare_item_for_response( $review_data, $request ); - $review = $this->prepare_response_for_collection( $review ); - $data[] = $review; - } - - return rest_ensure_response( $data ); - } - - /** - * Get a single product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $review = get_comment( $id ); - - if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $delivery = $this->prepare_item_for_response( $review, $request ); - $response = rest_ensure_response( $delivery ); - - return $response; - } - - - /** - * Create a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $prepared_review = $this->prepare_item_for_database( $request ); - - /** - * Filter a product review (comment) before it is inserted via the REST API. - * - * Allows modification of the comment right before it is inserted via `wp_insert_comment`. - * - * @param array $prepared_review The prepared comment data for `wp_insert_comment`. - * @param WP_REST_Request $request Request used to insert the comment. - */ - $prepared_review = apply_filters( 'rest_pre_insert_product_review', $prepared_review, $request ); - - $product_review_id = wp_insert_comment( $prepared_review ); - if ( ! $product_review_id ) { - return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); - - $product_review = get_comment( $product_review_id ); - $this->update_additional_fields_for_object( $product_review, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Comment $product_review Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $product_review, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $product_review_id ) ) ); - - return $response; - } - - /** - * Update a single product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $product_review_id = (int) $request['id']; - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $review = get_comment( $product_review_id ); - - if ( empty( $product_review_id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $prepared_review = $this->prepare_item_for_database( $request ); - - $updated = wp_update_comment( $prepared_review ); - if ( 0 === $updated ) { - return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - if ( ! empty( $request['rating'] ) ) { - update_comment_meta( $product_review_id, 'rating', $request['rating'] ); - } - - $product_review = get_comment( $product_review_id ); - $this->update_additional_fields_for_object( $product_review, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Comment $comment Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $product_review, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Delete a product review. - * - * @param WP_REST_Request $request Full details about the request - * - * @return bool|WP_Error|WP_REST_Response - */ - public function delete_item( $request ) { - $product_review_id = absint( is_array( $request['id'] ) ? $request['id']['id'] : $request['id'] ); - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - $product_review = get_comment( $product_review_id ); - if ( empty( $product_review_id ) || empty( $product_review->comment_ID ) || empty( $product_review->comment_post_ID ) ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - /** - * Filter whether a product review is trashable. - * - * Return false to disable trash support for the product review. - * - * @param boolean $supports_trash Whether the object supports trashing. - * @param WP_Post $product_review The object being considered for trashing support. - */ - $supports_trash = apply_filters( 'rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $product_review ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $product_review, $request ); - - if ( $force ) { - $result = wp_delete_comment( $product_review_id, true ); - } else { - if ( ! $supports_trash ) { - return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - if ( 'trash' === $product_review->comment_approved ) { - return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce-rest-api' ), array( 'status' => 410 ) ); - } - - $result = wp_trash_comment( $product_review->comment_ID ); - } - - if ( ! $result ) { - return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a product review is deleted via the REST API. - * - * @param object $product_review The deleted item. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'rest_delete_product_review', $product_review, $response, $request ); - - return $response; - } - - /** - * Prepare a single product review output for response. - * - * @param WP_Comment $review Product review object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $review, $request ) { - $data = array( - 'id' => (int) $review->comment_ID, - 'date_created' => wc_rest_prepare_date_response( $review->comment_date_gmt ), - 'review' => $review->comment_content, - 'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ), - 'name' => $review->comment_author, - 'email' => $review->comment_author_email, - 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), - ); - - $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( $review, $request ) ); - - /** - * Filter product reviews object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_Comment $review Product review object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); - } - - /** - * Prepare a single product review to be inserted into the database. - * - * @param WP_REST_Request $request Request object. - * @return array|WP_Error $prepared_review - */ - protected function prepare_item_for_database( $request ) { - $prepared_review = array( 'comment_approved' => 1, 'comment_type' => 'review' ); - - if ( isset( $request['id'] ) ) { - $prepared_review['comment_ID'] = (int) $request['id']; - } - - if ( isset( $request['review'] ) ) { - $prepared_review['comment_content'] = $request['review']; - } - - if ( isset( $request['product_id'] ) ) { - $prepared_review['comment_post_ID'] = (int) $request['product_id']; - } - - if ( isset( $request['name'] ) ) { - $prepared_review['comment_author'] = $request['name']; - } - - if ( isset( $request['email'] ) ) { - $prepared_review['comment_author_email'] = $request['email']; - } - - if ( isset( $request['date_created'] ) ) { - $prepared_review['comment_date'] = $request['date_created']; - } - - if ( isset( $request['date_created_gmt'] ) ) { - $prepared_review['comment_date_gmt'] = $request['date_created_gmt']; - } - - return apply_filters( 'rest_preprocess_product_review', $prepared_review, $request ); - } - - /** - * Prepare links for the request. - * - * @param WP_Comment $review Product review object. - * @param WP_REST_Request $request Request object. - * @return array Links for the given product review. - */ - protected function prepare_links( $review, $request ) { - $product_id = (int) $request['product_id']; - $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $review->comment_ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Product Review's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_review', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), - '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() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php deleted file mode 100644 index 92ab292f1a0..00000000000 --- a/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php +++ /dev/null @@ -1,134 +0,0 @@ - (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'description' => $item->description, - 'count' => (int) $item->count, - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); - } - - /** - * Get the Shipping Class schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Shipping class name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php b/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php deleted file mode 100644 index c4e587b44da..00000000000 --- a/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php +++ /dev/null @@ -1,134 +0,0 @@ - (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'description' => $item->description, - 'count' => (int) $item->count, - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); - } - - /** - * Get the Tag's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-products-v1-controller.php b/src/Controllers/Version1/class-wc-rest-products-v1-controller.php deleted file mode 100644 index bf8629b027d..00000000000 --- a/src/Controllers/Version1/class-wc-rest-products-v1-controller.php +++ /dev/null @@ -1,2641 +0,0 @@ -post_type}_query", array( $this, 'query_args' ), 10, 2 ); - add_action( "woocommerce_rest_insert_{$this->post_type}", array( $this, 'clear_transients' ) ); - } - - /** - * Register the routes for products. - */ - public function register_routes() { - register_rest_route( $this->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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Get post types. - * - * @return array - */ - protected function get_post_types() { - return array( 'product', 'product_variation' ); - } - - /** - * Query args. - * - * @param array $args Request args. - * @param WP_REST_Request $request Request data. - * @return array - */ - public function query_args( $args, $request ) { - // Set post_status. - $args['post_status'] = $request['status']; - - // Taxonomy query to filter products by type, category, - // tag, shipping class, and attribute. - $tax_query = array(); - - // Map between taxonomy name and arg's key. - $taxonomies = array( - 'product_cat' => 'category', - 'product_tag' => 'tag', - 'product_shipping_class' => 'shipping_class', - ); - - // Set tax_query for each passed arg. - foreach ( $taxonomies as $taxonomy => $key ) { - if ( ! empty( $request[ $key ] ) && is_array( $request[ $key ] ) ) { - $request[ $key ] = array_filter( $request[ $key ] ); - } - - if ( ! empty( $request[ $key ] ) ) { - $tax_query[] = array( - 'taxonomy' => $taxonomy, - 'field' => 'term_id', - 'terms' => $request[ $key ], - ); - } - } - - // Filter product type by slug. - if ( ! empty( $request['type'] ) ) { - $tax_query[] = array( - 'taxonomy' => 'product_type', - 'field' => 'slug', - 'terms' => $request['type'], - ); - } - - // Filter by attribute and term. - if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { - if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { - $tax_query[] = array( - 'taxonomy' => $request['attribute'], - 'field' => 'term_id', - 'terms' => $request['attribute_term'], - ); - } - } - - if ( ! empty( $tax_query ) ) { - $args['tax_query'] = $tax_query; - } - - // Filter by sku. - if ( ! empty( $request['sku'] ) ) { - $skus = explode( ',', $request['sku'] ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $request['sku']; - } - - $args['meta_query'] = $this->add_meta_query( $args, array( - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', - ) ); - } - - // Apply all WP_Query filters again. - if ( is_array( $request['filter'] ) ) { - $args = array_merge( $args, $request['filter'] ); - unset( $args['filter'] ); - } - - // Force the post_type argument, since it's not a user input variable. - if ( ! empty( $request['sku'] ) ) { - $args['post_type'] = array( 'product', 'product_variation' ); - } else { - $args['post_type'] = $this->post_type; - } - - return $args; - } - - /** - * Get the downloads for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * @return array - */ - protected function get_downloads( $product ) { - $downloads = array(); - - if ( $product->is_downloadable() ) { - foreach ( $product->get_downloads() as $file_id => $file ) { - $downloads[] = array( - 'id' => $file_id, // MD5 hash. - 'name' => $file['name'], - 'file' => $file['file'], - ); - } - } - - return $downloads; - } - - /** - * Get taxonomy terms. - * - * @param WC_Product $product Product instance. - * @param string $taxonomy Taxonomy slug. - * @return array - */ - protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { - $terms = array(); - - foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { - $terms[] = array( - 'id' => $term->term_id, - 'name' => $term->name, - 'slug' => $term->slug, - ); - } - - return $terms; - } - - /** - * Get the images for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * @return array - */ - protected function get_images( $product ) { - $images = array(); - $attachment_ids = array(); - - // Add featured image. - if ( $product->get_image_id() ) { - $attachment_ids[] = $product->get_image_id(); - } - - // Add gallery images. - $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); - - // Build image data. - foreach ( $attachment_ids as $position => $attachment_id ) { - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - continue; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - continue; - } - - $images[] = array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified_gmt ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - 'position' => (int) $position, - ); - } - - // Set a placeholder image if the product has no images set. - if ( empty( $images ) ) { - $images[] = array( - 'id' => 0, - 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), // Default to now. - 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), - 'src' => wc_placeholder_img_src(), - 'name' => __( 'Placeholder', 'woocommerce-rest-api' ), - 'alt' => __( 'Placeholder', 'woocommerce-rest-api' ), - 'position' => 0, - ); - } - - return $images; - } - - /** - * Get attribute taxonomy label. - * - * @param string $name Taxonomy name. - * @return string - */ - protected function get_attribute_taxonomy_label( $name ) { - $tax = get_taxonomy( $name ); - $labels = get_taxonomy_labels( $tax ); - - return $labels->singular_name; - } - - /** - * Get default attributes. - * - * @param WC_Product $product Product instance. - * @return array - */ - protected function get_default_attributes( $product ) { - $default = array(); - - if ( $product->is_type( 'variable' ) ) { - foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { - if ( 0 === strpos( $key, 'pa_' ) ) { - $default[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $key ), - 'name' => $this->get_attribute_taxonomy_label( $key ), - 'option' => $value, - ); - } else { - $default[] = array( - 'id' => 0, - 'name' => wc_attribute_taxonomy_slug( $key ), - 'option' => $value, - ); - } - } - } - - return $default; - } - - /** - * Get attribute options. - * - * @param int $product_id Product ID. - * @param array $attribute Attribute data. - * @return array - */ - protected function get_attribute_options( $product_id, $attribute ) { - if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { - return wc_get_product_terms( $product_id, $attribute['name'], array( 'fields' => 'names' ) ); - } elseif ( isset( $attribute['value'] ) ) { - return array_map( 'trim', explode( '|', $attribute['value'] ) ); - } - - return array(); - } - - /** - * Get the attributes for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * @return array - */ - protected function get_attributes( $product ) { - $attributes = array(); - - if ( $product->is_type( 'variation' ) ) { - // Variation attributes. - foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { - $name = str_replace( 'attribute_', '', $attribute_name ); - - if ( ! $attribute ) { - continue; - } - - // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. - if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { - $option_term = get_term_by( 'slug', $attribute, $name ); - $attributes[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $name ), - 'name' => $this->get_attribute_taxonomy_label( $name ), - 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, - ); - } else { - $attributes[] = array( - 'id' => 0, - 'name' => $name, - 'option' => $attribute, - ); - } - } - } else { - foreach ( $product->get_attributes() as $attribute ) { - if ( $attribute['is_taxonomy'] ) { - $attributes[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $attribute['name'] ), - 'name' => $this->get_attribute_taxonomy_label( $attribute['name'] ), - 'position' => (int) $attribute['position'], - 'visible' => (bool) $attribute['is_visible'], - 'variation' => (bool) $attribute['is_variation'], - 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), - ); - } else { - $attributes[] = array( - 'id' => 0, - 'name' => $attribute['name'], - 'position' => (int) $attribute['position'], - 'visible' => (bool) $attribute['is_visible'], - 'variation' => (bool) $attribute['is_variation'], - 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), - ); - } - } - } - - return $attributes; - } - - /** - * Get product menu order. - * - * @deprecated 3.0.0 - * @param WC_Product $product Product instance. - * @return int - */ - protected function get_product_menu_order( $product ) { - return $product->get_menu_order(); - } - - /** - * Get product data. - * - * @param WC_Product $product Product instance. - * @return array - */ - protected function get_product_data( $product ) { - $data = array( - 'id' => $product->get_id(), - 'name' => $product->get_name(), - 'slug' => $product->get_slug(), - 'permalink' => $product->get_permalink(), - 'date_created' => wc_rest_prepare_date_response( $product->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified() ), - 'type' => $product->get_type(), - 'status' => $product->get_status(), - 'featured' => $product->is_featured(), - 'catalog_visibility' => $product->get_catalog_visibility(), - 'description' => wpautop( do_shortcode( $product->get_description() ) ), - 'short_description' => apply_filters( 'woocommerce_short_description', $product->get_short_description() ), - 'sku' => $product->get_sku(), - 'price' => $product->get_price(), - 'regular_price' => $product->get_regular_price(), - 'sale_price' => $product->get_sale_price() ? $product->get_sale_price() : '', - 'date_on_sale_from' => $product->get_date_on_sale_from() ? date( 'Y-m-d', $product->get_date_on_sale_from()->getTimestamp() ) : '', - 'date_on_sale_to' => $product->get_date_on_sale_to() ? date( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ) : '', - 'price_html' => $product->get_price_html(), - 'on_sale' => $product->is_on_sale(), - 'purchasable' => $product->is_purchasable(), - 'total_sales' => $product->get_total_sales(), - 'virtual' => $product->is_virtual(), - 'downloadable' => $product->is_downloadable(), - 'downloads' => $this->get_downloads( $product ), - 'download_limit' => $product->get_download_limit(), - 'download_expiry' => $product->get_download_expiry(), - 'download_type' => 'standard', - 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url() : '', - 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text() : '', - 'tax_status' => $product->get_tax_status(), - 'tax_class' => $product->get_tax_class(), - 'manage_stock' => $product->managing_stock(), - 'stock_quantity' => $product->get_stock_quantity(), - 'in_stock' => $product->is_in_stock(), - 'backorders' => $product->get_backorders(), - 'backorders_allowed' => $product->backorders_allowed(), - 'backordered' => $product->is_on_backorder(), - 'sold_individually' => $product->is_sold_individually(), - 'weight' => $product->get_weight(), - 'dimensions' => array( - 'length' => $product->get_length(), - 'width' => $product->get_width(), - 'height' => $product->get_height(), - ), - 'shipping_required' => $product->needs_shipping(), - 'shipping_taxable' => $product->is_shipping_taxable(), - 'shipping_class' => $product->get_shipping_class(), - 'shipping_class_id' => $product->get_shipping_class_id(), - 'reviews_allowed' => $product->get_reviews_allowed(), - 'average_rating' => wc_format_decimal( $product->get_average_rating(), 2 ), - 'rating_count' => $product->get_rating_count(), - 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), - 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids() ), - 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids() ), - 'parent_id' => $product->get_parent_id(), - 'purchase_note' => wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ), - 'categories' => $this->get_taxonomy_terms( $product ), - 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), - 'images' => $this->get_images( $product ), - 'attributes' => $this->get_attributes( $product ), - 'default_attributes' => $this->get_default_attributes( $product ), - 'variations' => array(), - 'grouped_products' => array(), - 'menu_order' => $product->get_menu_order(), - ); - - return $data; - } - - /** - * Get an individual variation's data. - * - * @param WC_Product $product Product instance. - * @return array - */ - protected function get_variation_data( $product ) { - $variations = array(); - - foreach ( $product->get_children() as $child_id ) { - $variation = wc_get_product( $child_id ); - if ( ! $variation || ! $variation->exists() ) { - continue; - } - - $variations[] = array( - 'id' => $variation->get_id(), - 'date_created' => wc_rest_prepare_date_response( $variation->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $variation->get_date_modified() ), - 'permalink' => $variation->get_permalink(), - 'sku' => $variation->get_sku(), - 'price' => $variation->get_price(), - 'regular_price' => $variation->get_regular_price(), - 'sale_price' => $variation->get_sale_price(), - 'date_on_sale_from' => $variation->get_date_on_sale_from() ? date( 'Y-m-d', $variation->get_date_on_sale_from()->getTimestamp() ) : '', - 'date_on_sale_to' => $variation->get_date_on_sale_to() ? date( 'Y-m-d', $variation->get_date_on_sale_to()->getTimestamp() ) : '', - 'on_sale' => $variation->is_on_sale(), - 'purchasable' => $variation->is_purchasable(), - 'visible' => $variation->is_visible(), - 'virtual' => $variation->is_virtual(), - 'downloadable' => $variation->is_downloadable(), - 'downloads' => $this->get_downloads( $variation ), - 'download_limit' => '' !== $variation->get_download_limit() ? (int) $variation->get_download_limit() : -1, - 'download_expiry' => '' !== $variation->get_download_expiry() ? (int) $variation->get_download_expiry() : -1, - 'tax_status' => $variation->get_tax_status(), - 'tax_class' => $variation->get_tax_class(), - 'manage_stock' => $variation->managing_stock(), - 'stock_quantity' => $variation->get_stock_quantity(), - 'in_stock' => $variation->is_in_stock(), - 'backorders' => $variation->get_backorders(), - 'backorders_allowed' => $variation->backorders_allowed(), - 'backordered' => $variation->is_on_backorder(), - 'weight' => $variation->get_weight(), - 'dimensions' => array( - 'length' => $variation->get_length(), - 'width' => $variation->get_width(), - 'height' => $variation->get_height(), - ), - 'shipping_class' => $variation->get_shipping_class(), - 'shipping_class_id' => $variation->get_shipping_class_id(), - 'image' => $this->get_images( $variation ), - 'attributes' => $this->get_attributes( $variation ), - ); - } - - return $variations; - } - - /** - * Prepare a single product output for response. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_item_for_response( $post, $request ) { - $product = wc_get_product( $post ); - $data = $this->get_product_data( $product ); - - // Add variations to variable products. - if ( $product->is_type( 'variable' ) && $product->has_child() ) { - $data['variations'] = $this->get_variation_data( $product ); - } - - // Add grouped products data. - if ( $product->is_type( 'grouped' ) && $product->has_child() ) { - $data['grouped_products'] = $product->get_children(); - } - - $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, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Product $product Product object. - * @param WP_REST_Request $request Request object. - * @return array Links for the given product. - */ - protected function prepare_links( $product, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $product->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - if ( $product->get_parent_id() ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_parent_id() ) ), - ); - } - - return $links; - } - - /** - * Prepare a single product for create or update. - * - * @param WP_REST_Request $request Request object. - * @return WP_Error|stdClass $data Post object. - */ - protected function prepare_item_for_database( $request ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - - // Type is the most important part here because we need to be using the correct class and methods. - if ( isset( $request['type'] ) ) { - $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); - - if ( ! class_exists( $classname ) ) { - $classname = 'WC_Product_Simple'; - } - - $product = new $classname( $id ); - } elseif ( isset( $request['id'] ) ) { - $product = wc_get_product( $id ); - } else { - $product = new WC_Product_Simple(); - } - - // Post title. - if ( isset( $request['name'] ) ) { - $product->set_name( wp_filter_post_kses( $request['name'] ) ); - } - - // Post content. - if ( isset( $request['description'] ) ) { - $product->set_description( wp_filter_post_kses( $request['description'] ) ); - } - - // Post excerpt. - if ( isset( $request['short_description'] ) ) { - $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); - } - - // Post status. - if ( isset( $request['status'] ) ) { - $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); - } - - // Post slug. - if ( isset( $request['slug'] ) ) { - $product->set_slug( $request['slug'] ); - } - - // Menu order. - if ( isset( $request['menu_order'] ) ) { - $product->set_menu_order( $request['menu_order'] ); - } - - // Comment status. - if ( isset( $request['reviews_allowed'] ) ) { - $product->set_reviews_allowed( $request['reviews_allowed'] ); - } - - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for insertion. - * - * @param WC_Product $product An object representing a single item prepared - * for inserting or updating the database. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $product, $request ); - } - - /** - * Create a single product. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $product_id = 0; - - try { - $product_id = $this->save_product( $request ); - $post = get_post( $product_id ); - $this->update_additional_fields_for_object( $post, $request ); - $this->update_post_meta_fields( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post data. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_product', $post, $request, true ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); - - return $response; - } catch ( WC_Data_Exception $e ) { - $this->delete_post( $product_id ); - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - $this->delete_post( $product_id ); - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Update a single product. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $post_id = (int) $request['id']; - - if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - try { - $product_id = $this->save_product( $request ); - $post = get_post( $product_id ); - $this->update_additional_fields_for_object( $post, $request ); - $this->update_post_meta_fields( $post, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post data. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_product', $post, $request, false ); - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - - return rest_ensure_response( $response ); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Saves a product to the database. - * - * @param WP_REST_Request $request Full details about the request. - * @return int - */ - public function save_product( $request ) { - $product = $this->prepare_item_for_database( $request ); - return $product->save(); - } - - /** - * Save product images. - * - * @deprecated 3.0.0 - * @param int $product_id - * @param array $images - * @throws WC_REST_Exception - */ - protected function save_product_images( $product_id, $images ) { - $product = wc_get_product( $product_id ); - - return set_product_images( $product, $images ); - } - - /** - * Set product images. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product $product Product instance. - * @param array $images Images data. - * @return WC_Product - */ - protected function set_product_images( $product, $images ) { - if ( is_array( $images ) ) { - $gallery = array(); - - foreach ( $images as $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { - throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); - } else { - continue; - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); - } - - if ( isset( $image['position'] ) && 0 === absint( $image['position'] ) ) { - $product->set_image_id( $attachment_id ); - } else { - $gallery[] = $attachment_id; - } - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( array( 'ID' => $attachment_id, 'post_title' => $image['name'] ) ); - } - } - - if ( ! empty( $gallery ) ) { - $product->set_gallery_image_ids( $gallery ); - } - } else { - $product->set_image_id( '' ); - $product->set_gallery_image_ids( array() ); - } - - return $product; - } - - /** - * Save product shipping data. - * - * @param WC_Product $product Product instance. - * @param array $data Shipping data. - * @return WC_Product - */ - protected function save_product_shipping_data( $product, $data ) { - // Virtual. - if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { - $product->set_weight( '' ); - $product->set_height( '' ); - $product->set_length( '' ); - $product->set_width( '' ); - } else { - if ( isset( $data['weight'] ) ) { - $product->set_weight( $data['weight'] ); - } - - // Height. - if ( isset( $data['dimensions']['height'] ) ) { - $product->set_height( $data['dimensions']['height'] ); - } - - // Width. - if ( isset( $data['dimensions']['width'] ) ) { - $product->set_width( $data['dimensions']['width'] ); - } - - // Length. - if ( isset( $data['dimensions']['length'] ) ) { - $product->set_length( $data['dimensions']['length'] ); - } - } - - // Shipping class. - if ( isset( $data['shipping_class'] ) ) { - $data_store = $product->get_data_store(); - $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); - $product->set_shipping_class_id( $shipping_class_id ); - } - - return $product; - } - - /** - * Save downloadable files. - * - * @param WC_Product $product Product instance. - * @param array $downloads Downloads data. - * @param int $deprecated Deprecated since 3.0. - * @return WC_Product - */ - protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { - if ( $deprecated ) { - wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); - } - - $files = array(); - foreach ( $downloads as $key => $file ) { - if ( empty( $file['file'] ) ) { - continue; - } - - $download = new WC_Product_Download(); - $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); - $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); - $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); - $files[] = $download; - } - $product->set_downloads( $files ); - - return $product; - } - - /** - * Save taxonomy terms. - * - * @param WC_Product $product Product instance. - * @param array $terms Terms data. - * @param string $taxonomy Taxonomy name. - * @return WC_Product - */ - protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { - $term_ids = wp_list_pluck( $terms, 'id' ); - - if ( 'cat' === $taxonomy ) { - $product->set_category_ids( $term_ids ); - } elseif ( 'tag' === $taxonomy ) { - $product->set_tag_ids( $term_ids ); - } - - return $product; - } - - /** - * Save default attributes. - * - * @since 3.0.0 - * - * @param WC_Product $product Product instance. - * @param WP_REST_Request $request Request data. - * @return WC_Product - */ - protected function save_default_attributes( $product, $request ) { - if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { - $attributes = $product->get_attributes(); - $default_attributes = array(); - - foreach ( $request['default_attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( isset( $attributes[ $attribute_name ] ) ) { - $_attribute = $attributes[ $attribute_name ]; - - if ( $_attribute['is_variation'] ) { - $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( ! empty( $_attribute['is_taxonomy'] ) ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $value = $term->slug; - } else { - $value = sanitize_title( $value ); - } - } - - if ( $value ) { - $default_attributes[ $attribute_name ] = $value; - } - } - } - } - - $product->set_default_attributes( $default_attributes ); - } - - return $product; - } - - /** - * Save product meta. - * - * @deprecated 3.0.0 - * @param WC_Product $product - * @param WP_REST_Request $request - * @return bool - * @throws WC_REST_Exception - */ - protected function save_product_meta( $product, $request ) { - $product = $this->set_product_meta( $product, $request ); - $product->save(); - - return true; - } - - /** - * Set product meta. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product $product Product instance. - * @param WP_REST_Request $request Request data. - * @return WC_Product - */ - protected function set_product_meta( $product, $request ) { - // Virtual. - if ( isset( $request['virtual'] ) ) { - $product->set_virtual( $request['virtual'] ); - } - - // Tax status. - if ( isset( $request['tax_status'] ) ) { - $product->set_tax_status( $request['tax_status'] ); - } - - // Tax Class. - if ( isset( $request['tax_class'] ) ) { - $product->set_tax_class( $request['tax_class'] ); - } - - // Catalog Visibility. - if ( isset( $request['catalog_visibility'] ) ) { - $product->set_catalog_visibility( $request['catalog_visibility'] ); - } - - // Purchase Note. - if ( isset( $request['purchase_note'] ) ) { - $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); - } - - // Featured Product. - if ( isset( $request['featured'] ) ) { - $product->set_featured( $request['featured'] ); - } - - // Shipping data. - $product = $this->save_product_shipping_data( $product, $request ); - - // SKU. - if ( isset( $request['sku'] ) ) { - $product->set_sku( wc_clean( $request['sku'] ) ); - } - - // Attributes. - if ( isset( $request['attributes'] ) ) { - $attributes = array(); - - foreach ( $request['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = wc_clean( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( $attribute_id ) { - - if ( isset( $attribute['options'] ) ) { - $options = $attribute['options']; - - if ( ! is_array( $attribute['options'] ) ) { - // Text based attributes - Posted values are term names. - $options = explode( WC_DELIMITER, $options ); - } - - $values = array_map( 'wc_sanitize_term_text_based', $options ); - $values = array_filter( $values, 'strlen' ); - } else { - $values = array(); - } - - if ( ! empty( $values ) ) { - // Add attribute to array, but don't set values. - $attribute_object = new WC_Product_Attribute(); - $attribute_object->set_id( $attribute_id ); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } elseif ( isset( $attribute['options'] ) ) { - // Custom attribute - Add attribute to array and set the values. - if ( is_array( $attribute['options'] ) ) { - $values = $attribute['options']; - } else { - $values = explode( WC_DELIMITER, $attribute['options'] ); - } - $attribute_object = new WC_Product_Attribute(); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } - $product->set_attributes( $attributes ); - } - - // Sales and prices. - if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { - $product->set_regular_price( '' ); - $product->set_sale_price( '' ); - $product->set_date_on_sale_to( '' ); - $product->set_date_on_sale_from( '' ); - $product->set_price( '' ); - } else { - // Regular Price. - if ( isset( $request['regular_price'] ) ) { - $product->set_regular_price( $request['regular_price'] ); - } - - // Sale Price. - if ( isset( $request['sale_price'] ) ) { - $product->set_sale_price( $request['sale_price'] ); - } - - if ( isset( $request['date_on_sale_from'] ) ) { - $product->set_date_on_sale_from( $request['date_on_sale_from'] ); - } - - if ( isset( $request['date_on_sale_to'] ) ) { - $product->set_date_on_sale_to( $request['date_on_sale_to'] ); - } - } - - // Product parent ID for groups. - if ( isset( $request['parent_id'] ) ) { - $product->set_parent_id( $request['parent_id'] ); - } - - // Sold individually. - if ( isset( $request['sold_individually'] ) ) { - $product->set_sold_individually( $request['sold_individually'] ); - } - - // Stock status. - if ( isset( $request['in_stock'] ) ) { - $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; - } else { - $stock_status = $product->get_stock_status(); - } - - // Stock data. - if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { - // Manage stock. - if ( isset( $request['manage_stock'] ) ) { - $product->set_manage_stock( $request['manage_stock'] ); - } - - // Backorders. - if ( isset( $request['backorders'] ) ) { - $product->set_backorders( $request['backorders'] ); - } - - if ( $product->is_type( 'grouped' ) ) { - $product->set_manage_stock( 'no' ); - $product->set_backorders( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( $stock_status ); - } elseif ( $product->is_type( 'external' ) ) { - $product->set_manage_stock( 'no' ); - $product->set_backorders( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( 'instock' ); - } elseif ( $product->get_manage_stock() ) { - // Stock status is always determined by children so sync later. - if ( ! $product->is_type( 'variable' ) ) { - $product->set_stock_status( $stock_status ); - } - - // Stock quantity. - if ( isset( $request['stock_quantity'] ) ) { - $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); - } elseif ( isset( $request['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); - $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); - } - } else { - // Don't manage stock. - $product->set_manage_stock( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( $stock_status ); - } - } elseif ( ! $product->is_type( 'variable' ) ) { - $product->set_stock_status( $stock_status ); - } - - // Upsells. - if ( isset( $request['upsell_ids'] ) ) { - $upsells = array(); - $ids = $request['upsell_ids']; - - if ( ! empty( $ids ) ) { - foreach ( $ids as $id ) { - if ( $id && $id > 0 ) { - $upsells[] = $id; - } - } - } - - $product->set_upsell_ids( $upsells ); - } - - // Cross sells. - if ( isset( $request['cross_sell_ids'] ) ) { - $crosssells = array(); - $ids = $request['cross_sell_ids']; - - if ( ! empty( $ids ) ) { - foreach ( $ids as $id ) { - if ( $id && $id > 0 ) { - $crosssells[] = $id; - } - } - } - - $product->set_cross_sell_ids( $crosssells ); - } - - // Product categories. - if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { - $product = $this->save_taxonomy_terms( $product, $request['categories'] ); - } - - // Product tags. - if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { - $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); - } - - // Downloadable. - if ( isset( $request['downloadable'] ) ) { - $product->set_downloadable( $request['downloadable'] ); - } - - // Downloadable options. - if ( $product->get_downloadable() ) { - - // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - $product = $this->save_downloadable_files( $product, $request['downloads'] ); - } - - // Download limit. - if ( isset( $request['download_limit'] ) ) { - $product->set_download_limit( $request['download_limit'] ); - } - - // Download expiry. - if ( isset( $request['download_expiry'] ) ) { - $product->set_download_expiry( $request['download_expiry'] ); - } - } - - // Product url and button text for external products. - if ( $product->is_type( 'external' ) ) { - if ( isset( $request['external_url'] ) ) { - $product->set_product_url( $request['external_url'] ); - } - - if ( isset( $request['button_text'] ) ) { - $product->set_button_text( $request['button_text'] ); - } - } - - // Save default attributes for variable products. - if ( $product->is_type( 'variable' ) ) { - $product = $this->save_default_attributes( $product, $request ); - } - - return $product; - } - - /** - * Save variations. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product $product Product instance. - * @param WP_REST_Request $request Request data. - * @return bool - */ - protected function save_variations_data( $product, $request ) { - foreach ( $request['variations'] as $menu_order => $data ) { - $variation = new WC_Product_Variation( isset( $data['id'] ) ? absint( $data['id'] ) : 0 ); - - // Create initial name and status. - if ( ! $variation->get_slug() ) { - /* translators: 1: variation id 2: product name */ - $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce-rest-api' ), $variation->get_id(), $product->get_name() ) ); - $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); - } - - // Parent ID. - $variation->set_parent_id( $product->get_id() ); - - // Menu order. - $variation->set_menu_order( $menu_order ); - - // Status. - if ( isset( $data['visible'] ) ) { - $variation->set_status( false === $data['visible'] ? 'private' : 'publish' ); - } - - // SKU. - if ( isset( $data['sku'] ) ) { - $variation->set_sku( wc_clean( $data['sku'] ) ); - } - - // Thumbnail. - if ( isset( $data['image'] ) && is_array( $data['image'] ) ) { - $image = $data['image']; - $image = current( $image ); - if ( is_array( $image ) ) { - $image['position'] = 0; - } - - $variation = $this->set_product_images( $variation, array( $image ) ); - } - - // Virtual variation. - if ( isset( $data['virtual'] ) ) { - $variation->set_virtual( $data['virtual'] ); - } - - // Downloadable variation. - if ( isset( $data['downloadable'] ) ) { - $variation->set_downloadable( $data['downloadable'] ); - } - - // Downloads. - if ( $variation->get_downloadable() ) { - // Downloadable files. - if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { - $variation = $this->save_downloadable_files( $variation, $data['downloads'] ); - } - - // Download limit. - if ( isset( $data['download_limit'] ) ) { - $variation->set_download_limit( $data['download_limit'] ); - } - - // Download expiry. - if ( isset( $data['download_expiry'] ) ) { - $variation->set_download_expiry( $data['download_expiry'] ); - } - } - - // Shipping data. - $variation = $this->save_product_shipping_data( $variation, $data ); - - // Stock handling. - if ( isset( $data['manage_stock'] ) ) { - $variation->set_manage_stock( $data['manage_stock'] ); - } - - if ( isset( $data['in_stock'] ) ) { - $variation->set_stock_status( true === $data['in_stock'] ? 'instock' : 'outofstock' ); - } - - if ( isset( $data['backorders'] ) ) { - $variation->set_backorders( $data['backorders'] ); - } - - if ( $variation->get_manage_stock() ) { - if ( isset( $data['stock_quantity'] ) ) { - $variation->set_stock_quantity( $data['stock_quantity'] ); - } elseif ( isset( $data['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $data['inventory_delta'] ); - $variation->set_stock_quantity( $stock_quantity ); - } - } else { - $variation->set_backorders( 'no' ); - $variation->set_stock_quantity( '' ); - } - - // Regular Price. - if ( isset( $data['regular_price'] ) ) { - $variation->set_regular_price( $data['regular_price'] ); - } - - // Sale Price. - if ( isset( $data['sale_price'] ) ) { - $variation->set_sale_price( $data['sale_price'] ); - } - - if ( isset( $data['date_on_sale_from'] ) ) { - $variation->set_date_on_sale_from( $data['date_on_sale_from'] ); - } - - if ( isset( $data['date_on_sale_to'] ) ) { - $variation->set_date_on_sale_to( $data['date_on_sale_to'] ); - } - - // Tax class. - if ( isset( $data['tax_class'] ) ) { - $variation->set_tax_class( $data['tax_class'] ); - } - - // Description. - if ( isset( $data['description'] ) ) { - $variation->set_description( wp_kses_post( $data['description'] ) ); - } - - // Update taxonomies. - if ( isset( $data['attributes'] ) ) { - $attributes = array(); - $parent_attributes = $product->get_attributes(); - - foreach ( $data['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { - continue; - } - - $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); - $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $attribute_value = $term->slug; - } else { - $attribute_value = sanitize_title( $attribute_value ); - } - } - - $attributes[ $attribute_key ] = $attribute_value; - } - - $variation->set_attributes( $attributes ); - } - - $variation->save(); - - do_action( 'woocommerce_rest_save_product_variation', $variation->get_id(), $menu_order, $data ); - } - - return true; - } - - /** - * Add post meta fields. - * - * @param WP_Post $post Post data. - * @param WP_REST_Request $request Request data. - * @return bool|WP_Error - */ - protected function add_post_meta_fields( $post, $request ) { - return $this->update_post_meta_fields( $post, $request ); - } - - /** - * Update post meta fields. - * - * @param WP_Post $post Post data. - * @param WP_REST_Request $request Request data. - * @return bool|WP_Error - */ - protected function update_post_meta_fields( $post, $request ) { - $product = wc_get_product( $post ); - - // Check for featured/gallery images, upload it and set it. - if ( isset( $request['images'] ) ) { - $product = $this->set_product_images( $product, $request['images'] ); - } - - // Save product meta fields. - $product = $this->set_product_meta( $product, $request ); - - // Save the product data. - $product->save(); - - // Save variations. - if ( $product->is_type( 'variable' ) ) { - if ( isset( $request['variations'] ) && is_array( $request['variations'] ) ) { - $this->save_variations_data( $product, $request ); - } - } - - // Clear caches here so in sync with any new variations/children. - wc_delete_product_transients( $product->get_id() ); - wp_cache_delete( 'product-' . $product->get_id(), 'products' ); - - return true; - } - - /** - * Clear cache/transients. - * - * @param WP_Post $post Post data. - */ - public function clear_transients( $post ) { - wc_delete_product_transients( $post->ID ); - } - - /** - * Delete post. - * - * @param int|WP_Post $id Post ID or WP_Post instance. - */ - protected function delete_post( $id ) { - if ( ! empty( $id->ID ) ) { - $id = $id->ID; - } elseif ( ! is_numeric( $id ) || 0 >= $id ) { - return; - } - - // Delete product attachments. - $attachments = get_posts( array( - 'post_parent' => $id, - 'post_status' => 'any', - 'post_type' => 'attachment', - ) ); - - foreach ( (array) $attachments as $attachment ) { - wp_delete_attachment( $attachment->ID, true ); - } - - // Delete product. - $product = wc_get_product( $id ); - $product->delete( true ); - } - - /** - * Delete a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = (bool) $request['force']; - $post = get_post( $id ); - $product = wc_get_product( $id ); - - if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $supports_trash = EMPTY_TRASH_DAYS > 0; - - /** - * Filter whether an item is trashable. - * - * Return false to disable trash support for the item. - * - * @param boolean $supports_trash Whether the item type support trashing. - * @param WP_Post $post The Post object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); - - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - - // If we're forcing, then delete permanently. - if ( $force ) { - if ( $product->is_type( 'variable' ) ) { - foreach ( $product->get_children() as $child_id ) { - $child = wc_get_product( $child_id ); - if ( ! empty( $child ) ) { - $child->delete( true ); - } - } - } else { - // For other product types, if the product has children, remove the relationship. - foreach ( $product->get_children() as $child_id ) { - $child = wc_get_product( $child_id ); - if ( ! empty( $child ) ) { - $child->set_parent_id( 0 ); - $child->save(); - } - } - } - - $product->delete( true ); - $result = ! ( $product->get_id() > 0 ); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); - } - - // Otherwise, only trash if we haven't already. - if ( 'trash' === $post->post_status ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); - } - - // (Note that internally this falls through to `wp_delete_post` if - // the trash is disabled.) - $product->delete(); - $result = 'trash' === $product->get_status(); - } - - if ( ! $result ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); - } - - // Delete parent product transients. - if ( $parent_id = wp_get_post_parent_id( $id ) ) { - wc_delete_product_transients( $parent_id ); - } - - /** - * Fires after a single item is deleted or trashed via the REST API. - * - * @param object $post The deleted or trashed item. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); - - return $response; - } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'simple', - 'enum' => array_keys( wc_get_product_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), - 'context' => array( 'view', 'edit' ), - ), - 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'visible', - 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Product description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( 'Start date of sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( 'End date of sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_type' => array( - 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'standard', - 'enum' => array( 'standard' ), - 'context' => array( 'view', 'edit' ), - ), - 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'in_stock' => array( - 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'upsell_ids' => array( - 'description' => __( 'List of upsell products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'images' => array( - 'description' => __( 'List of images.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'variations' => array( - 'description' => __( 'List of variations.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Variation ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( 'Start date of sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( 'End date of sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'visible' => array( - 'description' => __( 'If the variation is visible.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - ), - 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => null, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => null, - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'in_stock' => array( - 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['status'] = array( - 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_types() ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['sku'] = array( - 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php b/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php deleted file mode 100644 index 57bd5da4490..00000000000 --- a/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php +++ /dev/null @@ -1,397 +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' ), - ) ); - } - - /** - * Check whether a given request has permission to read report. - * - * @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( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get sales reports. - * - * @param WP_REST_Request $request - * @return array|WP_Error - */ - public function get_items( $request ) { - $data = array(); - $item = $this->prepare_item_for_response( null, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - - return rest_ensure_response( $data ); - } - - /** - * Prepare a report sales object for serialization. - * - * @param null $_ - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $_, $request ) { - // Set date filtering. - $filter = array( - 'period' => $request['period'], - 'date_min' => $request['date_min'], - 'date_max' => $request['date_max'], - ); - $this->setup_report( $filter ); - - // New customers. - $users_query = new WP_User_Query( - array( - 'fields' => array( 'user_registered' ), - 'role' => 'customer', - ) - ); - - $customers = $users_query->get_results(); - - foreach ( $customers as $key => $customer ) { - if ( strtotime( $customer->user_registered ) < $this->report->start_date || strtotime( $customer->user_registered ) > $this->report->end_date ) { - unset( $customers[ $key ] ); - } - } - - $total_customers = count( $customers ); - $report_data = $this->report->get_report_data(); - $period_totals = array(); - - // Setup period totals by ensuring each period in the interval has data. - for ( $i = 0; $i <= $this->report->chart_interval; $i++ ) { - - switch ( $this->report->chart_groupby ) { - case 'day' : - $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $this->report->start_date ) ); - break; - default : - $time = date( 'Y-m', strtotime( "+{$i} MONTH", $this->report->start_date ) ); - break; - } - - // Set the customer signups for each period. - $customer_count = 0; - foreach ( $customers as $customer ) { - if ( date( ( 'day' == $this->report->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) { - $customer_count++; - } - } - - $period_totals[ $time ] = array( - 'sales' => wc_format_decimal( 0.00, 2 ), - 'orders' => 0, - 'items' => 0, - 'tax' => wc_format_decimal( 0.00, 2 ), - 'shipping' => wc_format_decimal( 0.00, 2 ), - 'discount' => wc_format_decimal( 0.00, 2 ), - 'customers' => $customer_count, - ); - } - - // add total sales, total order count, total tax and total shipping for each period - foreach ( $report_data->orders as $order ) { - $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); - - if ( ! isset( $period_totals[ $time ] ) ) { - continue; - } - - $period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 ); - $period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 ); - $period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 ); - } - - foreach ( $report_data->order_counts as $order ) { - $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); - - if ( ! isset( $period_totals[ $time ] ) ) { - continue; - } - - $period_totals[ $time ]['orders'] = (int) $order->count; - } - - // Add total order items for each period. - foreach ( $report_data->order_items as $order_item ) { - $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) ); - - if ( ! isset( $period_totals[ $time ] ) ) { - continue; - } - - $period_totals[ $time ]['items'] = (int) $order_item->order_item_count; - } - - // Add total discount for each period. - foreach ( $report_data->coupons as $discount ) { - $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) ); - - if ( ! isset( $period_totals[ $time ] ) ) { - continue; - } - - $period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 ); - } - - $sales_data = array( - 'total_sales' => $report_data->total_sales, - 'net_sales' => $report_data->net_sales, - 'average_sales' => $report_data->average_sales, - 'total_orders' => $report_data->total_orders, - 'total_items' => $report_data->total_items, - 'total_tax' => wc_format_decimal( $report_data->total_tax + $report_data->total_shipping_tax, 2 ), - 'total_shipping' => $report_data->total_shipping, - 'total_refunds' => $report_data->total_refunds, - 'total_discount' => $report_data->total_coupons, - 'totals_grouped_by' => $this->report->chart_groupby, - 'totals' => $period_totals, - 'total_customers' => $total_customers, - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $sales_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( array( - 'about' => array( - 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), - ), - ) ); - - /** - * Filter a report sales returned from the API. - * - * Allows modification of the report sales data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $data The original report object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_sales', $response, (object) $sales_data, $request ); - } - - /** - * Setup the report object and parse any date filtering. - * - * @param array $filter date filtering - */ - protected function setup_report( $filter ) { - include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); - include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' ); - - $this->report = new WC_Report_Sales_By_Date(); - - if ( empty( $filter['period'] ) ) { - // Custom date range. - $filter['period'] = 'custom'; - - if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) { - - // Overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges. - $_GET['start_date'] = $filter['date_min']; - $_GET['end_date'] = isset( $filter['date_max'] ) ? $filter['date_max'] : null; - - } else { - - // Default custom range to today. - $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); - } - } else { - $filter['period'] = empty( $filter['period'] ) ? 'week' : $filter['period']; - - // Change "week" period to "7day". - if ( 'week' === $filter['period'] ) { - $filter['period'] = '7day'; - } - } - - $this->report->calculate_current_range( $filter['period'] ); - } - - /** - * 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' => 'sales_report', - 'type' => 'object', - 'properties' => array( - 'total_sales' => array( - 'description' => __( 'Gross sales in the period.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'net_sales' => array( - 'description' => __( 'Net sales in the period.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'average_sales' => array( - 'description' => __( 'Average net daily sales.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_orders' => array( - 'description' => __( 'Total of orders placed.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_items' => array( - 'description' => __( 'Total of items purchased.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Total charged for taxes.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_shipping' => array( - 'description' => __( 'Total charged for shipping.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_refunds' => array( - 'description' => __( 'Total of refunded orders.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total_discount' => array( - 'description' => __( 'Total of coupons used.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'totals_grouped_by' => array( - 'description' => __( 'Group type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'totals' => array( - 'description' => __( 'Totals.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'array', - ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - 'period' => array( - 'description' => __( 'Report period.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array( 'week', 'month', 'last_month', 'year' ), - 'validate_callback' => 'rest_validate_request_arg', - 'sanitize_callback' => 'sanitize_text_field', - ), - 'date_min' => array( - /* translators: %s: date format */ - 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce-rest-api' ), 'YYYY-MM-DD' ), - 'type' => 'string', - 'format' => 'date', - 'validate_callback' => 'wc_rest_validate_reports_request_arg', - 'sanitize_callback' => 'sanitize_text_field', - ), - 'date_max' => array( - /* translators: %s: date format */ - 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce-rest-api' ), 'YYYY-MM-DD' ), - 'type' => 'string', - 'format' => 'date', - 'validate_callback' => 'wc_rest_validate_reports_request_arg', - 'sanitize_callback' => 'sanitize_text_field', - ), - ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php b/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php deleted file mode 100644 index 76d0aa9d2ae..00000000000 --- a/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php +++ /dev/null @@ -1,174 +0,0 @@ - $request['period'], - 'date_min' => $request['date_min'], - 'date_max' => $request['date_max'], - ); - $this->setup_report( $filter ); - - $report_data = $this->report->get_order_report_data( array( - 'data' => array( - '_product_id' => array( - 'type' => 'order_item_meta', - 'order_item_type' => 'line_item', - 'function' => '', - 'name' => 'product_id', - ), - '_qty' => array( - 'type' => 'order_item_meta', - 'order_item_type' => 'line_item', - 'function' => 'SUM', - 'name' => 'order_item_qty', - ), - ), - 'order_by' => 'order_item_qty DESC', - 'group_by' => 'product_id', - 'limit' => isset( $filter['limit'] ) ? absint( $filter['limit'] ) : 12, - 'query_type' => 'get_results', - 'filter_range' => true, - ) ); - - $top_sellers = array(); - - foreach ( $report_data as $item ) { - $product = wc_get_product( $item->product_id ); - - if ( $product ) { - $top_sellers[] = array( - 'name' => $product->get_name(), - 'product_id' => (int) $item->product_id, - 'quantity' => wc_stock_amount( $item->order_item_qty ), - ); - } - } - - $data = array(); - foreach ( $top_sellers as $top_seller ) { - $item = $this->prepare_item_for_response( (object) $top_seller, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - return rest_ensure_response( $data ); - } - - /** - * Prepare a report sales object for serialization. - * - * @param stdClass $top_seller - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $top_seller, $request ) { - $data = array( - 'name' => $top_seller->name, - 'product_id' => $top_seller->product_id, - 'quantity' => $top_seller->quantity, - ); - - $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( array( - 'about' => array( - 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), - ), - 'product' => array( - 'href' => rest_url( sprintf( '/%s/products/%s', $this->namespace, $top_seller->product_id ) ), - ), - ) ); - - /** - * Filter a report top sellers returned from the API. - * - * Allows modification of the report top sellers data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $top_seller The original report object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_report_top_sellers', $response, $top_seller, $request ); - } - - /** - * 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' => 'top_sellers_report', - 'type' => 'object', - 'properties' => array( - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'quantity' => array( - 'description' => __( 'Total number of purchases.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php b/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php deleted file mode 100644 index 1f1463ae2b5..00000000000 --- a/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php +++ /dev/null @@ -1,184 +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' ), - ) ); - } - - /** - * Check whether a given request has permission to read reports. - * - * @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( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get reports list. - * - * @since 3.5.0 - * @return array - */ - protected function get_reports() { - return array( - array( - 'slug' => 'sales', - 'description' => __( 'List of sales reports.', 'woocommerce-rest-api' ), - ), - array( - 'slug' => 'top_sellers', - 'description' => __( 'List of top sellers products.', 'woocommerce-rest-api' ), - ), - ); - } - - /** - * Get all reports. - * - * @param WP_REST_Request $request - * @return array|WP_Error - */ - public function get_items( $request ) { - $data = array(); - $reports = $this->get_reports(); - - foreach ( $reports as $report ) { - $item = $this->prepare_item_for_response( (object) $report, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - return rest_ensure_response( $data ); - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'description' => $report->description, - ); - - $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( array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $report->slug ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - ) ); - - /** - * 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', $response, $report, $request ); - } - - /** - * 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', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human-readable description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php deleted file mode 100644 index 5a7206fb6a6..00000000000 --- a/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php +++ /dev/null @@ -1,321 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', array( - 'args' => array( - 'slug' => array( - 'description' => __( 'Unique slug for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read tax classes. - * - * @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( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create tax classes. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a tax. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function delete_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all tax classes. - * - * @param WP_REST_Request $request - * @return array - */ - public function get_items( $request ) { - $tax_classes = array(); - - // Add standard class. - $tax_classes[] = array( - 'slug' => 'standard', - 'name' => __( 'Standard rate', 'woocommerce-rest-api' ), - ); - - $classes = WC_Tax::get_tax_classes(); - - foreach ( $classes as $class ) { - $tax_classes[] = array( - 'slug' => sanitize_title( $class ), - 'name' => $class, - ); - } - - $data = array(); - foreach ( $tax_classes as $tax_class ) { - $class = $this->prepare_item_for_response( $tax_class, $request ); - $class = $this->prepare_response_for_collection( $class ); - $data[] = $class; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a single tax class. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - $tax_class = WC_Tax::create_tax_class( $request['name'] ); - - if ( is_wp_error( $tax_class ) ) { - return new WP_Error( 'woocommerce_rest_' . $tax_class->get_error_code(), $tax_class->get_error_message(), array( 'status' => 400 ) ); - } - - $this->update_additional_fields_for_object( $tax_class, $request ); - - /** - * Fires after a tax class is created or updated via the REST API. - * - * @param stdClass $tax_class Data used to create the tax class. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating tax class, false when updating tax class. - */ - do_action( 'woocommerce_rest_insert_tax_class', (object) $tax_class, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax_class, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $tax_class['slug'] ) ) ); - - return $response; - } - - /** - * Delete a single tax class. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function delete_item( $request ) { - global $wpdb; - - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $tax_class = WC_Tax::get_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); - $deleted = WC_Tax::delete_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); - - if ( ! $deleted ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - if ( is_wp_error( $deleted ) ) { - return new WP_Error( 'woocommerce_rest_' . $deleted->get_error_code(), $deleted->get_error_message(), array( 'status' => 400 ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax_class, $request ); - - /** - * Fires after a tax class is deleted via the REST API. - * - * @param stdClass $tax_class The tax data. - * @param WP_REST_Response $response The response returned from the API. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_tax', (object) $tax_class, $response, $request ); - - return $response; - } - - /** - * Prepare a single tax class output for response. - * - * @param array $tax_class Tax class data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $tax_class, $request ) { - $data = $tax_class; - - $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() ); - - /** - * Filter tax object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $tax_class Tax object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_tax', $response, (object) $tax_class, $request ); - } - - /** - * Prepare links for the request. - * - * @return array Links for the given tax class. - */ - protected function prepare_links() { - $links = array( - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the Tax Classes schema, conforming to JSON Schema - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'tax_class', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Tax class name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'required' => true, - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php b/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php deleted file mode 100644 index ae81985a3d2..00000000000 --- a/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php +++ /dev/null @@ -1,709 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read taxes. - * - * @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( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create taxes. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a tax. - * - * @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( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access update a tax. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function update_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a tax. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function delete_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all taxes. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - global $wpdb; - - $prepared_args = array(); - $prepared_args['order'] = $request['order']; - $prepared_args['number'] = $request['per_page']; - if ( ! empty( $request['offset'] ) ) { - $prepared_args['offset'] = $request['offset']; - } else { - $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; - } - $orderby_possibles = array( - 'id' => 'tax_rate_id', - 'order' => 'tax_rate_order', - ); - $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; - $prepared_args['class'] = $request['class']; - - /** - * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. - * - * @param array $prepared_args Array of arguments for $wpdb->get_results(). - * @param WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request ); - - $query = " - SELECT * - FROM {$wpdb->prefix}woocommerce_tax_rates - WHERE 1 = 1 - "; - - // Filter by tax class. - if ( ! empty( $prepared_args['class'] ) ) { - $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; - $query .= " AND tax_rate_class = '$class'"; - } - - // Order tax rates. - $order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) ); - - // Pagination. - $pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] ); - - // Query taxes. - $results = $wpdb->get_results( $query . $order_by . $pagination ); - - $taxes = array(); - foreach ( $results as $tax ) { - $data = $this->prepare_item_for_response( $tax, $request ); - $taxes[] = $this->prepare_response_for_collection( $data ); - } - - $response = rest_ensure_response( $taxes ); - - // Store pagination values for headers then unset for count query. - $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); - - // Query only for ids. - $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); - - // Calculate totals. - $total_taxes = (int) $wpdb->num_rows; - $response->header( 'X-WP-Total', (int) $total_taxes ); - $max_pages = ceil( $total_taxes / $per_page ); - $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; - } - - /** - * Take tax data from the request and return the updated or newly created rate. - * - * @param WP_REST_Request $request Full details about the request. - * @param stdClass|null $current Existing tax object. - * @return object - */ - protected function create_or_update_tax( $request, $current = null ) { - $id = absint( isset( $request['id'] ) ? $request['id'] : 0 ); - $data = array(); - $fields = array( - 'tax_rate_country', - 'tax_rate_state', - 'tax_rate', - 'tax_rate_name', - 'tax_rate_priority', - 'tax_rate_compound', - 'tax_rate_shipping', - 'tax_rate_order', - 'tax_rate_class', - ); - - foreach ( $fields as $field ) { - // Keys via API differ from the stored names returned by _get_tax_rate. - $key = 'tax_rate' === $field ? 'rate' : str_replace( 'tax_rate_', '', $field ); - - // Remove data that was not posted. - if ( ! isset( $request[ $key ] ) ) { - continue; - } - - // Test new data against current data. - if ( $current && $current->$field === $request[ $key ] ) { - continue; - } - - // Add to data array. - switch ( $key ) { - case 'tax_rate_priority' : - case 'tax_rate_compound' : - case 'tax_rate_shipping' : - case 'tax_rate_order' : - $data[ $field ] = absint( $request[ $key ] ); - break; - case 'tax_rate_class' : - $data[ $field ] = 'standard' !== $request['tax_rate_class'] ? $request['tax_rate_class'] : ''; - break; - default : - $data[ $field ] = wc_clean( $request[ $key ] ); - break; - } - } - - if ( $id ) { - WC_Tax::_update_tax_rate( $id, $data ); - } else { - $id = WC_Tax::_insert_tax_rate( $data ); - } - - // Add locales. - if ( ! empty( $request['postcode'] ) ) { - WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) ); - } - if ( ! empty( $request['city'] ) ) { - WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) ); - } - - return WC_Tax::_get_tax_rate( $id, OBJECT ); - } - - /** - * Create a single tax. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $tax = $this->create_or_update_tax( $request ); - - $this->update_additional_fields_for_object( $tax, $request ); - - /** - * Fires after a tax is created or updated via the REST API. - * - * @param stdClass $tax Data used to create the tax. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating tax, false when updating tax. - */ - do_action( 'woocommerce_rest_insert_tax', $tax, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ) ); - - return $response; - } - - /** - * Get a single tax. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); - - if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $tax = $this->prepare_item_for_response( $tax_obj, $request ); - $response = rest_ensure_response( $tax ); - - return $response; - } - - /** - * Update a single tax. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $id = (int) $request['id']; - $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); - - if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $tax = $this->create_or_update_tax( $request, $tax_obj ); - - $this->update_additional_fields_for_object( $tax, $request ); - - /** - * Fires after a tax is created or updated via the REST API. - * - * @param stdClass $tax Data used to create the tax. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating tax, false when updating tax. - */ - do_action( 'woocommerce_rest_insert_tax', $tax, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax, $request ); - $response = rest_ensure_response( $response ); - - return $response; - } - - /** - * Delete a single tax. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function delete_item( $request ) { - global $wpdb; - - $id = (int) $request['id']; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $tax = WC_Tax::_get_tax_rate( $id, OBJECT ); - - if ( empty( $id ) || empty( $tax ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tax, $request ); - - WC_Tax::_delete_tax_rate( $id ); - - if ( 0 === $wpdb->rows_affected ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a tax is deleted via the REST API. - * - * @param stdClass $tax The tax data. - * @param WP_REST_Response $response The response returned from the API. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request ); - - return $response; - } - - /** - * Prepare a single tax output for response. - * - * @param stdClass $tax Tax object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $tax, $request ) { - global $wpdb; - - $id = (int) $tax->tax_rate_id; - $data = array( - 'id' => $id, - 'country' => $tax->tax_rate_country, - 'state' => $tax->tax_rate_state, - 'postcode' => '', - 'city' => '', - 'rate' => $tax->tax_rate, - 'name' => $tax->tax_rate_name, - 'priority' => (int) $tax->tax_rate_priority, - 'compound' => (bool) $tax->tax_rate_compound, - 'shipping' => (bool) $tax->tax_rate_shipping, - 'order' => (int) $tax->tax_rate_order, - 'class' => $tax->tax_rate_class ? $tax->tax_rate_class : 'standard', - ); - - // Get locales from a tax rate. - $locales = $wpdb->get_results( $wpdb->prepare( " - SELECT location_code, location_type - FROM {$wpdb->prefix}woocommerce_tax_rate_locations - WHERE tax_rate_id = %d - ", $id ) ); - - if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) { - foreach ( $locales as $locale ) { - $data[ $locale->location_type ] = $locale->location_code; - } - } - - $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( $tax ) ); - - /** - * Filter tax object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $tax Tax object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_tax', $response, $tax, $request ); - } - - /** - * Prepare links for the request. - * - * @param stdClass $tax Tax object. - * @return array Links for the given tax. - */ - protected function prepare_links( $tax ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the Taxes schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'tax', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'country' => array( - 'description' => __( 'Country ISO 3166 code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'State code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postcode / ZIP.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'rate' => array( - 'description' => __( 'Tax rate.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Tax rate name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'priority' => array( - 'description' => __( 'Tax priority.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => 1, - 'context' => array( 'view', 'edit' ), - ), - 'compound' => array( - 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'shipping' => array( - 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'order' => array( - 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'standard', - 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - 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(); - $params['context']['default'] = 'view'; - - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'enum' => array( 'asc', 'desc' ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'default' => 'order', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'enum' => array( - 'id', - 'order', - ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['class'] = array( - 'description' => __( 'Sort by tax class.', 'woocommerce-rest-api' ), - 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), - 'sanitize_callback' => 'sanitize_title', - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php b/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php deleted file mode 100644 index adbd3f62b2f..00000000000 --- a/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php +++ /dev/null @@ -1,314 +0,0 @@ -/deliveries endpoint. - * - * @author WooThemes - * @category API - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * REST API Webhook Deliveries controller class. - * - * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Controller - */ -class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'webhooks/(?P[\d]+)/deliveries'; - - /** - * Register the routes for webhook deliveries. - */ - public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'webhook_id' => array( - 'description' => __( 'Unique identifier for the webhook.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - 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( - 'webhook_id' => array( - 'description' => __( 'Unique identifier for the webhook.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read taxes. - * - * @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( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a tax. - * - * @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( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all webhook deliveries. - * - * @param WP_REST_Request $request - * - * @return array|WP_Error - */ - public function get_items( $request ) { - $webhook = wc_get_webhook( (int) $request['webhook_id'] ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $logs = array(); - $data = array(); - foreach ( $logs as $log ) { - $delivery = $this->prepare_item_for_response( (object) $log, $request ); - $delivery = $this->prepare_response_for_collection( $delivery ); - $data[] = $delivery; - } - - return rest_ensure_response( $data ); - } - - /** - * Get a single webhook delivery. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $webhook = wc_get_webhook( (int) $request['webhook_id'] ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $log = array(); - - if ( empty( $id ) || empty( $log ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $delivery = $this->prepare_item_for_response( (object) $log, $request ); - $response = rest_ensure_response( $delivery ); - - return $response; - } - - /** - * Prepare a single webhook delivery output for response. - * - * @param stdClass $log Delivery log object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $log, $request ) { - $data = (array) $log; - $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( $log ) ); - - /** - * Filter webhook delivery object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $log Delivery log object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request ); - } - - /** - * Prepare links for the request. - * - * @param stdClass $log Delivery log object. - * @return array Links for the given webhook delivery. - */ - protected function prepare_links( $log ) { - $webhook_id = (int) $log->request_headers['X-WC-Webhook-ID']; - $base = str_replace( '(?P[\d]+)', $webhook_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $log->id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/webhooks/%d', $this->namespace, $webhook_id ) ), - ), - ); - - return $links; - } - - /** - * Get the Webhook's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'webhook_delivery', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'duration' => array( - 'description' => __( 'The delivery duration, in seconds.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'summary' => array( - 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'request_url' => array( - 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'request_headers' => array( - 'description' => __( 'Request headers.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'request_body' => array( - 'description' => __( 'Request body.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_code' => array( - 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_message' => array( - 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_headers' => array( - 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'response_body' => array( - 'description' => __( 'The response body from the receiving server.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - '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() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php b/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php deleted file mode 100644 index d9f6c611c8a..00000000000 --- a/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php +++ /dev/null @@ -1,763 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'topic' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), - ), - 'delivery_url' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Webhook delivery URL.', 'woocommerce-rest-api' ), - ), - ) ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) ); - } - - /** - * Check whether a given request has permission to read webhooks. - * - * @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( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access create webhooks. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'webhooks', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a webhook. - * - * @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( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access update a webhook. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function update_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'webhooks', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access delete a webhook. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function delete_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'webhooks', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'webhooks', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get the default REST API version. - * - * @since 3.0.0 - * @return string - */ - protected function get_default_api_version() { - return 'wp_api_v1'; - } - - /** - * Get all webhooks. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $args = array(); - $args['order'] = $request['order']; - $args['orderby'] = $request['orderby']; - $args['status'] = 'all' === $request['status'] ? '' : $request['status']; - $args['include'] = implode( ',', $request['include'] ); - $args['exclude'] = implode( ',', $request['exclude'] ); - $args['limit'] = $request['per_page']; - $args['search'] = $request['search']; - $args['before'] = $request['before']; - $args['after'] = $request['after']; - - if ( empty( $request['offset'] ) ) { - $args['offset'] = 1 < $request['page'] ? ( $request['page'] - 1 ) * $args['limit'] : 0; - } - - /** - * Filter arguments, before passing to WC_Webhook_Data_Store->search_webhooks, when querying webhooks via the REST API. - * - * @param array $args Array of arguments for $wpdb->get_results(). - * @param WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request ); - unset( $prepared_args['page'] ); - $prepared_args['paginate'] = true; - - // Get the webhooks. - $webhooks = array(); - $data_store = WC_Data_Store::load( 'webhook' ); - $results = $data_store->search_webhooks( $prepared_args ); - $webhook_ids = $results->webhooks; - - foreach ( $webhook_ids as $webhook_id ) { - $data = $this->prepare_item_for_response( $webhook_id, $request ); - $webhooks[] = $this->prepare_response_for_collection( $data ); - } - - $response = rest_ensure_response( $webhooks ); - $per_page = (int) $prepared_args['limit']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); - $total_webhooks = $results->total; - $max_pages = $results->max_num_pages; - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); - - $response->header( 'X-WP-Total', $total_webhooks ); - $response->header( 'X-WP-TotalPages', $max_pages ); - - 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; - } - - /** - * Get a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - - if ( empty( $id ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $data = $this->prepare_item_for_response( $id, $request ); - $response = rest_ensure_response( $data ); - - return $response; - } - - /** - * Create a single webhook. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - // Validate topic. - if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - // Validate delivery URL. - if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $post = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $post ) ) { - return $post; - } - - $webhook = new WC_Webhook(); - $webhook->set_name( $post->post_title ); - $webhook->set_user_id( $post->post_author ); - $webhook->set_status( 'publish' === $post->post_status ? 'active' : 'disabled' ); - $webhook->set_topic( $request['topic'] ); - $webhook->set_delivery_url( $request['delivery_url'] ); - $webhook->set_secret( ! empty( $request['secret'] ) ? $request['secret'] : wp_generate_password( 50, true, true ) ); - $webhook->set_api_version( $this->get_default_api_version() ); - $webhook->save(); - - $this->update_additional_fields_for_object( $webhook, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WC_Webhook $webhook Webhook data. - * @param WP_REST_Request $request Request object. - * @param bool $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $webhook->get_id() ) ) ); - - // Send ping. - $webhook->deliver_ping(); - - return $response; - } - - /** - * Update a single webhook. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $id = (int) $request['id']; - $webhook = wc_get_webhook( $id ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - // Update topic. - if ( ! empty( $request['topic'] ) ) { - if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { - $webhook->set_topic( $request['topic'] ); - } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - // Update delivery URL. - if ( ! empty( $request['delivery_url'] ) ) { - if ( wc_is_valid_url( $request['delivery_url'] ) ) { - $webhook->set_delivery_url( $request['delivery_url'] ); - } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - // Update secret. - if ( ! empty( $request['secret'] ) ) { - $webhook->set_secret( $request['secret'] ); - } - - // Update status. - if ( ! empty( $request['status'] ) ) { - if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { - $webhook->set_status( $request['status'] ); - } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - $post = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $post ) ) { - return $post; - } - - if ( isset( $post->post_title ) ) { - $webhook->set_name( $post->post_title ); - } - - $webhook->save(); - - $this->update_additional_fields_for_object( $webhook, $request ); - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WC_Webhook $webhook Webhook data. - * @param WP_REST_Request $request Request object. - * @param bool $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); - - return rest_ensure_response( $response ); - } - - /** - * Delete a single webhook. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $webhook = wc_get_webhook( $id ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $webhook, $request ); - $result = $webhook->delete( true ); - - if ( ! $result ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); - } - - /** - * Fires after a single item is deleted or trashed via the REST API. - * - * @param WC_Webhook $webhook The deleted or trashed item. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_webhook_object", $webhook, $response, $request ); - - return $response; - } - - /** - * Prepare a single webhook for create or update. - * - * @param WP_REST_Request $request Request object. - * @return WP_Error|stdClass $data Post object. - */ - protected function prepare_item_for_database( $request ) { - $data = new stdClass; - - // Post ID. - if ( isset( $request['id'] ) ) { - $data->ID = absint( $request['id'] ); - } - - // Validate required POST fields. - if ( 'POST' === $request->get_method() && empty( $data->ID ) ) { - $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce-rest-api' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce-rest-api' ) ) ); // @codingStandardsIgnoreLine - - // Post author. - $data->post_author = get_current_user_id(); - - // Post password. - $data->post_password = 'webhook_' . wp_generate_password(); - - // Post status. - $data->post_status = 'publish'; - } else { - - // Allow edit post title. - if ( ! empty( $request['name'] ) ) { - $data->post_title = $request['name']; - } - } - - // Comment status. - $data->comment_status = 'closed'; - - // Ping status. - $data->ping_status = 'closed'; - - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being - * prepared for insertion. - * - * @param stdClass $data An object representing a single item prepared - * for inserting or updating the database. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $data, $request ); - } - - /** - * Prepare a single webhook output for response. - * - * @param int $id Webhook ID or object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $id, $request ) { - $webhook = wc_get_webhook( $id ); - - if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $data = array( - 'id' => $webhook->get_id(), - 'name' => $webhook->get_name(), - 'status' => $webhook->get_status(), - 'topic' => $webhook->get_topic(), - 'resource' => $webhook->get_resource(), - 'event' => $webhook->get_event(), - 'hooks' => $webhook->get_hooks(), - 'delivery_url' => $webhook->get_delivery_url(), - 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), - ); - - $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( $webhook->get_id() ) ); - - /** - * Filter webhook object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WC_Webhook $webhook Webhook object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); - } - - /** - * Prepare links for the request. - * - * @param int $id Webhook ID. - * @return array - */ - protected function prepare_links( $id ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the Webhook's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'webhook', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Webhook status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'active', - 'enum' => array_keys( wc_get_webhook_statuses() ), - 'context' => array( 'view', 'edit' ), - ), - 'topic' => array( - 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'resource' => array( - 'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'event' => array( - 'description' => __( 'Webhook event.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'hooks' => array( - 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'delivery_url' => array( - 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'secret' => array( - 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['context']['default'] = 'view'; - - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'id', - 'title', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['status'] = array( - 'default' => 'all', - 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array( 'all', 'active', 'paused', 'disabled' ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php b/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php deleted file mode 100644 index 7dbcaa1c2ae..00000000000 --- a/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php +++ /dev/null @@ -1,542 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'required' => true, - 'type' => 'string', - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) - ); - } - - /** - * Get object. - * - * @since 3.0.0 - * @param int $id Object ID. - * @return WC_Data - */ - protected function get_object( $id ) { - return new WC_Coupon( $id ); - } - - /** - * Get formatted item data. - * - * @since 3.0.0 - * @param WC_Data $object WC_Data instance. - * @return array - */ - protected function get_formatted_item_data( $object ) { - $data = $object->get_data(); - - $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); - $format_date = array( 'date_created', 'date_modified', 'date_expires' ); - $format_null = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], 2 ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $datetime = $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - // Format null values. - foreach ( $format_null as $key ) { - $data[ $key ] = $data[ $key ] ? $data[ $key ] : null; - } - - return array( - 'id' => $object->get_id(), - 'code' => $data['code'], - 'amount' => $data['amount'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'discount_type' => $data['discount_type'], - 'description' => $data['description'], - 'date_expires' => $data['date_expires'], - 'date_expires_gmt' => $data['date_expires_gmt'], - 'usage_count' => $data['usage_count'], - 'individual_use' => $data['individual_use'], - 'product_ids' => $data['product_ids'], - 'excluded_product_ids' => $data['excluded_product_ids'], - 'usage_limit' => $data['usage_limit'], - 'usage_limit_per_user' => $data['usage_limit_per_user'], - 'limit_usage_to_x_items' => $data['limit_usage_to_x_items'], - 'free_shipping' => $data['free_shipping'], - 'product_categories' => $data['product_categories'], - 'excluded_product_categories' => $data['excluded_product_categories'], - 'exclude_sale_items' => $data['exclude_sale_items'], - 'minimum_amount' => $data['minimum_amount'], - 'maximum_amount' => $data['maximum_amount'], - 'email_restrictions' => $data['email_restrictions'], - 'used_by' => $data['used_by'], - 'meta_data' => $data['meta_data'], - ); - } - - /** - * Prepare a single coupon output for response. - * - * @since 3.0.0 - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $data = $this->get_formatted_item_data( $object ); - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - if ( ! empty( $request['code'] ) ) { - $id = wc_get_coupon_id_by_code( $request['code'] ); - $args['post__in'] = array( $id ); - } - - // Get only ids. - $args['fields'] = 'ids'; - - return $args; - } - - /** - * Only return writable props from schema. - * - * @param array $schema Schema. - * @return bool - */ - protected function filter_writable_props( $schema ) { - return empty( $schema['readonly'] ); - } - - /** - * Prepare a single coupon for create or update. - * - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $coupon = new WC_Coupon( $id ); - $schema = $this->get_item_schema(); - $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - - // Validate required POST fields. - if ( $creating && empty( $request['code'] ) ) { - return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce-rest-api' ), 'code' ), array( 'status' => 400 ) ); - } - - // Handle all writable props. - foreach ( $data_keys as $key ) { - $value = $request[ $key ]; - - if ( ! is_null( $value ) ) { - switch ( $key ) { - case 'code': - $coupon_code = wc_format_coupon_code( $value ); - $id = $coupon->get_id() ? $coupon->get_id() : 0; - $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); - - if ( $id_from_code ) { - return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $coupon->set_code( $coupon_code ); - break; - case 'meta_data': - if ( is_array( $value ) ) { - foreach ( $value as $meta ) { - $coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - break; - case 'description': - $coupon->set_description( wp_filter_post_kses( $value ) ); - break; - default: - if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { - $coupon->{"set_{$key}"}( $value ); - } - break; - } - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $coupon Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $coupon, $request, $creating ); - } - - /** - * Get the Coupon's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the object.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'amount' => array( - 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'discount_type' => array( - 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'fixed_cart', - 'enum' => array_keys( wc_get_coupon_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Coupon description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_expires' => array( - 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_expires_gmt' => array( - 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'usage_count' => array( - 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'individual_use' => array( - 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'product_ids' => array( - 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'excluded_product_ids' => array( - 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'usage_limit' => array( - 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'usage_limit_per_user' => array( - 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'limit_usage_to_x_items' => array( - 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'free_shipping' => array( - 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'product_categories' => array( - 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'excluded_product_categories' => array( - 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'exclude_sale_items' => array( - 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'minimum_amount' => array( - 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'maximum_amount' => array( - 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email_restrictions' => array( - 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - 'context' => array( 'view', 'edit' ), - ), - 'used_by' => array( - 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['code'] = array( - 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php deleted file mode 100644 index 1b7c0de9fd6..00000000000 --- a/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php +++ /dev/null @@ -1,165 +0,0 @@ -/downloads endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Customers controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Customer_Downloads_V1_Controller - */ -class WC_REST_Customer_Downloads_V2_Controller extends WC_REST_Customer_Downloads_V1_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; - - /** - * Prepare a single download output for response. - * - * @param stdClass $download Download object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $download, $request ) { - $data = array( - 'download_id' => $download->download_id, - 'download_url' => $download->download_url, - 'product_id' => $download->product_id, - 'product_name' => $download->product_name, - 'download_name' => $download->download_name, - 'order_id' => $download->order_id, - 'order_key' => $download->order_key, - 'downloads_remaining' => '' === $download->downloads_remaining ? 'unlimited' : $download->downloads_remaining, - 'access_expires' => $download->access_expires ? wc_rest_prepare_date_response( $download->access_expires ) : 'never', - 'access_expires_gmt' => $download->access_expires ? wc_rest_prepare_date_response( get_gmt_from_date( $download->access_expires ) ) : 'never', - 'file' => $download->file, - ); - - $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( $download, $request ) ); - - /** - * Filter customer download data returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $download Download object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); - } - - /** - * Get the Customer Download's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'customer_download', - 'type' => 'object', - 'properties' => array( - 'download_id' => array( - 'description' => __( 'Download ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'download_url' => array( - 'description' => __( 'Download file URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Downloadable product ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'product_name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'download_name' => array( - 'description' => __( 'Downloadable file name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'downloads_remaining' => array( - 'description' => __( 'Number of downloads remaining.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'access_expires' => array( - 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'access_expires_gmt' => array( - 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'file' => array( - 'description' => __( 'File details.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php deleted file mode 100644 index 29d4e07d2e2..00000000000 --- a/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php +++ /dev/null @@ -1,364 +0,0 @@ -get_data(); - $format_date = array( 'date_created', 'date_modified' ); - - // Format date values. - foreach ( $format_date as $key ) { - $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - return array( - 'id' => $object->get_id(), - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => $data['email'], - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'role' => $data['role'], - 'username' => $data['username'], - 'billing' => $data['billing'], - 'shipping' => $data['shipping'], - 'is_paying_customer' => $data['is_paying_customer'], - 'orders_count' => $object->get_order_count(), - 'total_spent' => $object->get_total_spent(), - 'avatar_url' => $object->get_avatar_url(), - 'meta_data' => $data['meta_data'], - ); - } - - /** - * Prepare a single customer output for response. - * - * @param WP_User $user_data User object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $user_data, $request ) { - $customer = new WC_Customer( $user_data->ID ); - $data = $this->get_formatted_item_data( $customer ); - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $user_data ) ); - - /** - * Filter customer data returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_User $user_data User object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); - } - - /** - * Update customer meta fields. - * - * @param WC_Customer $customer Customer data. - * @param WP_REST_Request $request Request data. - */ - protected function update_customer_meta_fields( $customer, $request ) { - parent::update_customer_meta_fields( $customer, $request ); - - // Meta data. - if ( isset( $request['meta_data'] ) ) { - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $customer->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - } - } - - /** - * Get the Customer's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'customer', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'role' => array( - 'description' => __( 'Customer role.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_user', - ), - ), - 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - ), - 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'is_paying_customer' => array( - 'description' => __( 'Is the customer a paying customer?', 'woocommerce-rest-api' ), - 'type' => 'bool', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'orders_count' => array( - 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_spent' => array( - 'description' => __( 'Total amount spent.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php deleted file mode 100644 index 357082d1b65..00000000000 --- a/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php +++ /dev/null @@ -1,174 +0,0 @@ -namespace, - '/' . $this->rest_base . '/network', - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'network_orders' ), - 'permission_callback' => array( $this, 'network_orders_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - } - - /** - * Retrieves the item's schema for display / public consumption purposes. - * - * @return array Public item schema data. - */ - public function get_public_item_schema() { - $schema = parent::get_public_item_schema(); - - $schema['properties']['blog'] = array( - 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ); - $schema['properties']['edit_url'] = array( - 'description' => __( 'URL to edit the order', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ); - $schema['properties']['customer'][] = array( - 'description' => __( 'Name of the customer for the order', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ); - $schema['properties']['status_name'][] = array( - 'description' => __( 'Order Status', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ); - $schema['properties']['formatted_total'][] = array( - 'description' => __( 'Order total formatted for locale', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ); - - return $schema; - } - - /** - * Does a permissions check for the proper requested blog - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool $permission - */ - public function network_orders_permissions_check( $request ) { - $blog_id = $request->get_param( 'blog_id' ); - $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); - - switch_to_blog( $blog_id ); - - $permission = $this->get_items_permissions_check( $request ); - - restore_current_blog(); - - return $permission; - } - - /** - * Get a collection of orders from the requested blog id - * - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_REST_Response - */ - public function network_orders( $request ) { - $blog_id = $request->get_param( 'blog_id' ); - $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); - $active_plugins = get_blog_option( $blog_id, 'active_plugins', array() ); - $network_active_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); - - $plugins = array_merge( $active_plugins, $network_active_plugins ); - $wc_active = false; - foreach ( $plugins as $plugin ) { - if ( substr_compare( $plugin, '/woocommerce.php', strlen( $plugin ) - strlen( '/woocommerce.php' ), strlen( '/woocommerce.php' ) ) === 0 ) { - $wc_active = true; - } - } - - // If WooCommerce not active for site, return an empty response. - if ( ! $wc_active ) { - $response = rest_ensure_response( array() ); - return $response; - } - - switch_to_blog( $blog_id ); - add_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); - $items = $this->get_items( $request ); - remove_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); - - foreach ( $items->data as &$current_order ) { - $order = wc_get_order( $current_order['id'] ); - - $current_order['blog'] = get_blog_details( get_current_blog_id() ); - $current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' ); - /* translators: 1: first name 2: last name */ - $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce-rest-api' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); - $current_order['status_name'] = wc_get_order_status_name( $order->get_status() ); - $current_order['formatted_total'] = $order->get_formatted_order_total(); - } - - restore_current_blog(); - - return $items; - } - - /** - * Filters the post statuses to on hold and processing for the network order query. - * - * @param array $args Query args. - * - * @return array - */ - public function network_orders_filter_args( $args ) { - $args['post_status'] = array( - 'wc-on-hold', - 'wc-processing', - ); - - return $args; - } -} diff --git a/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php deleted file mode 100644 index 6ecd15e3165..00000000000 --- a/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php +++ /dev/null @@ -1,182 +0,0 @@ -/notes endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Order Notes controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Order_Notes_V1_Controller - */ -class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; - - /** - * Get order notes from an order. - * - * @param WP_REST_Request $request Request data. - * - * @return array|WP_Error - */ - public function get_items( $request ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $args = array( - 'post_id' => $order->get_id(), - 'approve' => 'approve', - 'type' => 'order_note', - ); - - // Allow filter by order note type. - if ( 'customer' === $request['type'] ) { - $args['meta_query'] = array( // WPCS: slow query ok. - array( - 'key' => 'is_customer_note', - 'value' => 1, - 'compare' => '=', - ), - ); - } elseif ( 'internal' === $request['type'] ) { - $args['meta_query'] = array( // WPCS: slow query ok. - array( - 'key' => 'is_customer_note', - 'compare' => 'NOT EXISTS', - ), - ); - } - - remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); - - $notes = get_comments( $args ); - - add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); - - $data = array(); - foreach ( $notes as $note ) { - $order_note = $this->prepare_item_for_response( $note, $request ); - $order_note = $this->prepare_response_for_collection( $order_note ); - $data[] = $order_note; - } - - return rest_ensure_response( $data ); - } - - /** - * Prepare a single order note output for response. - * - * @param WP_Comment $note Order note object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $note, $request ) { - $data = array( - 'id' => (int) $note->comment_ID, - 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), - 'note' => $note->comment_content, - 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), - ); - - $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( $note ) ); - - /** - * Filter order note object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_Comment $note Order note object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); - } - - /** - * Get the Order Notes schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'order_note', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'note' => array( - 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'customer_note' => array( - 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - 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['type'] = array( - 'default' => 'any', - 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array( 'any', 'customer', 'internal' ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php b/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php deleted file mode 100644 index dff06e2d063..00000000000 --- a/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php +++ /dev/null @@ -1,584 +0,0 @@ -/refunds endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Order Refunds controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Orders_V2_Controller - */ -class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'orders/(?P[\d]+)/refunds'; - - /** - * Post type. - * - * @var string - */ - protected $post_type = 'shop_order_refund'; - - /** - * Stores the request. - * - * @var array - */ - protected $request = array(); - - /** - * Order refunds actions. - */ - public function __construct() { - add_filter( "woocommerce_rest_{$this->post_type}_object_trashable", '__return_false' ); - } - - /** - * Register the routes for order refunds. - */ - public function register_routes() { - register_rest_route( - $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => true, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get object. - * - * @since 3.0.0 - * @param int $id Object ID. - * @return WC_Data - */ - protected function get_object( $id ) { - return wc_get_order( $id ); - } - - /** - * Get formatted item data. - * - * @since 3.0.0 - * @param WC_Data $object WC_Data instance. - * @return array - */ - protected function get_formatted_item_data( $object ) { - $data = $object->get_data(); - $format_decimal = array( 'amount' ); - $format_date = array( 'date_created' ); - $format_line_items = array( 'line_items' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $datetime = $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - // Format line items. - foreach ( $format_line_items as $key ) { - $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); - } - - return array( - 'id' => $object->get_id(), - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'amount' => $data['amount'], - 'reason' => $data['reason'], - 'refunded_by' => $data['refunded_by'], - 'refunded_payment' => $data['refunded_payment'], - 'meta_data' => $data['meta_data'], - 'line_items' => $data['line_items'], - ); - } - - /** - * Prepare a single order output for response. - * - * @since 3.0.0 - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * - * @return WP_Error|WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $this->request = $request; - $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); - } - - if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce-rest-api' ), 404 ); - } - - $data = $this->get_formatted_item_data( $object ); - $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( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return array Links for the given post. - */ - protected function prepare_links( $object, $request ) { - $base = str_replace( '(?P[\d]+)', $object->get_parent_id(), $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), - ), - ); - - return $links; - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - $args['post_status'] = array_keys( wc_get_order_statuses() ); - $args['post_parent__in'] = array( absint( $request['order_id'] ) ); - - return $args; - } - - /** - * Prepares one object for create or update operation. - * - * @since 3.0.0 - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); - } - - if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); - } - - // Create the refund. - $refund = wc_create_refund( - array( - 'order_id' => $order->get_id(), - 'amount' => $request['amount'], - 'reason' => empty( $request['reason'] ) ? null : $request['reason'], - 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, - 'restock_items' => true, - ) - ); - - if ( is_wp_error( $refund ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); - } - - if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); - } - - if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - $refund->save_meta_data(); - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $coupon Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); - } - - /** - * Save an object data. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. - * @return WC_Data|WP_Error - */ - protected function save_object( $request, $creating = false ) { - try { - $object = $this->prepare_object_for_database( $request, $creating ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - return $this->get_object( $object->get_id() ); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Get the Order's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'amount' => array( - 'description' => __( 'Refund amount.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'reason' => array( - 'description' => __( 'Reason for refund.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'refunded_by' => array( - 'description' => __( 'User ID of user who created the refund.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'refunded_payment' => array( - 'description' => __( 'If the payment was refunded via the API.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'api_refund' => array( - 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'edit' ), - 'default' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - unset( $params['status'], $params['customer'], $params['product'] ); - - return $params; - } -} diff --git a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php deleted file mode 100644 index a9422aec274..00000000000 --- a/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ /dev/null @@ -1,1711 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) - ); - } - - /** - * Get object. Return false if object is not of required type. - * - * @since 3.0.0 - * @param int $id Object ID. - * @return WC_Data|bool - */ - protected function get_object( $id ) { - $order = wc_get_order( $id ); - // In case id is a refund's id (or it's not an order at all), don't expose it via /orders/ path. - if ( ! $order || 'shop_order_refund' === $order->get_type() ) { - return false; - } - - return $order; - } - - /** - * Expands an order item to get its data. - * - * @param WC_Order_item $item Order item data. - * @return array - */ - protected function get_order_item_data( $item ) { - $data = $item->get_data(); - $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - if ( isset( $data[ $key ] ) ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); - } - } - - // Add SKU and PRICE to products. - if ( is_callable( array( $item, 'get_product' ) ) ) { - $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; - $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; - } - - // Format taxes. - if ( ! empty( $data['taxes']['total'] ) ) { - $taxes = array(); - - foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { - $taxes[] = array( - 'id' => $tax_rate_id, - 'total' => $tax, - 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', - ); - } - $data['taxes'] = $taxes; - } elseif ( isset( $data['taxes'] ) ) { - $data['taxes'] = array(); - } - - // Remove names for coupons, taxes and shipping. - if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { - unset( $data['name'] ); - } - - // Remove props we don't want to expose. - unset( $data['order_id'] ); - unset( $data['type'] ); - - return $data; - } - - /** - * Get formatted item data. - * - * @since 3.0.0 - * @param WC_Data $object WC_Data instance. - * @return array - */ - protected function get_formatted_item_data( $object ) { - $data = $object->get_data(); - $format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' ); - $format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' ); - $format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' ); - - // Format decimal values. - foreach ( $format_decimal as $key ) { - $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); - } - - // Format date values. - foreach ( $format_date as $key ) { - $datetime = $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - // Format the order status. - $data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status']; - - // Format line items. - foreach ( $format_line_items as $key ) { - $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); - } - - // Refunds. - $data['refunds'] = array(); - foreach ( $object->get_refunds() as $refund ) { - $data['refunds'][] = array( - 'id' => $refund->get_id(), - 'reason' => $refund->get_reason() ? $refund->get_reason() : '', - 'total' => '-' . wc_format_decimal( $refund->get_amount(), $this->request['dp'] ), - ); - } - - return array( - 'id' => $object->get_id(), - 'parent_id' => $data['parent_id'], - 'number' => $data['number'], - 'order_key' => $data['order_key'], - 'created_via' => $data['created_via'], - 'version' => $data['version'], - 'status' => $data['status'], - 'currency' => $data['currency'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'discount_total' => $data['discount_total'], - 'discount_tax' => $data['discount_tax'], - 'shipping_total' => $data['shipping_total'], - 'shipping_tax' => $data['shipping_tax'], - 'cart_tax' => $data['cart_tax'], - 'total' => $data['total'], - 'total_tax' => $data['total_tax'], - 'prices_include_tax' => $data['prices_include_tax'], - 'customer_id' => $data['customer_id'], - 'customer_ip_address' => $data['customer_ip_address'], - 'customer_user_agent' => $data['customer_user_agent'], - 'customer_note' => $data['customer_note'], - 'billing' => $data['billing'], - 'shipping' => $data['shipping'], - 'payment_method' => $data['payment_method'], - 'payment_method_title' => $data['payment_method_title'], - 'transaction_id' => $data['transaction_id'], - 'date_paid' => $data['date_paid'], - 'date_paid_gmt' => $data['date_paid_gmt'], - 'date_completed' => $data['date_completed'], - 'date_completed_gmt' => $data['date_completed_gmt'], - 'cart_hash' => $data['cart_hash'], - 'meta_data' => $data['meta_data'], - 'line_items' => $data['line_items'], - 'tax_lines' => $data['tax_lines'], - 'shipping_lines' => $data['shipping_lines'], - 'fee_lines' => $data['fee_lines'], - 'coupon_lines' => $data['coupon_lines'], - 'refunds' => $data['refunds'], - ); - } - - /** - * Prepare a single order output for response. - * - * @since 3.0.0 - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $this->request = $request; - $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); - $data = $this->get_formatted_item_data( $object ); - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return array Links for the given post. - */ - protected function prepare_links( $object, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - if ( 0 !== (int) $object->get_customer_id() ) { - $links['customer'] = array( - 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object->get_customer_id() ) ), - ); - } - - if ( 0 !== (int) $object->get_parent_id() ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), - ); - } - - return $links; - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - global $wpdb; - - $args = parent::prepare_objects_query( $request ); - - // Set post_status. - if ( in_array( $request['status'], $this->get_order_statuses(), true ) ) { - $args['post_status'] = 'wc-' . $request['status']; - } elseif ( 'any' === $request['status'] ) { - $args['post_status'] = 'any'; - } else { - $args['post_status'] = $request['status']; - } - - if ( isset( $request['customer'] ) ) { - if ( ! empty( $args['meta_query'] ) ) { - $args['meta_query'] = array(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - } - - $args['meta_query'][] = array( - 'key' => '_customer_user', - 'value' => $request['customer'], - 'type' => 'NUMERIC', - ); - } - - // Search by product. - if ( ! empty( $request['product'] ) ) { - $order_ids = $wpdb->get_col( - $wpdb->prepare( - "SELECT order_id - FROM {$wpdb->prefix}woocommerce_order_items - WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) - AND order_item_type = 'line_item'", - $request['product'] - ) - ); - - // Force WP_Query return empty if don't found any order. - $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); - - $args['post__in'] = $order_ids; - } - - // Search. - if ( ! empty( $args['s'] ) ) { - $order_ids = wc_order_search( $args['s'] ); - - if ( ! empty( $order_ids ) ) { - unset( $args['s'] ); - $args['post__in'] = array_merge( $order_ids, array( 0 ) ); - } - } - - /** - * Filter the query arguments for a request. - * - * Enables adding extra arguments or setting defaults for an order 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_orders_prepare_object_query', $args, $request ); - - return $args; - } - - /** - * Only return writable props from schema. - * - * @param array $schema Schema. - * @return bool - */ - protected function filter_writable_props( $schema ) { - return empty( $schema['readonly'] ); - } - - /** - * Prepare a single order for create or update. - * - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $order = new WC_Order( $id ); - $schema = $this->get_item_schema(); - $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - - // Handle all writable props. - foreach ( $data_keys as $key ) { - $value = $request[ $key ]; - - if ( ! is_null( $value ) ) { - switch ( $key ) { - case 'status': - // Status change should be done later so transitions have new data. - break; - case 'billing': - case 'shipping': - $this->update_address( $order, $value, $key ); - break; - case 'line_items': - case 'shipping_lines': - case 'fee_lines': - case 'coupon_lines': - if ( is_array( $value ) ) { - foreach ( $value as $item ) { - if ( is_array( $item ) ) { - if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { - $order->remove_item( $item['id'] ); - } else { - $this->set_item( $order, $key, $item ); - } - } - } - } - break; - case 'meta_data': - if ( is_array( $value ) ) { - foreach ( $value as $meta ) { - $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - break; - default: - if ( is_callable( array( $order, "set_{$key}" ) ) ) { - $order->{"set_{$key}"}( $value ); - } - break; - } - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $order Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); - } - - /** - * Save an object data. - * - * @since 3.0.0 - * @throws WC_REST_Exception But all errors are validated before returning any data. - * @param WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. - * @return WC_Data|WP_Error - */ - protected function save_object( $request, $creating = false ) { - try { - $object = $this->prepare_object_for_database( $request, $creating ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - // Make sure gateways are loaded so hooks from gateways fire on save/create. - WC()->payment_gateways(); - - if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { - // Make sure customer exists. - if ( false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); - } - - // Make sure customer is part of blog. - if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { - add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); - } - } - - if ( $creating ) { - $object->set_created_via( 'rest-api' ); - $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); - $object->calculate_totals(); - } else { - // If items have changed, recalculate order totals. - if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { - $object->calculate_totals( true ); - } - } - - // Set status. - if ( ! empty( $request['status'] ) ) { - $object->set_status( $request['status'] ); - } - - $object->save(); - - // Actions for after the order is saved. - if ( true === $request['set_paid'] ) { - if ( $creating || $object->needs_payment() ) { - $object->payment_complete( $request['transaction_id'] ); - } - } - - return $this->get_object( $object->get_id() ); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Update address. - * - * @param WC_Order $order Order data. - * @param array $posted Posted data. - * @param string $type Address type. - */ - protected function update_address( $order, $posted, $type = 'billing' ) { - foreach ( $posted as $key => $value ) { - if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { - $order->{"set_{$type}_{$key}"}( $value ); - } - } - } - - /** - * Gets the product ID from the SKU or posted ID. - * - * @throws WC_REST_Exception When SKU or ID is not valid. - * @param array $posted Request data. - * @param string $action 'create' to add line item or 'update' to update it. - * @return int - */ - protected function get_product_id( $posted, $action = 'create' ) { - if ( ! empty( $posted['sku'] ) ) { - $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); - } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { - $product_id = (int) $posted['product_id']; - } elseif ( ! empty( $posted['variation_id'] ) ) { - $product_id = (int) $posted['variation_id']; - } elseif ( 'update' === $action ) { - $product_id = 0; - } else { - throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); - } - return $product_id; - } - - /** - * Maybe set an item prop if the value was posted. - * - * @param WC_Order_Item $item Order item. - * @param string $prop Order property. - * @param array $posted Request data. - */ - protected function maybe_set_item_prop( $item, $prop, $posted ) { - if ( isset( $posted[ $prop ] ) ) { - $item->{"set_$prop"}( $posted[ $prop ] ); - } - } - - /** - * Maybe set item props if the values were posted. - * - * @param WC_Order_Item $item Order item data. - * @param string[] $props Properties. - * @param array $posted Request data. - */ - protected function maybe_set_item_props( $item, $props, $posted ) { - foreach ( $props as $prop ) { - $this->maybe_set_item_prop( $item, $prop, $posted ); - } - } - - /** - * Maybe set item meta if posted. - * - * @param WC_Order_Item $item Order item data. - * @param array $posted Request data. - */ - protected function maybe_set_item_meta_data( $item, $posted ) { - if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { - foreach ( $posted['meta_data'] as $meta ) { - if ( isset( $meta['key'] ) ) { - $value = isset( $meta['value'] ) ? $meta['value'] : null; - $item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - } - } - - /** - * Create or update a line item. - * - * @param array $posted Line item data. - * @param string $action 'create' to add line item or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Product - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_line_items( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - $product = wc_get_product( $this->get_product_id( $posted, $action ) ); - - if ( $product && $product !== $item->get_product() ) { - $item->set_product( $product ); - - if ( 'create' === $action ) { - $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; - $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); - $item->set_total( $total ); - $item->set_subtotal( $total ); - } - } - - $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Create or update an order shipping method. - * - * @param array $posted $shipping Item data. - * @param string $action 'create' to add shipping or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Shipping - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - - if ( 'create' === $action ) { - if ( empty( $posted['method_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce-rest-api' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total', 'instance_id' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Create or update an order fee. - * - * @param array $posted Item data. - * @param string $action 'create' to add fee or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Fee - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - - if ( 'create' === $action ) { - if ( empty( $posted['name'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce-rest-api' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Create or update an order coupon. - * - * @param array $posted Item data. - * @param string $action 'create' to add coupon or 'update' to update it. - * @param object $item Passed when updating an item. Null during creation. - * @return WC_Order_Item_Coupon - * @throws WC_REST_Exception Invalid data, server error. - */ - protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) { - $item = is_null( $item ) ? new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; - - if ( 'create' === $action ) { - if ( empty( $posted['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); - } - } - - $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); - $this->maybe_set_item_meta_data( $item, $posted ); - - return $item; - } - - /** - * Wrapper method to create/update order items. - * When updating, the item ID provided is checked to ensure it is associated - * with the order. - * - * @param WC_Order $order order object. - * @param string $item_type The item type. - * @param array $posted item provided in the request body. - * @throws WC_REST_Exception If item ID is not associated with order. - */ - protected function set_item( $order, $item_type, $posted ) { - global $wpdb; - - if ( ! empty( $posted['id'] ) ) { - $action = 'update'; - } else { - $action = 'create'; - } - - $method = 'prepare_' . $item_type; - $item = null; - - // Verify provided line item ID is associated with order. - if ( 'update' === $action ) { - $item = $order->get_item( absint( $posted['id'] ), false ); - - if ( ! $item ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce-rest-api' ), 400 ); - } - } - - // Prepare item data. - $item = $this->$method( $posted, $action, $item ); - - do_action( 'woocommerce_rest_set_order_item', $item, $posted ); - - // If creating the order, add the item to it. - if ( 'create' === $action ) { - $order->add_item( $item ); - } else { - $item->save(); - } - } - - /** - * Helper method to check if the resource ID associated with the provided item is null. - * Items can be deleted by setting the resource ID to null. - * - * @param array $item Item provided in the request body. - * @return bool True if the item resource ID is null, false otherwise. - */ - protected function item_is_null( $item ) { - $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); - - foreach ( $keys as $key ) { - if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { - return true; - } - } - - return false; - } - - /** - * Get order statuses without prefixes. - * - * @return array - */ - protected function get_order_statuses() { - $order_statuses = array(); - - foreach ( array_keys( wc_get_order_statuses() ) as $status ) { - $order_statuses[] = str_replace( 'wc-', '', $status ); - } - - return $order_statuses; - } - - /** - * Get the Order's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'parent_id' => array( - 'description' => __( 'Parent order ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'number' => array( - 'description' => __( 'Order number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Order status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'pending', - 'enum' => $this->get_order_statuses(), - 'context' => array( 'view', 'edit' ), - ), - 'currency' => array( - 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => get_woocommerce_currency(), - 'enum' => array_keys( get_woocommerce_currencies() ), - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the order was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'discount_total' => array( - 'description' => __( 'Total discount amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'discount_tax' => array( - 'description' => __( 'Total discount tax amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_total' => array( - 'description' => __( 'Total shipping amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_tax' => array( - 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'cart_tax' => array( - 'description' => __( 'Sum of line item taxes only.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Grand total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_tax' => array( - 'description' => __( 'Sum of all taxes.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => 0, - 'context' => array( 'view', 'edit' ), - ), - 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'billing' => array( - 'description' => __( 'Billing address.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping' => array( - 'description' => __( 'Shipping address.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'payment_method' => array( - 'description' => __( 'Payment method ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'payment_method_title' => array( - 'description' => __( 'Payment method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'transaction_id' => array( - 'description' => __( 'Unique transaction ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_paid' => array( - 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_paid_gmt' => array( - 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_completed_gmt' => array( - 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'cart_hash' => array( - 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), - 'type' => 'number', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'tax_lines' => array( - 'description' => __( 'Tax lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rate_code' => array( - 'description' => __( 'Tax rate code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'Tax rate label.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'compound' => array( - 'description' => __( 'Show if is a compound tax rate.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tax_total' => array( - 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_tax_total' => array( - 'description' => __( 'Shipping tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'shipping_lines' => array( - 'description' => __( 'Shipping lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_title' => array( - 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'instance_id' => array( - 'description' => __( 'Shipping instance ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'fee_lines' => array( - 'description' => __( 'Fee lines data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class of fee.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status of fee.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'taxable', 'none' ), - ), - 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'coupon_lines' => array( - 'description' => __( 'Coupons line data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'discount' => array( - 'description' => __( 'Discount total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'discount_tax' => array( - 'description' => __( 'Discount total tax.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ), - ), - 'refunds' => array( - 'description' => __( 'List of refunds.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Refund ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reason' => array( - 'description' => __( 'Refund reason.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Refund total.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['status'] = array( - 'default' => 'any', - 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['customer'] = array( - 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['product'] = array( - 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['dp'] = array( - 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php b/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php deleted file mode 100644 index a652ea1fab3..00000000000 --- a/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php +++ /dev/null @@ -1,466 +0,0 @@ - - */ - public function register_routes() { - register_rest_route( - $this->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[\w-]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check whether a given request has permission to view payment gateways. - * - * @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( 'payment_gateways', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to read a payment gateway. - * - * @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( 'payment_gateways', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check whether a given request has permission to edit payment gateways. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Get payment gateways. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $payment_gateways = WC()->payment_gateways->payment_gateways(); - $response = array(); - foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { - $payment_gateway->id = $payment_gateway_id; - $gateway = $this->prepare_item_for_response( $payment_gateway, $request ); - $gateway = $this->prepare_response_for_collection( $gateway ); - $response[] = $gateway; - } - return rest_ensure_response( $response ); - } - - /** - * Get a single payment gateway. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function get_item( $request ) { - $gateway = $this->get_gateway( $request ); - - if ( is_null( $gateway ) ) { - return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $gateway = $this->prepare_item_for_response( $gateway, $request ); - return rest_ensure_response( $gateway ); - } - - /** - * Update A Single Payment Method. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function update_item( $request ) { - $gateway = $this->get_gateway( $request ); - - if ( is_null( $gateway ) ) { - return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - // Get settings. - $gateway->init_form_fields(); - $settings = $gateway->settings; - - // Update settings. - if ( isset( $request['settings'] ) ) { - $errors_found = false; - foreach ( $gateway->form_fields as $key => $field ) { - if ( isset( $request['settings'][ $key ] ) ) { - if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { - $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); - } else { - $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); - } - if ( is_wp_error( $value ) ) { - $errors_found = true; - break; - } - $settings[ $key ] = $value; - } - } - - if ( $errors_found ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - // Update if this method is enabled or not. - if ( isset( $request['enabled'] ) ) { - $settings['enabled'] = wc_bool_to_string( $request['enabled'] ); - $gateway->enabled = $settings['enabled']; - } - - // Update title. - if ( isset( $request['title'] ) ) { - $settings['title'] = $request['title']; - $gateway->title = $settings['title']; - } - - // Update description. - if ( isset( $request['description'] ) ) { - $settings['description'] = $request['description']; - $gateway->description = $settings['description']; - } - - // Update options. - $gateway->settings = $settings; - update_option( $gateway->get_option_key(), apply_filters( 'woocommerce_gateway_' . $gateway->id . '_settings_values', $settings, $gateway ) ); - - // Update order. - if ( isset( $request['order'] ) ) { - $order = (array) get_option( 'woocommerce_gateway_order' ); - $order[ $gateway->id ] = $request['order']; - update_option( 'woocommerce_gateway_order', $order ); - $gateway->order = absint( $request['order'] ); - } - - $gateway = $this->prepare_item_for_response( $gateway, $request ); - return rest_ensure_response( $gateway ); - } - - /** - * Get a gateway based on the current request object. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|null - */ - public function get_gateway( $request ) { - $gateway = null; - $payment_gateways = WC()->payment_gateways->payment_gateways(); - foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { - if ( $request['id'] !== $payment_gateway_id ) { - continue; - } - $payment_gateway->id = $payment_gateway_id; - $gateway = $payment_gateway; - } - return $gateway; - } - - /** - * Prepare a payment gateway for response. - * - * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $gateway, $request ) { - $order = (array) get_option( 'woocommerce_gateway_order' ); - $item = array( - 'id' => $gateway->id, - 'title' => $gateway->title, - 'description' => $gateway->description, - 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', - 'enabled' => ( 'yes' === $gateway->enabled ), - 'method_title' => $gateway->get_method_title(), - 'method_description' => $gateway->get_method_description(), - 'settings' => $this->get_settings( $gateway ), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $gateway, $request ) ); - - /** - * Filter payment gateway objects returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); - } - - /** - * Return settings associated with this payment gateway. - * - * @param WC_Payment_Gateway $gateway Gateway data. - * - * @return array - */ - public function get_settings( $gateway ) { - $settings = array(); - $gateway->init_form_fields(); - foreach ( $gateway->form_fields as $id => $field ) { - // Make sure we at least have a title and type. - if ( empty( $field['title'] ) || empty( $field['type'] ) ) { - continue; - } - // Ignore 'title' settings/fields -- they are UI only. - if ( 'title' === $field['type'] ) { - continue; - } - // Ignore 'enabled' and 'description' which get included elsewhere. - if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { - continue; - } - $data = array( - 'id' => $id, - 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - - /** - * Prepare links for the request. - * - * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $gateway, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $gateway->id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the payment gateway schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'payment_gateway', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'absint', - ), - ), - 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - ), - 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get any query params needed. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } - -} diff --git a/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php deleted file mode 100644 index 27d71b11c10..00000000000 --- a/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/terms endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Product Attribute Terms controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Product_Attribute_Terms_V1_Controller - */ -class WC_REST_Product_Attribute_Terms_V2_Controller extends WC_REST_Product_Attribute_Terms_V1_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; -} diff --git a/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php deleted file mode 100644 index 3ff18b310a2..00000000000 --- a/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -term_id, 'display_type', true ); - - // Get category order. - $menu_order = get_term_meta( $item->term_id, 'order', true ); - - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'parent' => (int) $item->parent, - 'description' => $item->description, - 'display' => $display_type ? $display_type : 'default', - 'image' => null, - 'menu_order' => (int) $menu_order, - 'count' => (int) $item->count, - ); - - // Get category image. - $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); - if ( $image_id ) { - $attachment = get_post( $image_id ); - - $data['image'] = array( - 'id' => (int) $image_id, - 'date_created' => wc_rest_prepare_date_response( $attachment->post_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), - 'src' => wp_get_attachment_url( $image_id ), - 'title' => get_the_title( $attachment ), - 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), - ); - } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); - } - - /** - * Get the Category schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'default', - 'enum' => array( 'default', 'products', 'subcategories', 'both' ), - 'context' => array( 'view', 'edit' ), - ), - 'image' => array( - 'description' => __( 'Image data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'title' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php deleted file mode 100644 index a90d4ad232e..00000000000 --- a/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php +++ /dev/null @@ -1,199 +0,0 @@ -/reviews. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Product Reviews Controller Class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Product_Reviews_V1_Controller - */ -class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'products/(?P[\d]+)/reviews'; - - /** - * Register the routes for product reviews. - */ - public function register_routes() { - parent::register_routes(); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) - ); - } - - /** - * Check if a given request has access to batch manage product reviews. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( 'product', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Prepare a single product review output for response. - * - * @param WP_Comment $review Product review object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $review, $request ) { - $data = array( - 'id' => (int) $review->comment_ID, - 'date_created' => wc_rest_prepare_date_response( $review->comment_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $review->comment_date_gmt ), - 'review' => $review->comment_content, - 'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ), - 'name' => $review->comment_author, - 'email' => $review->comment_author_email, - 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), - ); - - $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( $review, $request ) ); - - /** - * Filter product reviews object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_Comment $review Product review object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); - } - - - /** - * Bulk create, update and delete items. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array Of WP_Error or WP_REST_Response. - */ - public function batch_items( $request ) { - $items = array_filter( $request->get_params() ); - $params = $request->get_url_params(); - $product_id = $params['product_id']; - $body_params = array(); - - foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { - if ( ! empty( $items[ $batch_type ] ) ) { - $injected_items = array(); - foreach ( $items[ $batch_type ] as $item ) { - $injected_items[] = is_array( $item ) ? array_merge( array( 'product_id' => $product_id ), $item ) : $item; - } - $body_params[ $batch_type ] = $injected_items; - } - } - - $request = new WP_REST_Request( $request->get_method() ); - $request->set_body_params( $body_params ); - - return parent::batch_items( $request ); - } - - /** - * Get the Product Review's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_review', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the review was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php deleted file mode 100644 index 6430ded093f..00000000000 --- a/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/variations endpoints. - * - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API variations controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Products_V2_Controller - */ -class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'products/(?P[\d]+)/variations'; - - /** - * Post type. - * - * @var string - */ - protected $post_type = 'product_variation'; - - /** - * Register the routes for products. - */ - public function register_routes() { - register_rest_route( - $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', array( - 'args' => array( - 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) - ); - } - - /** - * Get object. - * - * @since 3.0.0 - * @param int $id Object ID. - * @return WC_Data - */ - protected function get_object( $id ) { - return wc_get_product( $id ); - } - - /** - * Check if a given request has access to update an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - // Check if variation belongs to the correct parent product. - if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Prepare a single variation output for response. - * - * @since 3.0.0 - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $data = array( - 'id' => $object->get_id(), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), - 'description' => wc_format_content( $object->get_description() ), - 'permalink' => $object->get_permalink(), - 'sku' => $object->get_sku(), - 'price' => $object->get_price(), - 'regular_price' => $object->get_regular_price(), - 'sale_price' => $object->get_sale_price(), - 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), - 'on_sale' => $object->is_on_sale(), - 'visible' => $object->is_visible(), - 'purchasable' => $object->is_purchasable(), - 'virtual' => $object->is_virtual(), - 'downloadable' => $object->is_downloadable(), - 'downloads' => $this->get_downloads( $object ), - 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, - 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, - 'tax_status' => $object->get_tax_status(), - 'tax_class' => $object->get_tax_class(), - 'manage_stock' => $object->managing_stock(), - 'stock_quantity' => $object->get_stock_quantity(), - 'in_stock' => $object->is_in_stock(), - 'backorders' => $object->get_backorders(), - 'backorders_allowed' => $object->backorders_allowed(), - 'backordered' => $object->is_on_backorder(), - 'weight' => $object->get_weight(), - 'dimensions' => array( - 'length' => $object->get_length(), - 'width' => $object->get_width(), - 'height' => $object->get_height(), - ), - 'shipping_class' => $object->get_shipping_class(), - 'shipping_class_id' => $object->get_shipping_class_id(), - 'image' => current( $this->get_images( $object ) ), - 'attributes' => $this->get_attributes( $object ), - 'menu_order' => $object->get_menu_order(), - 'meta_data' => $object->get_meta_data(), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - $args['post_parent'] = $request['product_id']; - - return $args; - } - - /** - * Prepare a single variation for create or update. - * - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - if ( isset( $request['id'] ) ) { - $variation = wc_get_product( absint( $request['id'] ) ); - } else { - $variation = new WC_Product_Variation(); - } - - // Update parent ID just once. - if ( 0 === $variation->get_parent_id() ) { - $variation->set_parent_id( absint( $request['product_id'] ) ); - } - - // Status. - if ( isset( $request['visible'] ) ) { - $variation->set_status( false === $request['visible'] ? 'private' : 'publish' ); - } - - // SKU. - if ( isset( $request['sku'] ) ) { - $variation->set_sku( wc_clean( $request['sku'] ) ); - } - - // Thumbnail. - if ( isset( $request['image'] ) ) { - if ( is_array( $request['image'] ) && ! empty( $request['image'] ) ) { - $image = $request['image']; - if ( is_array( $image ) ) { - $image['position'] = 0; - } - - $variation = $this->set_product_images( $variation, array( $image ) ); - } else { - $variation->set_image_id( '' ); - } - } - - // Virtual variation. - if ( isset( $request['virtual'] ) ) { - $variation->set_virtual( $request['virtual'] ); - } - - // Downloadable variation. - if ( isset( $request['downloadable'] ) ) { - $variation->set_downloadable( $request['downloadable'] ); - } - - // Downloads. - if ( $variation->get_downloadable() ) { - // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); - } - - // Download limit. - if ( isset( $request['download_limit'] ) ) { - $variation->set_download_limit( $request['download_limit'] ); - } - - // Download expiry. - if ( isset( $request['download_expiry'] ) ) { - $variation->set_download_expiry( $request['download_expiry'] ); - } - } - - // Shipping data. - $variation = $this->save_product_shipping_data( $variation, $request ); - - // Stock handling. - if ( isset( $request['manage_stock'] ) ) { - if ( 'parent' === $request['manage_stock'] ) { - $variation->set_manage_stock( false ); // This just indicates the variation does not manage stock, but the parent does. - } else { - $variation->set_manage_stock( wc_string_to_bool( $request['manage_stock'] ) ); - } - } - - if ( isset( $request['in_stock'] ) ) { - $variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' ); - } - - if ( isset( $request['backorders'] ) ) { - $variation->set_backorders( $request['backorders'] ); - } - - if ( $variation->get_manage_stock() ) { - if ( isset( $request['stock_quantity'] ) ) { - $variation->set_stock_quantity( $request['stock_quantity'] ); - } elseif ( isset( $request['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); - $variation->set_stock_quantity( $stock_quantity ); - } - } else { - $variation->set_backorders( 'no' ); - $variation->set_stock_quantity( '' ); - } - - // Regular Price. - if ( isset( $request['regular_price'] ) ) { - $variation->set_regular_price( $request['regular_price'] ); - } - - // Sale Price. - if ( isset( $request['sale_price'] ) ) { - $variation->set_sale_price( $request['sale_price'] ); - } - - if ( isset( $request['date_on_sale_from'] ) ) { - $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); - } - - if ( isset( $request['date_on_sale_from_gmt'] ) ) { - $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); - } - - if ( isset( $request['date_on_sale_to'] ) ) { - $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); - } - - if ( isset( $request['date_on_sale_to_gmt'] ) ) { - $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); - } - - // Tax class. - if ( isset( $request['tax_class'] ) ) { - $variation->set_tax_class( $request['tax_class'] ); - } - - // Description. - if ( isset( $request['description'] ) ) { - $variation->set_description( wp_kses_post( $request['description'] ) ); - } - - // Update taxonomies. - if ( isset( $request['attributes'] ) ) { - $attributes = array(); - $parent = wc_get_product( $variation->get_parent_id() ); - $parent_attributes = $parent->get_attributes(); - - foreach ( $request['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $raw_attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $raw_attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $raw_attribute_name ) { - continue; - } - - $attribute_name = sanitize_title( $raw_attribute_name ); - - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { - continue; - } - - $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); - $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $raw_attribute_name ); // @codingStandardsIgnoreLine - - if ( $term && ! is_wp_error( $term ) ) { - $attribute_value = $term->slug; - } else { - $attribute_value = sanitize_title( $attribute_value ); - } - } - - $attributes[ $attribute_key ] = $attribute_value; - } - - $variation->set_attributes( $attributes ); - } - - // Menu order. - if ( $request['menu_order'] ) { - $variation->set_menu_order( $request['menu_order'] ); - } - - // Meta data. - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $variation Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); - } - - /** - * Clear caches here so in sync with any new variations. - * - * @param WC_Data $object Object data. - */ - public function clear_transients( $object ) { - wc_delete_product_transients( $object->get_parent_id() ); - wp_cache_delete( 'product-' . $object->get_parent_id(), 'products' ); - } - - /** - * Delete a variation. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return bool|WP_Error|WP_REST_Response - */ - public function delete_item( $request ) { - $force = (bool) $request['force']; - $object = $this->get_object( (int) $request['id'] ); - $result = false; - - if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( - "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( - 'status' => 404, - ) - ); - } - - $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); - - /** - * Filter whether an object is trashable. - * - * Return false to disable trash support for the object. - * - * @param boolean $supports_trash Whether the object type support trashing. - * @param WC_Data $object The object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - return new WP_Error( - /* translators: %s: post type */ - "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); - - // If we're forcing, then delete permanently. - if ( $force ) { - $object->delete( true ); - $result = 0 === $object->get_id(); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - return new WP_Error( - /* translators: %s: post type */ - 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( - 'status' => 501, - ) - ); - } - - // Otherwise, only trash if we haven't already. - if ( is_callable( array( $object, 'get_status' ) ) ) { - if ( 'trash' === $object->get_status() ) { - return new WP_Error( - /* translators: %s: post type */ - 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( - 'status' => 410, - ) - ); - } - - $object->delete(); - $result = 'trash' === $object->get_status(); - } - } - - if ( ! $result ) { - return new WP_Error( - /* translators: %s: post type */ - 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( - 'status' => 500, - ) - ); - } - - // Delete parent product transients. - if ( 0 !== $object->get_parent_id() ) { - wc_delete_product_transients( $object->get_parent_id() ); - } - - /** - * Fires after a single object is deleted or trashed via the REST API. - * - * @param WC_Data $object The deleted or trashed object. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); - - return $response; - } - - /** - * Bulk create, update and delete items. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array Of WP_Error or WP_REST_Response. - */ - public function batch_items( $request ) { - $items = array_filter( $request->get_params() ); - $params = $request->get_url_params(); - $query = $request->get_query_params(); - $product_id = $params['product_id']; - $body_params = array(); - - foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { - if ( ! empty( $items[ $batch_type ] ) ) { - $injected_items = array(); - foreach ( $items[ $batch_type ] as $item ) { - $injected_items[] = is_array( $item ) ? array_merge( - array( - 'product_id' => $product_id, - ), $item - ) : $item; - } - $body_params[ $batch_type ] = $injected_items; - } - } - - $request = new WP_REST_Request( $request->get_method() ); - $request->set_body_params( $body_params ); - $request->set_query_params( $query ); - - return parent::batch_items( $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return array Links for the given post. - */ - protected function prepare_links( $object, $request ) { - $product_id = (int) $request['product_id']; - $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), - ), - ); - return $links; - } - - /** - * Get the Variation's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( 'End date of sale price, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'visible' => array( - 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'in_stock' => array( - 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php b/src/Controllers/Version2/class-wc-rest-products-v2-controller.php deleted file mode 100644 index f38ecb7dfb9..00000000000 --- a/src/Controllers/Version2/class-wc-rest-products-v2-controller.php +++ /dev/null @@ -1,2209 +0,0 @@ -post_type}_object", array( $this, 'clear_transients' ) ); - } - - /** - * Register the routes for products. - */ - public function register_routes() { - register_rest_route( - $this->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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( - array( - 'default' => 'view', - ) - ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) - ); - } - - /** - * Get object. - * - * @param int $id Object ID. - * - * @since 3.0.0 - * @return WC_Data - */ - protected function get_object( $id ) { - return wc_get_product( $id ); - } - - /** - * Prepare a single product output for response. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * - * @since 3.0.0 - * @return WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->get_product_data( $object, $context ); - - // Add variations to variable products. - if ( $object->is_type( 'variable' ) && $object->has_child() ) { - $data['variations'] = $object->get_children(); - } - - // Add grouped products data. - if ( $object->is_type( 'grouped' ) && $object->has_child() ) { - $data['grouped_products'] = $object->get_children(); - } - - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - - /** - * Prepare objects query. - * - * @param WP_REST_Request $request Full details about the request. - * - * @since 3.0.0 - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = parent::prepare_objects_query( $request ); - - // Set post_status. - $args['post_status'] = $request['status']; - - // Taxonomy query to filter products by type, category, - // tag, shipping class, and attribute. - $tax_query = array(); - - // Map between taxonomy name and arg's key. - $taxonomies = array( - 'product_cat' => 'category', - 'product_tag' => 'tag', - 'product_shipping_class' => 'shipping_class', - ); - - // Set tax_query for each passed arg. - foreach ( $taxonomies as $taxonomy => $key ) { - if ( ! empty( $request[ $key ] ) ) { - $tax_query[] = array( - 'taxonomy' => $taxonomy, - 'field' => 'term_id', - 'terms' => $request[ $key ], - ); - } - } - - // Filter product type by slug. - if ( ! empty( $request['type'] ) ) { - $tax_query[] = array( - 'taxonomy' => 'product_type', - 'field' => 'slug', - 'terms' => $request['type'], - ); - } - - // Filter by attribute and term. - if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { - if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { - $tax_query[] = array( - 'taxonomy' => $request['attribute'], - 'field' => 'term_id', - 'terms' => $request['attribute_term'], - ); - } - } - - if ( ! empty( $tax_query ) ) { - $args['tax_query'] = $tax_query; // WPCS: slow query ok. - } - - // Filter featured. - if ( is_bool( $request['featured'] ) ) { - $args['tax_query'][] = array( - 'taxonomy' => 'product_visibility', - 'field' => 'name', - 'terms' => 'featured', - 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', - ); - } - - // Filter by sku. - if ( ! empty( $request['sku'] ) ) { - $skus = explode( ',', $request['sku'] ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $request['sku']; - } - - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', - ) - ); - } - - // Filter by tax class. - if ( ! empty( $request['tax_class'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_tax_class', - 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', - ) - ); - } - - // Price filter. - if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { - $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. - } - - // Filter product in stock or out of stock. - if ( is_bool( $request['in_stock'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_stock_status', - 'value' => true === $request['in_stock'] ? 'instock' : 'outofstock', - ) - ); - } - - // Filter by on sale products. - if ( is_bool( $request['on_sale'] ) ) { - $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; - $on_sale_ids = wc_get_product_ids_on_sale(); - - // Use 0 when there's no on sale products to avoid return all products. - $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; - - $args[ $on_sale_key ] += $on_sale_ids; - } - - // Force the post_type argument, since it's not a user input variable. - if ( ! empty( $request['sku'] ) ) { - $args['post_type'] = array( 'product', 'product_variation' ); - } else { - $args['post_type'] = $this->post_type; - } - - return $args; - } - - /** - * Get the downloads for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * - * @return array - */ - protected function get_downloads( $product ) { - $downloads = array(); - - if ( $product->is_downloadable() ) { - foreach ( $product->get_downloads() as $file_id => $file ) { - $downloads[] = array( - 'id' => $file_id, // MD5 hash. - 'name' => $file['name'], - 'file' => $file['file'], - ); - } - } - - return $downloads; - } - - /** - * Get taxonomy terms. - * - * @param WC_Product $product Product instance. - * @param string $taxonomy Taxonomy slug. - * - * @return array - */ - protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { - $terms = array(); - - foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { - $terms[] = array( - 'id' => $term->term_id, - 'name' => $term->name, - 'slug' => $term->slug, - ); - } - - return $terms; - } - - /** - * Get the images for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * - * @return array - */ - protected function get_images( $product ) { - $images = array(); - $attachment_ids = array(); - - // Add featured image. - if ( $product->get_image_id() ) { - $attachment_ids[] = $product->get_image_id(); - } - - // Add gallery images. - $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); - - // Build image data. - foreach ( $attachment_ids as $position => $attachment_id ) { - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - continue; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - continue; - } - - $images[] = array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - 'position' => (int) $position, - ); - } - - // Set a placeholder image if the product has no images set. - if ( empty( $images ) ) { - $images[] = array( - 'id' => 0, - 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), // Default to now. - 'date_created_gmt' => wc_rest_prepare_date_response( time() ), // Default to now. - 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( time() ), - 'src' => wc_placeholder_img_src(), - 'name' => __( 'Placeholder', 'woocommerce-rest-api' ), - 'alt' => __( 'Placeholder', 'woocommerce-rest-api' ), - 'position' => 0, - ); - } - - return $images; - } - - /** - * Get attribute taxonomy label. - * - * @param string $name Taxonomy name. - * - * @deprecated 3.0.0 - * @return string - */ - protected function get_attribute_taxonomy_label( $name ) { - $tax = get_taxonomy( $name ); - $labels = get_taxonomy_labels( $tax ); - - return $labels->singular_name; - } - - /** - * Get product attribute taxonomy name. - * - * @param string $slug Taxonomy name. - * @param WC_Product $product Product data. - * - * @since 3.0.0 - * @return string - */ - protected function get_attribute_taxonomy_name( $slug, $product ) { - // Format slug so it matches attributes of the product. - $slug = wc_attribute_taxonomy_slug( $slug ); - $attributes = $product->get_attributes(); - $attribute = false; - - // pa_ attributes. - if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { - $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; - } elseif ( isset( $attributes[ $slug ] ) ) { - $attribute = $attributes[ $slug ]; - } - - if ( ! $attribute ) { - return $slug; - } - - // Taxonomy attribute name. - if ( $attribute->is_taxonomy() ) { - $taxonomy = $attribute->get_taxonomy_object(); - return $taxonomy->attribute_label; - } - - // Custom product attribute name. - return $attribute->get_name(); - } - - /** - * Get default attributes. - * - * @param WC_Product $product Product instance. - * - * @return array - */ - protected function get_default_attributes( $product ) { - $default = array(); - - if ( $product->is_type( 'variable' ) ) { - foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { - if ( 0 === strpos( $key, 'pa_' ) ) { - $default[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $key ), - 'name' => $this->get_attribute_taxonomy_name( $key, $product ), - 'option' => $value, - ); - } else { - $default[] = array( - 'id' => 0, - 'name' => $this->get_attribute_taxonomy_name( $key, $product ), - 'option' => $value, - ); - } - } - } - - return $default; - } - - /** - * Get attribute options. - * - * @param int $product_id Product ID. - * @param array $attribute Attribute data. - * - * @return array - */ - protected function get_attribute_options( $product_id, $attribute ) { - if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { - return wc_get_product_terms( - $product_id, - $attribute['name'], - array( - 'fields' => 'names', - ) - ); - } elseif ( isset( $attribute['value'] ) ) { - return array_map( 'trim', explode( '|', $attribute['value'] ) ); - } - - return array(); - } - - /** - * Get the attributes for a product or product variation. - * - * @param WC_Product|WC_Product_Variation $product Product instance. - * - * @return array - */ - protected function get_attributes( $product ) { - $attributes = array(); - - if ( $product->is_type( 'variation' ) ) { - $_product = wc_get_product( $product->get_parent_id() ); - foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { - $name = str_replace( 'attribute_', '', $attribute_name ); - - if ( empty( $attribute ) && '0' !== $attribute ) { - continue; - } - - // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. - if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { - $option_term = get_term_by( 'slug', $attribute, $name ); - $attributes[] = array( - 'id' => wc_attribute_taxonomy_id_by_name( $name ), - 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), - 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, - ); - } else { - $attributes[] = array( - 'id' => 0, - 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), - 'option' => $attribute, - ); - } - } - } else { - foreach ( $product->get_attributes() as $attribute ) { - $attributes[] = array( - 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, - 'name' => $this->get_attribute_taxonomy_name( $attribute['name'], $product ), - 'position' => (int) $attribute['position'], - 'visible' => (bool) $attribute['is_visible'], - 'variation' => (bool) $attribute['is_variation'], - 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), - ); - } - } - - return $attributes; - } - - /** - * Get product data. - * - * @param WC_Product $product Product instance. - * @param string $context Request context. - * Options: 'view' and 'edit'. - * - * @return array - */ - protected function get_product_data( $product, $context = 'view' ) { - $data = array( - 'id' => $product->get_id(), - 'name' => $product->get_name( $context ), - 'slug' => $product->get_slug( $context ), - 'permalink' => $product->get_permalink(), - 'date_created' => wc_rest_prepare_date_response( $product->get_date_created( $context ), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $product->get_date_created( $context ) ), - 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified( $context ), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $product->get_date_modified( $context ) ), - 'type' => $product->get_type(), - 'status' => $product->get_status( $context ), - 'featured' => $product->is_featured(), - 'catalog_visibility' => $product->get_catalog_visibility( $context ), - 'description' => 'view' === $context ? wpautop( do_shortcode( $product->get_description() ) ) : $product->get_description( $context ), - 'short_description' => 'view' === $context ? apply_filters( 'woocommerce_short_description', $product->get_short_description() ) : $product->get_short_description( $context ), - 'sku' => $product->get_sku( $context ), - 'price' => $product->get_price( $context ), - 'regular_price' => $product->get_regular_price( $context ), - 'sale_price' => $product->get_sale_price( $context ) ? $product->get_sale_price( $context ) : '', - 'date_on_sale_from' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ) ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ) ), - 'price_html' => $product->get_price_html(), - 'on_sale' => $product->is_on_sale( $context ), - 'purchasable' => $product->is_purchasable(), - 'total_sales' => $product->get_total_sales( $context ), - 'virtual' => $product->is_virtual(), - 'downloadable' => $product->is_downloadable(), - 'downloads' => $this->get_downloads( $product ), - 'download_limit' => $product->get_download_limit( $context ), - 'download_expiry' => $product->get_download_expiry( $context ), - 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url( $context ) : '', - 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text( $context ) : '', - 'tax_status' => $product->get_tax_status( $context ), - 'tax_class' => $product->get_tax_class( $context ), - 'manage_stock' => $product->managing_stock(), - 'stock_quantity' => $product->get_stock_quantity( $context ), - 'in_stock' => $product->is_in_stock(), - 'backorders' => $product->get_backorders( $context ), - 'backorders_allowed' => $product->backorders_allowed(), - 'backordered' => $product->is_on_backorder(), - 'sold_individually' => $product->is_sold_individually(), - 'weight' => $product->get_weight( $context ), - 'dimensions' => array( - 'length' => $product->get_length( $context ), - 'width' => $product->get_width( $context ), - 'height' => $product->get_height( $context ), - ), - 'shipping_required' => $product->needs_shipping(), - 'shipping_taxable' => $product->is_shipping_taxable(), - 'shipping_class' => $product->get_shipping_class(), - 'shipping_class_id' => $product->get_shipping_class_id( $context ), - 'reviews_allowed' => $product->get_reviews_allowed( $context ), - 'average_rating' => 'view' === $context ? wc_format_decimal( $product->get_average_rating(), 2 ) : $product->get_average_rating( $context ), - 'rating_count' => $product->get_rating_count(), - 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), - 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids( $context ) ), - 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids( $context ) ), - 'parent_id' => $product->get_parent_id( $context ), - 'purchase_note' => 'view' === $context ? wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ) : $product->get_purchase_note( $context ), - 'categories' => $this->get_taxonomy_terms( $product ), - 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), - 'images' => $this->get_images( $product ), - 'attributes' => $this->get_attributes( $product ), - 'default_attributes' => $this->get_default_attributes( $product ), - 'variations' => array(), - 'grouped_products' => array(), - 'menu_order' => $product->get_menu_order( $context ), - 'meta_data' => $product->get_meta_data(), - ); - - return $data; - } - - /** - * Prepare links for the request. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * - * @return array Links for the given post. - */ - protected function prepare_links( $object, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), // @codingStandardsIgnoreLine. - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), // @codingStandardsIgnoreLine. - ), - ); - - if ( $object->get_parent_id() ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $object->get_parent_id() ) ), // @codingStandardsIgnoreLine. - ); - } - - return $links; - } - - /** - * Prepare a single product for create or update. - * - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * - * @return WP_Error|WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - - // Type is the most important part here because we need to be using the correct class and methods. - if ( isset( $request['type'] ) ) { - $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); - - if ( ! class_exists( $classname ) ) { - $classname = 'WC_Product_Simple'; - } - - $product = new $classname( $id ); - } elseif ( isset( $request['id'] ) ) { - $product = wc_get_product( $id ); - } else { - $product = new WC_Product_Simple(); - } - - if ( 'variation' === $product->get_type() ) { - return new WP_Error( - "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), - array( - 'status' => 404, - ) - ); - } - - // Post title. - if ( isset( $request['name'] ) ) { - $product->set_name( wp_filter_post_kses( $request['name'] ) ); - } - - // Post content. - if ( isset( $request['description'] ) ) { - $product->set_description( wp_filter_post_kses( $request['description'] ) ); - } - - // Post excerpt. - if ( isset( $request['short_description'] ) ) { - $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); - } - - // Post status. - if ( isset( $request['status'] ) ) { - $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); - } - - // Post slug. - if ( isset( $request['slug'] ) ) { - $product->set_slug( $request['slug'] ); - } - - // Menu order. - if ( isset( $request['menu_order'] ) ) { - $product->set_menu_order( $request['menu_order'] ); - } - - // Comment status. - if ( isset( $request['reviews_allowed'] ) ) { - $product->set_reviews_allowed( $request['reviews_allowed'] ); - } - - // Virtual. - if ( isset( $request['virtual'] ) ) { - $product->set_virtual( $request['virtual'] ); - } - - // Tax status. - if ( isset( $request['tax_status'] ) ) { - $product->set_tax_status( $request['tax_status'] ); - } - - // Tax Class. - if ( isset( $request['tax_class'] ) ) { - $product->set_tax_class( $request['tax_class'] ); - } - - // Catalog Visibility. - if ( isset( $request['catalog_visibility'] ) ) { - $product->set_catalog_visibility( $request['catalog_visibility'] ); - } - - // Purchase Note. - if ( isset( $request['purchase_note'] ) ) { - $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); - } - - // Featured Product. - if ( isset( $request['featured'] ) ) { - $product->set_featured( $request['featured'] ); - } - - // Shipping data. - $product = $this->save_product_shipping_data( $product, $request ); - - // SKU. - if ( isset( $request['sku'] ) ) { - $product->set_sku( wc_clean( $request['sku'] ) ); - } - - // Attributes. - if ( isset( $request['attributes'] ) ) { - $attributes = array(); - - foreach ( $request['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = wc_clean( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( $attribute_id ) { - - if ( isset( $attribute['options'] ) ) { - $options = $attribute['options']; - - if ( ! is_array( $attribute['options'] ) ) { - // Text based attributes - Posted values are term names. - $options = explode( WC_DELIMITER, $options ); - } - - $values = array_map( 'wc_sanitize_term_text_based', $options ); - $values = array_filter( $values, 'strlen' ); - } else { - $values = array(); - } - - if ( ! empty( $values ) ) { - // Add attribute to array, but don't set values. - $attribute_object = new WC_Product_Attribute(); - $attribute_object->set_id( $attribute_id ); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } elseif ( isset( $attribute['options'] ) ) { - // Custom attribute - Add attribute to array and set the values. - if ( is_array( $attribute['options'] ) ) { - $values = $attribute['options']; - } else { - $values = explode( WC_DELIMITER, $attribute['options'] ); - } - $attribute_object = new WC_Product_Attribute(); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } - $product->set_attributes( $attributes ); - } - - // Sales and prices. - if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { - $product->set_regular_price( '' ); - $product->set_sale_price( '' ); - $product->set_date_on_sale_to( '' ); - $product->set_date_on_sale_from( '' ); - $product->set_price( '' ); - } else { - // Regular Price. - if ( isset( $request['regular_price'] ) ) { - $product->set_regular_price( $request['regular_price'] ); - } - - // Sale Price. - if ( isset( $request['sale_price'] ) ) { - $product->set_sale_price( $request['sale_price'] ); - } - - if ( isset( $request['date_on_sale_from'] ) ) { - $product->set_date_on_sale_from( $request['date_on_sale_from'] ); - } - - if ( isset( $request['date_on_sale_from_gmt'] ) ) { - $product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); - } - - if ( isset( $request['date_on_sale_to'] ) ) { - $product->set_date_on_sale_to( $request['date_on_sale_to'] ); - } - - if ( isset( $request['date_on_sale_to_gmt'] ) ) { - $product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); - } - } - - // Product parent ID. - if ( isset( $request['parent_id'] ) ) { - $product->set_parent_id( $request['parent_id'] ); - } - - // Sold individually. - if ( isset( $request['sold_individually'] ) ) { - $product->set_sold_individually( $request['sold_individually'] ); - } - - // Stock status. - if ( isset( $request['in_stock'] ) ) { - $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; - } else { - $stock_status = $product->get_stock_status(); - } - - // Stock data. - if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { - // Manage stock. - if ( isset( $request['manage_stock'] ) ) { - $product->set_manage_stock( $request['manage_stock'] ); - } - - // Backorders. - if ( isset( $request['backorders'] ) ) { - $product->set_backorders( $request['backorders'] ); - } - - if ( $product->is_type( 'grouped' ) ) { - $product->set_manage_stock( 'no' ); - $product->set_backorders( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( $stock_status ); - } elseif ( $product->is_type( 'external' ) ) { - $product->set_manage_stock( 'no' ); - $product->set_backorders( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( 'instock' ); - } elseif ( $product->get_manage_stock() ) { - // Stock status is always determined by children so sync later. - if ( ! $product->is_type( 'variable' ) ) { - $product->set_stock_status( $stock_status ); - } - - // Stock quantity. - if ( isset( $request['stock_quantity'] ) ) { - $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); - } elseif ( isset( $request['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); - $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); - } - } else { - // Don't manage stock. - $product->set_manage_stock( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( $stock_status ); - } - } elseif ( ! $product->is_type( 'variable' ) ) { - $product->set_stock_status( $stock_status ); - } - - // Upsells. - if ( isset( $request['upsell_ids'] ) ) { - $upsells = array(); - $ids = $request['upsell_ids']; - - if ( ! empty( $ids ) ) { - foreach ( $ids as $id ) { - if ( $id && $id > 0 ) { - $upsells[] = $id; - } - } - } - - $product->set_upsell_ids( $upsells ); - } - - // Cross sells. - if ( isset( $request['cross_sell_ids'] ) ) { - $crosssells = array(); - $ids = $request['cross_sell_ids']; - - if ( ! empty( $ids ) ) { - foreach ( $ids as $id ) { - if ( $id && $id > 0 ) { - $crosssells[] = $id; - } - } - } - - $product->set_cross_sell_ids( $crosssells ); - } - - // Product categories. - if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { - $product = $this->save_taxonomy_terms( $product, $request['categories'] ); - } - - // Product tags. - if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { - $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); - } - - // Downloadable. - if ( isset( $request['downloadable'] ) ) { - $product->set_downloadable( $request['downloadable'] ); - } - - // Downloadable options. - if ( $product->get_downloadable() ) { - - // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - $product = $this->save_downloadable_files( $product, $request['downloads'] ); - } - - // Download limit. - if ( isset( $request['download_limit'] ) ) { - $product->set_download_limit( $request['download_limit'] ); - } - - // Download expiry. - if ( isset( $request['download_expiry'] ) ) { - $product->set_download_expiry( $request['download_expiry'] ); - } - } - - // Product url and button text for external products. - if ( $product->is_type( 'external' ) ) { - if ( isset( $request['external_url'] ) ) { - $product->set_product_url( $request['external_url'] ); - } - - if ( isset( $request['button_text'] ) ) { - $product->set_button_text( $request['button_text'] ); - } - } - - // Save default attributes for variable products. - if ( $product->is_type( 'variable' ) ) { - $product = $this->save_default_attributes( $product, $request ); - } - - // Set children for a grouped product. - if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { - $product->set_children( $request['grouped_products'] ); - } - - // Check for featured/gallery images, upload it and set it. - if ( isset( $request['images'] ) ) { - $product = $this->set_product_images( $product, $request['images'] ); - } - - // Allow set meta_data. - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $product Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); - } - - /** - * Set product images. - * - * @param WC_Product $product Product instance. - * @param array $images Images data. - * - * @throws WC_REST_Exception REST API exceptions. - * @return WC_Product - */ - protected function set_product_images( $product, $images ) { - $images = is_array( $images ) ? array_filter( $images ) : array(); - - if ( ! empty( $images ) ) { - $gallery_positions = array(); - - foreach ( $images as $index => $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { - throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); - } else { - continue; - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: attachment id */ - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); - } - - $gallery_positions[ $attachment_id ] = absint( isset( $image['position'] ) ? $image['position'] : $index ); - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); - } - - // Set the image source if present, for future reference. - if ( ! empty( $image['src'] ) ) { - update_post_meta( $attachment_id, '_wc_attachment_source', esc_url_raw( $image['src'] ) ); - } - } - - // Sort images and get IDs in correct order. - asort( $gallery_positions ); - - // Get gallery in correct order. - $gallery = array_keys( $gallery_positions ); - - // Featured image is in position 0. - $image_id = array_shift( $gallery ); - - // Set images. - $product->set_image_id( $image_id ); - $product->set_gallery_image_ids( $gallery ); - } else { - $product->set_image_id( '' ); - $product->set_gallery_image_ids( array() ); - } - - return $product; - } - - /** - * Save product shipping data. - * - * @param WC_Product $product Product instance. - * @param array $data Shipping data. - * - * @return WC_Product - */ - protected function save_product_shipping_data( $product, $data ) { - // Virtual. - if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { - $product->set_weight( '' ); - $product->set_height( '' ); - $product->set_length( '' ); - $product->set_width( '' ); - } else { - if ( isset( $data['weight'] ) ) { - $product->set_weight( $data['weight'] ); - } - - // Height. - if ( isset( $data['dimensions']['height'] ) ) { - $product->set_height( $data['dimensions']['height'] ); - } - - // Width. - if ( isset( $data['dimensions']['width'] ) ) { - $product->set_width( $data['dimensions']['width'] ); - } - - // Length. - if ( isset( $data['dimensions']['length'] ) ) { - $product->set_length( $data['dimensions']['length'] ); - } - } - - // Shipping class. - if ( isset( $data['shipping_class'] ) ) { - $data_store = $product->get_data_store(); - $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); - $product->set_shipping_class_id( $shipping_class_id ); - } - - return $product; - } - - /** - * Save downloadable files. - * - * @param WC_Product $product Product instance. - * @param array $downloads Downloads data. - * @param int $deprecated Deprecated since 3.0. - * - * @return WC_Product - */ - protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { - if ( $deprecated ) { - wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); - } - - $files = array(); - foreach ( $downloads as $key => $file ) { - if ( empty( $file['file'] ) ) { - continue; - } - - $download = new WC_Product_Download(); - $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); - $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); - $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); - $files[] = $download; - } - $product->set_downloads( $files ); - - return $product; - } - - /** - * Save taxonomy terms. - * - * @param WC_Product $product Product instance. - * @param array $terms Terms data. - * @param string $taxonomy Taxonomy name. - * - * @return WC_Product - */ - protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { - $term_ids = wp_list_pluck( $terms, 'id' ); - - if ( 'cat' === $taxonomy ) { - $product->set_category_ids( $term_ids ); - } elseif ( 'tag' === $taxonomy ) { - $product->set_tag_ids( $term_ids ); - } - - return $product; - } - - /** - * Save default attributes. - * - * @param WC_Product $product Product instance. - * @param WP_REST_Request $request Request data. - * - * @since 3.0.0 - * @return WC_Product - */ - protected function save_default_attributes( $product, $request ) { - if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { - - $attributes = $product->get_attributes(); - $default_attributes = array(); - - foreach ( $request['default_attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( isset( $attributes[ $attribute_name ] ) ) { - $_attribute = $attributes[ $attribute_name ]; - - if ( $_attribute['is_variation'] ) { - $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( ! empty( $_attribute['is_taxonomy'] ) ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $value = $term->slug; - } else { - $value = sanitize_title( $value ); - } - } - - if ( $value ) { - $default_attributes[ $attribute_name ] = $value; - } - } - } - } - - $product->set_default_attributes( $default_attributes ); - } - - return $product; - } - - /** - * Clear caches here so in sync with any new variations/children. - * - * @param WC_Data $object Object data. - */ - public function clear_transients( $object ) { - wc_delete_product_transients( $object->get_id() ); - wp_cache_delete( 'product-' . $object->get_id(), 'products' ); - } - - /** - * Delete a single item. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_REST_Response|WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = (bool) $request['force']; - $object = $this->get_object( (int) $request['id'] ); - $result = false; - - if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( - "woocommerce_rest_{$this->post_type}_invalid_id", - __( 'Invalid ID.', 'woocommerce-rest-api' ), - array( - 'status' => 404, - ) - ); - } - - if ( 'variation' === $object->get_type() ) { - return new WP_Error( - "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), - array( - 'status' => 404, - ) - ); - } - - $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); - - /** - * Filter whether an object is trashable. - * - * Return false to disable trash support for the object. - * - * @param boolean $supports_trash Whether the object type support trashing. - * @param WC_Data $object The object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - return new WP_Error( - "woocommerce_rest_user_cannot_delete_{$this->post_type}", - /* translators: %s: post type */ - sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), - array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); - - // If we're forcing, then delete permanently. - if ( $force ) { - if ( $object->is_type( 'variable' ) ) { - foreach ( $object->get_children() as $child_id ) { - $child = wc_get_product( $child_id ); - if ( ! empty( $child ) ) { - $child->delete( true ); - } - } - } else { - // For other product types, if the product has children, remove the relationship. - foreach ( $object->get_children() as $child_id ) { - $child = wc_get_product( $child_id ); - if ( ! empty( $child ) ) { - $child->set_parent_id( 0 ); - $child->save(); - } - } - } - - $object->delete( true ); - $result = 0 === $object->get_id(); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - return new WP_Error( - 'woocommerce_rest_trash_not_supported', - /* translators: %s: post type */ - sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), - array( - 'status' => 501, - ) - ); - } - - // Otherwise, only trash if we haven't already. - if ( is_callable( array( $object, 'get_status' ) ) ) { - if ( 'trash' === $object->get_status() ) { - return new WP_Error( - 'woocommerce_rest_already_trashed', - /* translators: %s: post type */ - sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), - array( - 'status' => 410, - ) - ); - } - - $object->delete(); - $result = 'trash' === $object->get_status(); - } - } - - if ( ! $result ) { - return new WP_Error( - 'woocommerce_rest_cannot_delete', - /* translators: %s: post type */ - sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), - array( - 'status' => 500, - ) - ); - } - - // Delete parent product transients. - if ( 0 !== $object->get_parent_id() ) { - wc_delete_product_transients( $object->get_parent_id() ); - } - - /** - * Fires after a single object is deleted or trashed via the REST API. - * - * @param WC_Data $object The deleted or trashed object. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); - - return $response; - } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'simple', - 'enum' => array_keys( wc_get_product_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), - 'context' => array( 'view', 'edit' ), - ), - 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'visible', - 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Product description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( 'End date of sale price, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'in_stock' => array( - 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'images' => array( - 'description' => __( 'List of images.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'string', - ), - ), - ), - ), - ), - 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'integer', - ), - 'readonly' => true, - ), - 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'menu_order' ) ); - - $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['status'] = array( - 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_merge( array( 'any', 'future', 'trash' ), array_keys( get_post_statuses() ) ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_types() ), - 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['sku'] = array( - 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['featured'] = array( - 'description' => __( 'Limit result set to featured products.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'wp_parse_id_list', - 'validate_callback' => 'rest_validate_request_arg', - ); - - if ( wc_tax_enabled() ) { - $params['tax_class'] = array( - 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - } - - $params['in_stock'] = array( - 'description' => __( 'Limit result set to products in stock or out of stock.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['on_sale'] = array( - 'description' => __( 'Limit result set to products on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'sanitize_callback' => 'wc_string_to_bool', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['min_price'] = array( - 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['max_price'] = array( - 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php b/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php deleted file mode 100644 index 4c5a873f351..00000000000 --- a/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -[\w-]+)'; - - /** - * Register routes. - * - * @since 3.0.0 - */ - public function register_routes() { - register_rest_route( - $this->namespace, '/' . $this->rest_base, array( - 'args' => array( - 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', array( - 'args' => array( - 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) - ); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( - 'args' => array( - 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Return a single setting. - * - * @since 3.0.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $setting = $this->get_setting( $request['group_id'], $request['id'] ); - - if ( is_wp_error( $setting ) ) { - return $setting; - } - - $response = $this->prepare_item_for_response( $setting, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Return all settings in a group. - * - * @since 3.0.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $settings = $this->get_group_settings( $request['group_id'] ); - - if ( is_wp_error( $settings ) ) { - return $settings; - } - - $data = array(); - - foreach ( $settings as $setting_obj ) { - $setting = $this->prepare_item_for_response( $setting_obj, $request ); - $setting = $this->prepare_response_for_collection( $setting ); - if ( $this->is_setting_type_valid( $setting['type'] ) ) { - $data[] = $setting; - } - } - - return rest_ensure_response( $data ); - } - - /** - * Get all settings in a group. - * - * @since 3.0.0 - * @param string $group_id Group ID. - * @return array|WP_Error - */ - public function get_group_settings( $group_id ) { - if ( empty( $group_id ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); - - if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $filtered_settings = array(); - foreach ( $settings as $setting ) { - $option_key = $setting['option_key']; - $setting = $this->filter_setting( $setting ); - $default = isset( $setting['default'] ) ? $setting['default'] : ''; - // Get the option value. - if ( is_array( $option_key ) ) { - $option = get_option( $option_key[0] ); - $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; - } else { - $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); - $setting['value'] = $admin_setting_value; - } - - if ( 'multi_select_countries' === $setting['type'] ) { - $setting['options'] = WC()->countries->get_countries(); - $setting['type'] = 'multiselect'; - } elseif ( 'single_select_country' === $setting['type'] ) { - $setting['type'] = 'select'; - $setting['options'] = $this->get_countries_and_states(); - } - - $filtered_settings[] = $setting; - } - - return $filtered_settings; - } - - /** - * Returns a list of countries and states for use in the base location setting. - * - * @since 3.0.7 - * @return array Array of states and countries. - */ - private function get_countries_and_states() { - $countries = WC()->countries->get_countries(); - if ( ! $countries ) { - return array(); - } - - $output = array(); - - foreach ( $countries as $key => $value ) { - $states = WC()->countries->get_states( $key ); - if ( $states ) { - foreach ( $states as $state_key => $state_value ) { - $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; - } - } else { - $output[ $key ] = $value; - } - } - - return $output; - } - - /** - * Get setting data. - * - * @since 3.0.0 - * @param string $group_id Group ID. - * @param string $setting_id Setting ID. - * @return stdClass|WP_Error - */ - public function get_setting( $group_id, $setting_id ) { - if ( empty( $setting_id ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $settings = $this->get_group_settings( $group_id ); - - if ( is_wp_error( $settings ) ) { - return $settings; - } - - $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); - - if ( empty( $array_key ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $setting = $settings[ $array_key[0] ]; - - if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - return $setting; - } - - /** - * Bulk create, update and delete items. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array Of WP_Error or WP_REST_Response. - */ - public function batch_items( $request ) { - // Get the request params. - $items = array_filter( $request->get_params() ); - - /* - * Since our batch settings update is group-specific and matches based on the route, - * we inject the URL parameters (containing group) into the batch items - */ - if ( ! empty( $items['update'] ) ) { - $to_update = array(); - foreach ( $items['update'] as $item ) { - $to_update[] = array_merge( $request->get_url_params(), $item ); - } - $request = new WP_REST_Request( $request->get_method() ); - $request->set_body_params( array( 'update' => $to_update ) ); - } - - return parent::batch_items( $request ); - } - - /** - * Update a single setting in a group. - * - * @since 3.0.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $setting = $this->get_setting( $request['group_id'], $request['id'] ); - - if ( is_wp_error( $setting ) ) { - return $setting; - } - - if ( is_callable( array( $this, 'validate_setting_' . $setting['type'] . '_field' ) ) ) { - $value = $this->{'validate_setting_' . $setting['type'] . '_field'}( $request['value'], $setting ); - } else { - $value = $this->validate_setting_text_field( $request['value'], $setting ); - } - - if ( is_wp_error( $value ) ) { - return $value; - } - - if ( is_array( $setting['option_key'] ) ) { - $setting['value'] = $value; - $option_key = $setting['option_key']; - $prev = get_option( $option_key[0] ); - $prev[ $option_key[1] ] = $request['value']; - update_option( $option_key[0], $prev ); - } else { - $update_data = array(); - $update_data[ $setting['option_key'] ] = $value; - $setting['value'] = $value; - WC_Admin_Settings::save_fields( array( $setting ), $update_data ); - } - - $response = $this->prepare_item_for_response( $setting, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Prepare a single setting object for response. - * - * @since 3.0.0 - * @param object $item Setting object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - unset( $item['option_key'] ); - $data = $this->filter_setting( $item ); - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, empty( $request['context'] ) ? 'view' : $request['context'] ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $data['id'], $request['group_id'] ) ); - return $response; - } - - /** - * Prepare links for the request. - * - * @since 3.0.0 - * @param string $setting_id Setting ID. - * @param string $group_id Group ID. - * @return array Links for the given setting. - */ - protected function prepare_links( $setting_id, $group_id ) { - $base = str_replace( '(?P[\w-]+)', $group_id, $this->rest_base ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $base, $setting_id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), - ), - ); - - return $links; - } - - /** - * Makes sure the current user has access to READ the settings APIs. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full data about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Makes sure the current user has access to WRITE the settings APIs. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full data about the request. - * @return WP_Error|boolean - */ - 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-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Filters out bad values from the settings array/filter so we - * only return known values via the API. - * - * @since 3.0.0 - * @param array $setting Settings. - * @return array - */ - public function filter_setting( $setting ) { - $setting = array_intersect_key( - $setting, - array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) - ); - - if ( empty( $setting['options'] ) ) { - unset( $setting['options'] ); - } - - if ( 'image_width' === $setting['type'] ) { - $setting = $this->cast_image_width( $setting ); - } - - return $setting; - } - - /** - * For image_width, Crop can return "0" instead of false -- so we want - * to make sure we return these consistently the same we accept them. - * - * @todo remove in 4.0 - * @since 3.0.0 - * @param array $setting Settings. - * @return array - */ - public function cast_image_width( $setting ) { - foreach ( array( 'default', 'value' ) as $key ) { - if ( isset( $setting[ $key ] ) ) { - $setting[ $key ]['width'] = intval( $setting[ $key ]['width'] ); - $setting[ $key ]['height'] = intval( $setting[ $key ]['height'] ); - $setting[ $key ]['crop'] = (bool) $setting[ $key ]['crop']; - } - } - return $setting; - } - - /** - * Callback for allowed keys for each setting response. - * - * @since 3.0.0 - * @param string $key Key to check. - * @return boolean - */ - public function allowed_setting_keys( $key ) { - return in_array( - $key, array( - 'id', - 'label', - 'description', - 'default', - 'tip', - 'placeholder', - 'type', - 'options', - 'value', - 'option_key', - ) - ); - } - - /** - * Boolean for if a setting type is a valid supported setting type. - * - * @since 3.0.0 - * @param string $type Type. - * @return bool - */ - public function is_setting_type_valid( $type ) { - return in_array( - $type, array( - 'text', // Validates with validate_setting_text_field. - 'email', // Validates with validate_setting_text_field. - 'number', // Validates with validate_setting_text_field. - 'color', // Validates with validate_setting_text_field. - 'password', // Validates with validate_setting_text_field. - 'textarea', // Validates with validate_setting_textarea_field. - 'select', // Validates with validate_setting_select_field. - 'multiselect', // Validates with validate_setting_multiselect_field. - 'radio', // Validates with validate_setting_radio_field (-> validate_setting_select_field). - 'checkbox', // Validates with validate_setting_checkbox_field. - 'image_width', // Validates with validate_setting_image_width_field. - 'thumbnail_cropping', // Validates with validate_setting_text_field. - ) - ); - } - - /** - * Get the settings schema, conforming to JSON Schema. - * - * @since 3.0.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'setting', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox', 'thumbnail_cropping' ), - 'readonly' => true, - ), - 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php b/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php deleted file mode 100644 index 1ca5f153b40..00000000000 --- a/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php +++ /dev/null @@ -1,232 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get all settings groups items. - * - * @since 3.0.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $defaults = $this->group_defaults(); - $filtered_groups = array(); - foreach ( $groups as $group ) { - $sub_groups = array(); - foreach ( $groups as $_group ) { - if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { - $sub_groups[] = $_group['id']; - } - } - $group['sub_groups'] = $sub_groups; - - $group = wp_parse_args( $group, $defaults ); - if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { - $group_obj = $this->filter_group( $group ); - $group_data = $this->prepare_item_for_response( $group_obj, $request ); - $group_data = $this->prepare_response_for_collection( $group_data ); - - $filtered_groups[] = $group_data; - } - } - - $response = rest_ensure_response( $filtered_groups ); - return $response; - } - - /** - * Prepare links for the request. - * - * @param string $group_id Group ID. - * @return array Links for the given group. - */ - protected function prepare_links( $group_id ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - $links = array( - 'options' => array( - 'href' => rest_url( trailingslashit( $base ) . $group_id ), - ), - ); - - return $links; - } - - /** - * Prepare a report sales object for serialization. - * - * @since 3.0.0 - * @param array $item Group object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item['id'] ) ); - - return $response; - } - - /** - * Filters out bad values from the groups array/filter so we - * only return known values via the API. - * - * @since 3.0.0 - * @param array $group Group. - * @return array - */ - public function filter_group( $group ) { - return array_intersect_key( - $group, - array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) - ); - } - - /** - * Callback for allowed keys for each group response. - * - * @since 3.0.0 - * @param string $key Key to check. - * @return boolean - */ - public function allowed_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); - } - - /** - * Returns default settings for groups. null means the field is required. - * - * @since 3.0.0 - * @return array - */ - protected function group_defaults() { - return array( - 'id' => null, - 'label' => null, - 'description' => '', - 'parent_id' => '', - 'sub_groups' => array(), - ); - } - - /** - * Makes sure the current user has access to READ the settings APIs. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full data about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get the groups schema, conforming to JSON Schema. - * - * @since 3.0.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'setting_group', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php deleted file mode 100644 index 0c4a0ff8fcd..00000000000 --- a/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php +++ /dev/null @@ -1,231 +0,0 @@ - - */ - public function register_routes() { - register_rest_route( - $this->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[\w-]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check whether a given request has permission to view shipping methods. - * - * @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( 'shipping_methods', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check if a given request has access to read a shipping method. - * - * @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( 'shipping_methods', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Get shipping methods. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $wc_shipping = WC_Shipping::instance(); - $response = array(); - foreach ( $wc_shipping->get_shipping_methods() as $id => $shipping_method ) { - $method = $this->prepare_item_for_response( $shipping_method, $request ); - $method = $this->prepare_response_for_collection( $method ); - $response[] = $method; - } - return rest_ensure_response( $response ); - } - - /** - * Get a single Shipping Method. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function get_item( $request ) { - $wc_shipping = WC_Shipping::instance(); - $methods = $wc_shipping->get_shipping_methods(); - if ( empty( $methods[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $method = $methods[ $request['id'] ]; - $response = $this->prepare_item_for_response( $method, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Prepare a shipping method for response. - * - * @param WC_Shipping_Method $method Shipping method object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $method, $request ) { - $data = array( - 'id' => $method->id, - 'title' => $method->method_title, - 'description' => $method->method_description, - ); - - $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( $method, $request ) ); - - /** - * Filter shipping methods object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WC_Shipping_Method $method Shipping method object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_shipping_method', $response, $method, $request ); - } - - /** - * Prepare links for the request. - * - * @param WC_Shipping_Method $method Shipping method object. - * @param WP_REST_Request $request Request object. - * @return array - */ - protected function prepare_links( $method, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $method->id ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the shipping method schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_method', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Method ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get any query params needed. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php deleted file mode 100644 index 434906709c7..00000000000 --- a/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php +++ /dev/null @@ -1,190 +0,0 @@ -/locations endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Shipping Zone Locations class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Shipping_Zones_Controller_Base - */ -class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { - - /** - * Register the routes for Shipping Zone Locations. - */ - public function register_routes() { - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/locations', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_items' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get all Shipping Zone Locations. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function get_items( $request ) { - $zone = $this->get_zone( (int) $request['id'] ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $locations = $zone->get_zone_locations(); - $data = array(); - - foreach ( $locations as $location_obj ) { - $location = $this->prepare_item_for_response( $location_obj, $request ); - $location = $this->prepare_response_for_collection( $location ); - $data[] = $location; - } - - return rest_ensure_response( $data ); - } - - /** - * Update all Shipping Zone Locations. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function update_items( $request ) { - $zone = $this->get_zone( (int) $request['id'] ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - if ( 0 === $zone->get_id() ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); - } - - $raw_locations = $request->get_json_params(); - $locations = array(); - - foreach ( (array) $raw_locations as $raw_location ) { - if ( empty( $raw_location['code'] ) ) { - continue; - } - - $type = ! empty( $raw_location['type'] ) ? sanitize_text_field( $raw_location['type'] ) : 'country'; - - if ( ! in_array( $type, array( 'postcode', 'state', 'country', 'continent' ), true ) ) { - continue; - } - - $locations[] = array( - 'code' => sanitize_text_field( $raw_location['code'] ), - 'type' => sanitize_text_field( $type ), - ); - } - - $zone->set_locations( $locations ); - $zone->save(); - - return $this->get_items( $request ); - } - - /** - * Prepare the Shipping Zone Location for the REST response. - * - * @param array $item Shipping Zone Location. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response - */ - public function prepare_item_for_response( $item, $request ) { - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $data = $this->add_additional_fields_to_object( $item, $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( (int) $request['id'] ) ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param int $zone_id Given Shipping Zone ID. - * @return array Links for the given Shipping Zone Location. - */ - protected function prepare_links( $zone_id ) { - $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; - $links = array( - 'collection' => array( - 'href' => rest_url( $base . '/locations' ), - ), - 'describes' => array( - 'href' => rest_url( $base ), - ), - ); - - return $links; - } - - /** - * Get the Shipping Zone Locations schema, conforming to JSON Schema - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone_location', - 'type' => 'object', - 'properties' => array( - 'code' => array( - 'description' => __( 'Shipping zone location code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'type' => array( - 'description' => __( 'Shipping zone location type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'country', - 'enum' => array( - 'postcode', - 'state', - 'country', - 'continent', - ), - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php deleted file mode 100644 index 67ad37bfd26..00000000000 --- a/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php +++ /dev/null @@ -1,541 +0,0 @@ -/methods endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Shipping Zone Methods class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Shipping_Zones_Controller_Base - */ -class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { - - /** - * Register the routes for Shipping Zone Methods. - */ - public function register_routes() { - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods', array( - 'args' => array( - 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'method_id' => array( - 'required' => true, - 'readonly' => false, - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', array( - 'args' => array( - 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'instance_id' => array( - 'description' => __( 'Unique ID for the instance.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_items_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get a single Shipping Zone Method. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function get_item( $request ) { - $zone = $this->get_zone( $request['zone_id'] ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $instance_id = (int) $request['instance_id']; - $methods = $zone->get_shipping_methods(); - $method = false; - - foreach ( $methods as $method_obj ) { - if ( $instance_id === $method_obj->instance_id ) { - $method = $method_obj; - break; - } - } - - if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $data = $this->prepare_item_for_response( $method, $request ); - - return rest_ensure_response( $data ); - } - - /** - * Get all Shipping Zone Methods. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function get_items( $request ) { - $zone = $this->get_zone( $request['zone_id'] ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $methods = $zone->get_shipping_methods(); - $data = array(); - - foreach ( $methods as $method_obj ) { - $method = $this->prepare_item_for_response( $method_obj, $request ); - $data[] = $method; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a new shipping zone method instance. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function create_item( $request ) { - $method_id = $request['method_id']; - $zone = $this->get_zone( $request['zone_id'] ); - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $instance_id = $zone->add_shipping_method( $method_id ); - $methods = $zone->get_shipping_methods(); - $method = false; - foreach ( $methods as $method_obj ) { - if ( $instance_id === $method_obj->instance_id ) { - $method = $method_obj; - break; - } - } - - if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $method = $this->update_fields( $instance_id, $method, $request ); - if ( is_wp_error( $method ) ) { - return $method; - } - - $data = $this->prepare_item_for_response( $method, $request ); - return rest_ensure_response( $data ); - } - - /** - * Delete a shipping method instance. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function delete_item( $request ) { - $zone = $this->get_zone( $request['zone_id'] ); - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $instance_id = (int) $request['instance_id']; - $force = $request['force']; - - $methods = $zone->get_shipping_methods(); - $method = false; - - foreach ( $methods as $method_obj ) { - if ( $instance_id === $method_obj->instance_id ) { - $method = $method_obj; - break; - } - } - - if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $method = $this->update_fields( $instance_id, $method, $request ); - if ( is_wp_error( $method ) ) { - return $method; - } - - $request->set_param( 'context', 'view' ); - $response = $this->prepare_item_for_response( $method, $request ); - - // Actually delete. - if ( $force ) { - $zone->delete_shipping_method( $instance_id ); - } else { - return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - /** - * Fires after a product review is deleted via the REST API. - * - * @param object $method - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'rest_delete_product_review', $method, $response, $request ); - - return $response; - } - - /** - * Update A Single Shipping Zone Method. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function update_item( $request ) { - $zone = $this->get_zone( $request['zone_id'] ); - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $instance_id = (int) $request['instance_id']; - $methods = $zone->get_shipping_methods(); - $method = false; - - foreach ( $methods as $method_obj ) { - if ( $instance_id === $method_obj->instance_id ) { - $method = $method_obj; - break; - } - } - - if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $method = $this->update_fields( $instance_id, $method, $request ); - if ( is_wp_error( $method ) ) { - return $method; - } - - $data = $this->prepare_item_for_response( $method, $request ); - return rest_ensure_response( $data ); - } - - /** - * Updates settings, order, and enabled status on create. - * - * @param int $instance_id Instance ID. - * @param WC_Shipping_Method $method Shipping method data. - * @param WP_REST_Request $request Request data. - * - * @return WC_Shipping_Method - */ - public function update_fields( $instance_id, $method, $request ) { - global $wpdb; - - // Update settings if present. - if ( isset( $request['settings'] ) ) { - $method->init_instance_settings(); - $instance_settings = $method->instance_settings; - $errors_found = false; - foreach ( $method->get_instance_form_fields() as $key => $field ) { - if ( isset( $request['settings'][ $key ] ) ) { - if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { - $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); - } else { - $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); - } - if ( is_wp_error( $value ) ) { - $errors_found = true; - break; - } - $instance_settings[ $key ] = $value; - } - } - - if ( $errors_found ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); - } - - // Update order. - if ( isset( $request['order'] ) ) { - $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'method_order' => absint( $request['order'] ) ), array( 'instance_id' => absint( $instance_id ) ) ); - $method->method_order = absint( $request['order'] ); - } - - // Update if this method is enabled or not. - if ( isset( $request['enabled'] ) ) { - if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'is_enabled' => $request['enabled'] ), array( 'instance_id' => absint( $instance_id ) ) ) ) { - do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method->id, $request['zone_id'], $request['enabled'] ); - $method->enabled = ( true === $request['enabled'] ? 'yes' : 'no' ); - } - } - - return $method; - } - - /** - * Prepare the Shipping Zone Method for the REST response. - * - * @param array $item Shipping Zone Method. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response - */ - public function prepare_item_for_response( $item, $request ) { - $method = array( - 'id' => $item->instance_id, - 'instance_id' => $item->instance_id, - 'title' => $item->instance_settings['title'], - 'order' => $item->method_order, - 'enabled' => ( 'yes' === $item->enabled ), - 'method_id' => $item->id, - 'method_title' => $item->method_title, - 'method_description' => $item->method_description, - 'settings' => $this->get_settings( $item ), - ); - - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $data = $this->add_additional_fields_to_object( $method, $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( $request['zone_id'], $item->instance_id ) ); - - $response = $this->prepare_response_for_collection( $response ); - - return $response; - } - - /** - * Return settings associated with this shipping zone method instance. - * - * @param WC_Shipping_Method $item Shipping method data. - * - * @return array - */ - public function get_settings( $item ) { - $item->init_instance_settings(); - $settings = array(); - foreach ( $item->get_instance_form_fields() as $id => $field ) { - $data = array( - 'id' => $id, - 'label' => $field['title'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => $item->instance_settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - - /** - * Prepare links for the request. - * - * @param int $zone_id Given Shipping Zone ID. - * @param int $instance_id Given Shipping Zone Method Instance ID. - * @return array Links for the given Shipping Zone Method. - */ - protected function prepare_links( $zone_id, $instance_id ) { - $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; - $links = array( - 'self' => array( - 'href' => rest_url( $base . '/methods/' . $instance_id ), - ), - 'collection' => array( - 'href' => rest_url( $base . '/methods' ), - ), - 'describes' => array( - 'href' => rest_url( $base ), - ), - ); - - return $links; - } - - /** - * Get the Shipping Zone Methods schema, conforming to JSON Schema - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone_method', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'instance_id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Shipping method customer facing title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'order' => array( - 'description' => __( 'Shipping method sort order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'enabled' => array( - 'description' => __( 'Shipping method enabled status.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - ), - 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'settings' => array( - 'description' => __( 'Shipping method settings.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php b/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php deleted file mode 100644 index cd8a6b75ccf..00000000000 --- a/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php +++ /dev/null @@ -1,304 +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' ), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'name' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), - ), - ) - ), - ), - '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-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_items_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get a single Shipping Zone. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response|WP_Error - */ - public function get_item( $request ) { - $zone = $this->get_zone( $request->get_param( 'id' ) ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $data = $zone->get_data(); - $data = $this->prepare_item_for_response( $data, $request ); - $data = $this->prepare_response_for_collection( $data ); - - return rest_ensure_response( $data ); - } - - /** - * Get all Shipping Zones. - * - * @param WP_REST_Request $request Request data. - * @return WP_REST_Response - */ - public function get_items( $request ) { - $rest_of_the_world = WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); - - $zones = WC_Shipping_Zones::get_zones(); - array_unshift( $zones, $rest_of_the_world->get_data() ); - $data = array(); - - foreach ( $zones as $zone_obj ) { - $zone = $this->prepare_item_for_response( $zone_obj, $request ); - $zone = $this->prepare_response_for_collection( $zone ); - $data[] = $zone; - } - - return rest_ensure_response( $data ); - } - - /** - * Create a single Shipping Zone. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function create_item( $request ) { - $zone = new WC_Shipping_Zone( null ); - - if ( ! is_null( $request->get_param( 'name' ) ) ) { - $zone->set_zone_name( $request->get_param( 'name' ) ); - } - - if ( ! is_null( $request->get_param( 'order' ) ) ) { - $zone->set_zone_order( $request->get_param( 'order' ) ); - } - - $zone->save(); - - if ( $zone->get_id() !== 0 ) { - $request->set_param( 'id', $zone->get_id() ); - $response = $this->get_item( $request ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); - return $response; - } else { - return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - } - - /** - * Update a single Shipping Zone. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function update_item( $request ) { - $zone = $this->get_zone( $request->get_param( 'id' ) ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - if ( 0 === $zone->get_id() ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); - } - - $zone_changed = false; - - if ( ! is_null( $request->get_param( 'name' ) ) ) { - $zone->set_zone_name( $request->get_param( 'name' ) ); - $zone_changed = true; - } - - if ( ! is_null( $request->get_param( 'order' ) ) ) { - $zone->set_zone_order( $request->get_param( 'order' ) ); - $zone_changed = true; - } - - if ( $zone_changed ) { - $zone->save(); - } - - return $this->get_item( $request ); - } - - /** - * Delete a single Shipping Zone. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function delete_item( $request ) { - $zone = $this->get_zone( $request->get_param( 'id' ) ); - - if ( is_wp_error( $zone ) ) { - return $zone; - } - - $force = $request['force']; - - $response = $this->get_item( $request ); - - if ( $force ) { - $zone->delete(); - } else { - return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - return $response; - } - - /** - * Prepare the Shipping Zone for the REST response. - * - * @param array $item Shipping Zone. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response - */ - public function prepare_item_for_response( $item, $request ) { - $data = array( - 'id' => (int) $item['id'], - 'name' => $item['zone_name'], - 'order' => (int) $item['zone_order'], - ); - - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $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( $data['id'] ) ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param int $zone_id Given Shipping Zone ID. - * @return array Links for the given Shipping Zone. - */ - protected function prepare_links( $zone_id ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - $links = array( - 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $zone_id ), - ), - 'collection' => array( - 'href' => rest_url( $base ), - ), - 'describedby' => array( - 'href' => rest_url( trailingslashit( $base ) . $zone_id . '/locations' ), - ), - ); - - return $links; - } - - /** - * Get the Shipping Zones schema, conforming to JSON Schema - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'order' => array( - 'description' => __( 'Shipping zone order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php deleted file mode 100644 index ee62d186b82..00000000000 --- a/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ /dev/null @@ -1,618 +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[\w-]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - 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_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check whether a given request has permission to view system status tools. - * - * @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-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check whether a given request has permission to view a specific system status tool. - * - * @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 view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Check whether a given request has permission to execute a specific system status tool. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * A list of available tools for use in the system status section. - * 'button' becomes 'action' in the API. - * - * @return array - */ - public function get_tools() { - $tools = array( - 'clear_transients' => array( - 'name' => __( 'WooCommerce transients', 'woocommerce-rest-api' ), - 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce-rest-api' ), - ), - 'clear_expired_transients' => array( - 'name' => __( 'Expired transients', 'woocommerce-rest-api' ), - 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce-rest-api' ), - ), - 'delete_orphaned_variations' => array( - 'name' => __( 'Orphaned variations', 'woocommerce-rest-api' ), - 'button' => __( 'Delete orphaned variations', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce-rest-api' ), - ), - 'clear_expired_download_permissions' => array( - 'name' => __( 'Used-up download permissions', 'woocommerce-rest-api' ), - 'button' => __( 'Clean up download permissions', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce-rest-api' ), - ), - 'regenerate_product_lookup_tables' => array( - 'name' => __( 'Product lookup tables', 'woocommerce-rest-api' ), - 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce-rest-api' ), - ), - 'recount_terms' => array( - 'name' => __( 'Term counts', 'woocommerce-rest-api' ), - 'button' => __( 'Recount terms', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce-rest-api' ), - ), - 'reset_roles' => array( - 'name' => __( 'Capabilities', 'woocommerce-rest-api' ), - 'button' => __( 'Reset capabilities', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce-rest-api' ), - ), - 'clear_sessions' => array( - 'name' => __( 'Clear customer sessions', 'woocommerce-rest-api' ), - 'button' => __( 'Clear', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce-rest-api' ) - ), - ), - 'clear_template_cache' => array( - 'name' => __( 'Clear template cache', 'woocommerce-rest-api' ), - 'button' => __( 'Clear', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will empty the template cache.', 'woocommerce-rest-api' ) - ), - ), - 'install_pages' => array( - 'name' => __( 'Create default WooCommerce pages', 'woocommerce-rest-api' ), - 'button' => __( 'Create pages', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce-rest-api' ) - ), - ), - 'delete_taxes' => array( - 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce-rest-api' ), - 'button' => __( 'Delete tax rates', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce-rest-api' ) - ), - ), - 'regenerate_thumbnails' => array( - 'name' => __( 'Regenerate shop thumbnails', 'woocommerce-rest-api' ), - 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), - 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce-rest-api' ), - ), - 'db_update_routine' => array( - 'name' => __( 'Update database', 'woocommerce-rest-api' ), - 'button' => __( 'Update database', 'woocommerce-rest-api' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce-rest-api' ) - ), - ), - ); - if ( method_exists( 'WC_Install', 'verify_base_tables' ) ) { - $tools['verify_db_tables'] = array( - 'name' => __( 'Verify base database tables', 'woocommerce-rest-api' ), - 'button' => __( 'Verify database', 'woocommerce-rest-api' ), - 'desc' => sprintf( - __( 'Verify if all base database tables are present.', 'woocommerce-rest-api' ) - ), - ); - } - - // Jetpack does the image resizing heavy lifting so you don't have to. - if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) { - unset( $tools['regenerate_thumbnails'] ); - } - - if ( ! function_exists( 'wc_clear_template_cache' ) ) { - unset( $tools['clear_template_cache'] ); - } - - return apply_filters( 'woocommerce_debug_tools', $tools ); - } - - /** - * Get a list of system status tools. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $tools = array(); - foreach ( $this->get_tools() as $id => $tool ) { - $tools[] = $this->prepare_response_for_collection( - $this->prepare_item_for_response( - array( - 'id' => $id, - 'name' => $tool['name'], - 'action' => $tool['button'], - 'description' => $tool['desc'], - ), - $request - ) - ); - } - - $response = rest_ensure_response( $tools ); - return $response; - } - - /** - * Return a single tool. - * - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $tools = $this->get_tools(); - if ( empty( $tools[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - $tool = $tools[ $request['id'] ]; - return rest_ensure_response( - $this->prepare_item_for_response( - array( - 'id' => $request['id'], - 'name' => $tool['name'], - 'action' => $tool['button'], - 'description' => $tool['desc'], - ), - $request - ) - ); - } - - /** - * Update (execute) a tool. - * - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $tools = $this->get_tools(); - if ( empty( $tools[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $tool = $tools[ $request['id'] ]; - $tool = array( - 'id' => $request['id'], - 'name' => $tool['name'], - 'action' => $tool['button'], - 'description' => $tool['desc'], - ); - - $execute_return = $this->execute_tool( $request['id'] ); - $tool = array_merge( $tool, $execute_return ); - - /** - * Fires after a WooCommerce REST system status tool has been executed. - * - * @param array $tool Details about the tool that has been executed. - * @param WP_REST_Request $request The current WP_REST_Request object. - */ - do_action( 'woocommerce_rest_insert_system_status_tool', $tool, $request ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $tool, $request ); - return rest_ensure_response( $response ); - } - - /** - * Prepare a tool item for serialization. - * - * @param array $item Object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $item, $request ) { - $context = empty( $request['context'] ) ? 'view' : $request['context']; - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item['id'] ) ); - - return $response; - } - - /** - * Get the system status tools schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'system_status_tool', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the tool.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'name' => array( - 'description' => __( 'Tool name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'action' => array( - 'description' => __( 'What running the tool will do.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'description' => array( - 'description' => __( 'Tool description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'success' => array( - 'description' => __( 'Did the tool run successfully?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'edit' ), - ), - 'message' => array( - 'description' => __( 'Tool return message.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Prepare links for the request. - * - * @param string $id ID. - * @return array - */ - protected function prepare_links( $id ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - $links = array( - 'item' => array( - 'href' => rest_url( trailingslashit( $base ) . $id ), - 'embeddable' => true, - ), - ); - - return $links; - } - - /** - * Get any query params needed. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } - - /** - * Actually executes a tool. - * - * @param string $tool Tool. - * @return array - */ - public function execute_tool( $tool ) { - global $wpdb; - $ran = true; - switch ( $tool ) { - case 'clear_transients': - wc_delete_product_transients(); - wc_delete_shop_order_transients(); - delete_transient( 'wc_count_comments' ); - delete_transient( 'as_comment_count' ); - - $attribute_taxonomies = wc_get_attribute_taxonomies(); - - if ( $attribute_taxonomies ) { - foreach ( $attribute_taxonomies as $attribute ) { - delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name ); - } - } - - WC_Cache_Helper::get_transient_version( 'shipping', true ); - $message = __( 'Product transients cleared', 'woocommerce-rest-api' ); - break; - - case 'clear_expired_transients': - /* translators: %d: amount of expired transients */ - $message = sprintf( __( '%d transients rows cleared', 'woocommerce-rest-api' ), wc_delete_expired_transients() ); - break; - - case 'delete_orphaned_variations': - // Delete orphans. - $result = absint( - $wpdb->query( - "DELETE products - FROM {$wpdb->posts} products - LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent - WHERE wp.ID IS NULL AND products.post_type = 'product_variation';" - ) - ); - /* translators: %d: amount of orphaned variations */ - $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce-rest-api' ), $result ); - break; - - case 'clear_expired_download_permissions': - // Delete expired download permissions and ones with 0 downloads remaining. - $result = absint( - $wpdb->query( - $wpdb->prepare( - "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions - WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )", - gmdate( 'Y-m-d', current_time( 'timestamp' ) ) - ) - ) - ); - /* translators: %d: amount of permissions */ - $message = sprintf( __( '%d permissions deleted', 'woocommerce-rest-api' ), $result ); - break; - - case 'regenerate_product_lookup_tables': - if ( ! wc_update_product_lookup_tables_is_running() ) { - wc_update_product_lookup_tables(); - } - $message = __( 'Lookup tables are regenerating', 'woocommerce-rest-api' ); - break; - case 'reset_roles': - // Remove then re-add caps and roles. - WC_Install::remove_roles(); - WC_Install::create_roles(); - $message = __( 'Roles successfully reset', 'woocommerce-rest-api' ); - break; - - case 'recount_terms': - $product_cats = get_terms( - 'product_cat', - array( - 'hide_empty' => false, - 'fields' => 'id=>parent', - ) - ); - _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false ); - $product_tags = get_terms( - 'product_tag', - array( - 'hide_empty' => false, - 'fields' => 'id=>parent', - ) - ); - _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); - $message = __( 'Terms successfully recounted', 'woocommerce-rest-api' ); - break; - - case 'clear_sessions': - $wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" ); - $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. - wp_cache_flush(); - /* translators: %d: amount of sessions */ - $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce-rest-api' ), absint( $result ) ); - break; - - case 'install_pages': - WC_Install::create_pages(); - $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce-rest-api' ); - break; - - case 'delete_taxes': - $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); - $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); - - if ( method_exists( 'WC_Cache_Helper', 'invalidate_cache_group' ) ) { - WC_Cache_Helper::invalidate_cache_group( 'taxes' ); - } else { - WC_Cache_Helper::incr_cache_prefix( 'taxes' ); - } - $message = __( 'Tax rates successfully deleted', 'woocommerce-rest-api' ); - break; - - case 'regenerate_thumbnails': - WC_Regenerate_Images::queue_image_regeneration(); - $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce-rest-api' ); - break; - - case 'db_update_routine': - $blog_id = get_current_blog_id(); - // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). - // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. - do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); - $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce-rest-api' ); - break; - - case 'clear_template_cache': - if ( function_exists( 'wc_clear_template_cache' ) ) { - wc_clear_template_cache(); - $message = __( 'Template cache cleared.', 'woocommerce-rest-api' ); - } else { - $message = __( 'The active version of WooCommerce does not support template cache clearing.', 'woocommerce-rest-api' ); - $ran = false; - } - break; - - case 'verify_db_tables': - if ( ! method_exists( 'WC_Install', 'verify_base_tables' ) ) { - $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce-rest-api' ); - $ran = false; - break; - } - // Try to manually create table again. - $missing_tables = WC_Install::verify_base_tables( true, true ); - if ( 0 === count( $missing_tables ) ) { - $message = __( 'Database verified successfully.', 'woocommerce-rest-api' ); - } else { - $message = __( 'Verifying database... One or more tables are still missing: ', 'woocommerce-rest-api' ); - $message .= implode( ', ', $missing_tables ); - $ran = false; - } - break; - - default: - $tools = $this->get_tools(); - if ( isset( $tools[ $tool ]['callback'] ) ) { - $callback = $tools[ $tool ]['callback']; - $return = call_user_func( $callback ); - if ( is_string( $return ) ) { - $message = $return; - } elseif ( false === $return ) { - $callback_string = is_array( $callback ) ? get_class( $callback[0] ) . '::' . $callback[1] : $callback; - $ran = false; - /* translators: %s: callback string */ - $message = sprintf( __( 'There was an error calling %s', 'woocommerce-rest-api' ), $callback_string ); - } else { - $message = __( 'Tool ran.', 'woocommerce-rest-api' ); - } - } else { - $ran = false; - $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce-rest-api' ); - } - break; - } - - return array( - 'success' => $ran, - 'message' => $message, - ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php deleted file mode 100644 index 448f30f0725..00000000000 --- a/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ /dev/null @@ -1,1259 +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' ), - ) - ); - } - - /** - * Check whether a given request has permission to view system status. - * - * @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-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - return true; - } - - /** - * Get a system status info, by section. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $fields = $this->get_fields_for_response( $request ); - $mappings = $this->get_item_mappings_per_fields( $fields ); - $response = $this->prepare_item_for_response( $mappings, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Get the system status schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'system_status', - 'type' => 'object', - 'properties' => array( - 'environment' => array( - 'description' => __( 'Environment.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'home_url' => array( - 'description' => __( 'Home URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'site_url' => array( - 'description' => __( 'Site URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'version' => array( - 'description' => __( 'WooCommerce version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'log_directory' => array( - 'description' => __( 'Log directory.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'log_directory_writable' => array( - 'description' => __( 'Is log directory writable?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_version' => array( - 'description' => __( 'WordPress version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_multisite' => array( - 'description' => __( 'Is WordPress multisite?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_memory_limit' => array( - 'description' => __( 'WordPress memory limit.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_debug_mode' => array( - 'description' => __( 'Is WordPress debug mode active?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'wp_cron' => array( - 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'language' => array( - 'description' => __( 'WordPress language.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'server_info' => array( - 'description' => __( 'Server info.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'php_version' => array( - 'description' => __( 'PHP version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'php_post_max_size' => array( - 'description' => __( 'PHP post max size.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'php_max_execution_time' => array( - 'description' => __( 'PHP max execution time.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'php_max_input_vars' => array( - 'description' => __( 'PHP max input vars.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'curl_version' => array( - 'description' => __( 'cURL version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'suhosin_installed' => array( - 'description' => __( 'Is SUHOSIN installed?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'max_upload_size' => array( - 'description' => __( 'Max upload size.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'mysql_version' => array( - 'description' => __( 'MySQL version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'mysql_version_string' => array( - 'description' => __( 'MySQL version string.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'default_timezone' => array( - 'description' => __( 'Default timezone.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'fsockopen_or_curl_enabled' => array( - 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'soapclient_enabled' => array( - 'description' => __( 'Is SoapClient class enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'domdocument_enabled' => array( - 'description' => __( 'Is DomDocument class enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'gzip_enabled' => array( - 'description' => __( 'Is GZip enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'mbstring_enabled' => array( - 'description' => __( 'Is mbstring enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'remote_post_successful' => array( - 'description' => __( 'Remote POST successful?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'remote_post_response' => array( - 'description' => __( 'Remote POST response.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'remote_get_successful' => array( - 'description' => __( 'Remote GET successful?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'remote_get_response' => array( - 'description' => __( 'Remote GET response.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - 'database' => array( - 'description' => __( 'Database.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'wc_database_version' => array( - 'description' => __( 'WC database version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'database_prefix' => array( - 'description' => __( 'Database prefix.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'maxmind_geoip_database' => array( - 'description' => __( 'MaxMind GeoIP database.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'database_tables' => array( - 'description' => __( 'Database tables.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - ), - ), - 'active_plugins' => array( - 'description' => __( 'Active plugins.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'inactive_plugins' => array( - 'description' => __( 'Inactive plugins.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'dropins_mu_plugins' => array( - 'description' => __( 'Dropins & MU plugins.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'theme' => array( - 'description' => __( 'Theme.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'name' => array( - 'description' => __( 'Theme name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'version' => array( - 'description' => __( 'Theme version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'version_latest' => array( - 'description' => __( 'Latest version of theme.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'author_url' => array( - 'description' => __( 'Theme author URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'is_child_theme' => array( - 'description' => __( 'Is this theme a child theme?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'has_woocommerce_support' => array( - 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'has_woocommerce_file' => array( - 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'has_outdated_templates' => array( - 'description' => __( 'Does this theme have outdated templates?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'overrides' => array( - 'description' => __( 'Template overrides.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'parent_name' => array( - 'description' => __( 'Parent theme name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'parent_version' => array( - 'description' => __( 'Parent theme version.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'parent_author_url' => array( - 'description' => __( 'Parent theme author URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - 'settings' => array( - 'description' => __( 'Settings.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'api_enabled' => array( - 'description' => __( 'REST API enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'force_ssl' => array( - 'description' => __( 'SSL forced?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency' => array( - 'description' => __( 'Currency.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency_symbol' => array( - 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency_position' => array( - 'description' => __( 'Currency position.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'thousand_separator' => array( - 'description' => __( 'Thousand separator.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'decimal_separator' => array( - 'description' => __( 'Decimal separator.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'number_of_decimals' => array( - 'description' => __( 'Number of decimals.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'geolocation_enabled' => array( - 'description' => __( 'Geolocation enabled?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'taxonomies' => array( - 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'product_visibility_terms' => array( - 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - ), - ), - 'security' => array( - 'description' => __( 'Security.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'secure_connection' => array( - 'description' => __( 'Is the connection to your store secure?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'hide_errors' => array( - 'description' => __( 'Hide errors from visitors?', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - 'pages' => array( - 'description' => __( 'WooCommerce pages.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'post_type_counts' => array( - 'description' => __( 'Total post count.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Return an array of sections and the data associated with each. - * - * @deprecated 3.9.0 - * @return array - */ - public function get_item_mappings() { - return array( - 'environment' => $this->get_environment_info(), - 'database' => $this->get_database_info(), - 'active_plugins' => $this->get_active_plugins(), - 'inactive_plugins' => $this->get_inactive_plugins(), - 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(), - 'theme' => $this->get_theme_info(), - 'settings' => $this->get_settings(), - 'security' => $this->get_security_info(), - 'pages' => $this->get_pages(), - 'post_type_counts' => $this->get_post_type_counts(), - ); - } - - /** - * Return an array of sections and the data associated with each. - * - * @since 3.9.0 - * @param array $fields List of fields to be included on the response. - * @return array - */ - public function get_item_mappings_per_fields( $fields ) { - return array( - 'environment' => $this->get_environment_info_per_fields( $fields ), - 'database' => $this->get_database_info(), - 'active_plugins' => $this->get_active_plugins(), - 'inactive_plugins' => $this->get_inactive_plugins(), - 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(), - 'theme' => $this->get_theme_info(), - 'settings' => $this->get_settings(), - 'security' => $this->get_security_info(), - 'pages' => $this->get_pages(), - 'post_type_counts' => $this->get_post_type_counts(), - ); - } - - /** - * Get array of environment information. Includes thing like software - * versions, and various server settings. - * - * @deprecated 3.9.0 - * @return array - */ - public function get_environment_info() { - return $this->get_environment_info_per_fields( array( 'environment' ) ); - } - - /** - * Check if field item exists. - * - * @since 3.9.0 - * @param string $section Fields section. - * @param array $items List of items to check for. - * @param array $fields List of fields to be included on the response. - * @return bool - */ - private function check_if_field_item_exists( $section, $items, $fields ) { - if ( ! in_array( $section, $fields, true ) ) { - return false; - } - - $exclude = array(); - foreach ( $fields as $field ) { - $values = explode( '.', $field ); - - if ( $section !== $values[0] || empty( $values[1] ) ) { - continue; - } - - $exclude[] = $values[1]; - } - - return 0 <= count( array_intersect( $items, $exclude ) ); - } - - /** - * Get array of environment information. Includes thing like software - * versions, and various server settings. - * - * @param array $fields List of fields to be included on the response. - * @return array - */ - public function get_environment_info_per_fields( $fields ) { - global $wpdb; - - $enable_remote_post = $this->check_if_field_item_exists( 'environment', array( 'remote_post_successful', 'remote_post_response' ), $fields ); - $enable_remote_get = $this->check_if_field_item_exists( 'environment', array( 'remote_get_successful', 'remote_get_response' ), $fields ); - - // Figure out cURL version, if installed. - $curl_version = ''; - if ( function_exists( 'curl_version' ) ) { - $curl_version = curl_version(); - $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; - } elseif ( extension_loaded( 'curl' ) ) { - $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce-rest-api' ); - } - - // WP memory limit. - $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); - if ( function_exists( 'memory_get_usage' ) ) { - $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged - } - - // Test POST requests. - $post_response_successful = null; - $post_response_code = null; - if ( $enable_remote_post ) { - $post_response_code = get_transient( 'woocommerce_test_remote_post' ); - - if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { - $response = wp_safe_remote_post( - 'https://www.paypal.com/cgi-bin/webscr', - array( - 'timeout' => 10, - 'user-agent' => 'WooCommerce/' . WC()->version, - 'httpversion' => '1.1', - 'body' => array( - 'cmd' => '_notify-validate', - ), - ) - ); - if ( ! is_wp_error( $response ) ) { - $post_response_code = $response['response']['code']; - } - set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); - } - - $post_response_successful = ! is_wp_error( $post_response_code ) && $post_response_code >= 200 && $post_response_code < 300; - } - - // Test GET requests. - $get_response_successful = null; - $get_response_code = null; - if ( $enable_remote_get ) { - $get_response_code = get_transient( 'woocommerce_test_remote_get' ); - - if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { - $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); - if ( ! is_wp_error( $response ) ) { - $get_response_code = $response['response']['code']; - } - set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); - } - - $get_response_successful = ! is_wp_error( $get_response_code ) && $get_response_code >= 200 && $get_response_code < 300; - } - - $database_version = wc_get_server_database_version(); - - // Return all environment info. Described by JSON Schema. - return array( - 'home_url' => get_option( 'home' ), - 'site_url' => get_option( 'siteurl' ), - 'version' => WC()->version, - 'log_directory' => WC_LOG_DIR, - 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen - 'wp_version' => get_bloginfo( 'version' ), - 'wp_multisite' => is_multisite(), - 'wp_memory_limit' => $wp_memory_limit, - 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), - 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ), - 'language' => get_locale(), - 'external_object_cache' => wp_using_ext_object_cache(), - 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '', - 'php_version' => phpversion(), - 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), - 'php_max_execution_time' => (int) ini_get( 'max_execution_time' ), - 'php_max_input_vars' => (int) ini_get( 'max_input_vars' ), - 'curl_version' => $curl_version, - 'suhosin_installed' => extension_loaded( 'suhosin' ), - 'max_upload_size' => wp_max_upload_size(), - 'mysql_version' => $database_version['number'], - 'mysql_version_string' => $database_version['string'], - 'default_timezone' => date_default_timezone_get(), - 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ), - 'soapclient_enabled' => class_exists( 'SoapClient' ), - 'domdocument_enabled' => class_exists( 'DOMDocument' ), - 'gzip_enabled' => is_callable( 'gzopen' ), - 'mbstring_enabled' => extension_loaded( 'mbstring' ), - 'remote_post_successful' => $post_response_successful, - 'remote_post_response' => is_wp_error( $post_response_code ) ? $post_response_code->get_error_message() : $post_response_code, - 'remote_get_successful' => $get_response_successful, - 'remote_get_response' => is_wp_error( $get_response_code ) ? $get_response_code->get_error_message() : $get_response_code, - ); - } - - /** - * Add prefix to table. - * - * @param string $table Table name. - * @return stromg - */ - protected function add_db_table_prefix( $table ) { - global $wpdb; - return $wpdb->prefix . $table; - } - - /** - * Get array of database information. Version, prefix, and table existence. - * - * @return array - */ - public function get_database_info() { - global $wpdb; - - $tables = array(); - $database_size = array(); - - // It is not possible to get the database name from some classes that replace wpdb (e.g., HyperDB) - // and that is why this if condition is needed. - if ( defined( 'DB_NAME' ) ) { - $database_table_information = $wpdb->get_results( - $wpdb->prepare( - "SELECT - table_name AS 'name', - engine AS 'engine', - round( ( data_length / 1024 / 1024 ), 2 ) 'data', - round( ( index_length / 1024 / 1024 ), 2 ) 'index' - FROM information_schema.TABLES - WHERE table_schema = %s - ORDER BY name ASC;", - DB_NAME - ) - ); - - // WC Core tables to check existence of. - $core_tables = apply_filters( - 'woocommerce_database_tables', - array( - 'woocommerce_sessions', - 'woocommerce_api_keys', - 'woocommerce_attribute_taxonomies', - 'woocommerce_downloadable_product_permissions', - 'woocommerce_order_items', - 'woocommerce_order_itemmeta', - 'woocommerce_tax_rates', - 'woocommerce_tax_rate_locations', - 'woocommerce_shipping_zones', - 'woocommerce_shipping_zone_locations', - 'woocommerce_shipping_zone_methods', - 'woocommerce_payment_tokens', - 'woocommerce_payment_tokenmeta', - 'woocommerce_log', - ) - ); - - /** - * Adding the prefix to the tables array, for backwards compatibility. - * - * If we changed the tables above to include the prefix, then any filters against that table could break. - */ - $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); - - /** - * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. - * - * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. - */ - $tables = array( - 'woocommerce' => array_fill_keys( $core_tables, false ), - 'other' => array(), - ); - - $database_size = array( - 'data' => 0, - 'index' => 0, - ); - - $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); - $global_tables = $wpdb->tables( 'global', true ); - foreach ( $database_table_information as $table ) { - // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. - if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { - continue; - } - $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; - - $tables[ $table_type ][ $table->name ] = array( - 'data' => $table->data, - 'index' => $table->index, - 'engine' => $table->engine, - ); - - $database_size['data'] += $table->data; - $database_size['index'] += $table->index; - } - } - - // Return all database info. Described by JSON Schema. - return array( - 'wc_database_version' => get_option( 'woocommerce_db_version' ), - 'database_prefix' => $wpdb->prefix, - 'maxmind_geoip_database' => '', - 'database_tables' => $tables, - 'database_size' => $database_size, - ); - } - - /** - * Get array of counts of objects. Orders, products, etc. - * - * @return array - */ - public function get_post_type_counts() { - global $wpdb; - - $post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" ); - - return is_array( $post_type_counts ) ? $post_type_counts : array(); - } - - /** - * Get a list of plugins active on the site. - * - * @return array - */ - public function get_active_plugins() { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - if ( ! function_exists( 'get_plugin_data' ) ) { - return array(); - } - - $active_plugins = (array) get_option( 'active_plugins', array() ); - if ( is_multisite() ) { - $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); - $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); - } - - $active_plugins_data = array(); - - foreach ( $active_plugins as $plugin ) { - $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); - $active_plugins_data[] = $this->format_plugin_data( $plugin, $data ); - } - - return $active_plugins_data; - } - - /** - * Get a list of inplugins active on the site. - * - * @return array - */ - public function get_inactive_plugins() { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - if ( ! function_exists( 'get_plugins' ) ) { - return array(); - } - - $plugins = get_plugins(); - $active_plugins = (array) get_option( 'active_plugins', array() ); - - if ( is_multisite() ) { - $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); - $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); - } - - $plugins_data = array(); - - foreach ( $plugins as $plugin => $data ) { - if ( in_array( $plugin, $active_plugins, true ) ) { - continue; - } - $plugins_data[] = $this->format_plugin_data( $plugin, $data ); - } - - return $plugins_data; - } - - /** - * Format plugin data, including data on updates, into a standard format. - * - * @since 3.6.0 - * @param string $plugin Plugin directory/file. - * @param array $data Plugin data from WP. - * @return array Formatted data. - */ - protected function format_plugin_data( $plugin, $data ) { - require_once ABSPATH . 'wp-admin/includes/update.php'; - - if ( ! function_exists( 'get_plugin_updates' ) ) { - return array(); - } - - // Use WP API to lookup latest updates for plugins. WC_Helper injects updates for premium plugins. - if ( empty( $this->available_updates ) ) { - $this->available_updates = get_plugin_updates(); - } - - $version_latest = $data['Version']; - - // Find latest version. - if ( isset( $this->available_updates[ $plugin ]->update->new_version ) ) { - $version_latest = $this->available_updates[ $plugin ]->update->new_version; - } - - return array( - 'plugin' => $plugin, - 'name' => $data['Name'], - 'version' => $data['Version'], - 'version_latest' => $version_latest, - 'url' => $data['PluginURI'], - 'author_name' => $data['AuthorName'], - 'author_url' => esc_url_raw( $data['AuthorURI'] ), - 'network_activated' => $data['Network'], - ); - } - - /** - * Get a list of Dropins and MU plugins. - * - * @since 3.6.0 - * @return array - */ - public function get_dropins_mu_plugins() { - $dropins = get_dropins(); - $plugins = array( - 'dropins' => array(), - 'mu_plugins' => array(), - ); - foreach ( $dropins as $key => $dropin ) { - $plugins['dropins'][] = array( - 'plugin' => $key, - 'name' => $dropin['Name'], - ); - } - - $mu_plugins = get_mu_plugins(); - foreach ( $mu_plugins as $plugin => $mu_plugin ) { - $plugins['mu_plugins'][] = array( - 'plugin' => $plugin, - 'name' => $mu_plugin['Name'], - 'version' => $mu_plugin['Version'], - 'url' => $mu_plugin['PluginURI'], - 'author_name' => $mu_plugin['AuthorName'], - 'author_url' => esc_url_raw( $mu_plugin['AuthorURI'] ), - ); - } - return $plugins; - } - - /** - * Get info on the current active theme, info on parent theme (if presnet) - * and a list of template overrides. - * - * @return array - */ - public function get_theme_info() { - $active_theme = wp_get_theme(); - - // Get parent theme info if this theme is a child theme, otherwise - // pass empty info in the response. - if ( is_child_theme() ) { - $parent_theme = wp_get_theme( $active_theme->template ); - $parent_theme_info = array( - 'parent_name' => $parent_theme->name, - 'parent_version' => $parent_theme->version, - 'parent_version_latest' => WC_Admin_Status::get_latest_theme_version( $parent_theme ), - 'parent_author_url' => $parent_theme->{'Author URI'}, - ); - } else { - $parent_theme_info = array( - 'parent_name' => '', - 'parent_version' => '', - 'parent_version_latest' => '', - 'parent_author_url' => '', - ); - } - - /** - * Scan the theme directory for all WC templates to see if our theme - * overrides any of them. - */ - $override_files = array(); - $outdated_templates = false; - $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); - foreach ( $scan_files as $file ) { - $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' ); - - if ( file_exists( $located ) ) { - $theme_file = $located; - } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { - $theme_file = get_stylesheet_directory() . '/' . $file; - } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { - $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; - } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { - $theme_file = get_template_directory() . '/' . $file; - } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { - $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; - } else { - $theme_file = false; - } - - if ( ! empty( $theme_file ) ) { - $core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); - $theme_version = WC_Admin_Status::get_file_version( $theme_file ); - if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { - if ( ! $outdated_templates ) { - $outdated_templates = true; - } - } - $override_files[] = array( - 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), - 'version' => $theme_version, - 'core_version' => $core_version, - ); - } - } - - $active_theme_info = array( - 'name' => $active_theme->name, - 'version' => $active_theme->version, - 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ), - 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), - 'is_child_theme' => is_child_theme(), - 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), - 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), - 'has_outdated_templates' => $outdated_templates, - 'overrides' => $override_files, - ); - - return array_merge( $active_theme_info, $parent_theme_info ); - } - - /** - * Get some setting values for the site that are useful for debugging - * purposes. For full settings access, use the settings api. - * - * @return array - */ - public function get_settings() { - // Get a list of terms used for product/order taxonomies. - $term_response = array(); - $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); - foreach ( $terms as $term ) { - $term_response[ $term->slug ] = strtolower( $term->name ); - } - - // Get a list of terms used for product visibility. - $product_visibility_terms = array(); - $terms = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) ); - foreach ( $terms as $term ) { - $product_visibility_terms[ $term->slug ] = strtolower( $term->name ); - } - - // Check if WooCommerce.com account is connected. - $woo_com_connected = 'no'; - $helper_options = get_option( 'woocommerce_helper_data', array() ); - if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) { - $woo_com_connected = 'yes'; - } - - // Return array of useful settings for debugging. - return array( - 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ), - 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ), - 'currency' => get_woocommerce_currency(), - 'currency_symbol' => get_woocommerce_currency_symbol(), - 'currency_position' => get_option( 'woocommerce_currency_pos' ), - 'thousand_separator' => wc_get_price_thousand_separator(), - 'decimal_separator' => wc_get_price_decimal_separator(), - 'number_of_decimals' => wc_get_price_decimals(), - 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ), true ), - 'taxonomies' => $term_response, - 'product_visibility_terms' => $product_visibility_terms, - 'woocommerce_com_connected' => $woo_com_connected, - ); - } - - /** - * Returns security tips. - * - * @return array - */ - public function get_security_info() { - $check_page = wc_get_page_permalink( 'shop' ); - return array( - 'secure_connection' => 'https' === substr( $check_page, 0, 5 ), - 'hide_errors' => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), - ); - } - - /** - * Returns a mini-report on WC pages and if they are configured correctly: - * Present, visible, and including the correct shortcode. - * - * @return array - */ - public function get_pages() { - // WC pages to check against. - $check_pages = array( - _x( 'Shop base', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_shop_page_id', - 'shortcode' => '', - ), - _x( 'Cart', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_cart_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', - ), - _x( 'Checkout', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_checkout_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', - ), - _x( 'My account', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_myaccount_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', - ), - _x( 'Terms and conditions', 'Page setting', 'woocommerce-rest-api' ) => array( - 'option' => 'woocommerce_terms_page_id', - 'shortcode' => '', - ), - ); - - $pages_output = array(); - foreach ( $check_pages as $page_name => $values ) { - $page_id = get_option( $values['option'] ); - $page_set = false; - $page_exists = false; - $page_visible = false; - $shortcode_present = false; - $shortcode_required = false; - - // Page checks. - if ( $page_id ) { - $page_set = true; - } - if ( get_post( $page_id ) ) { - $page_exists = true; - } - if ( 'publish' === get_post_status( $page_id ) ) { - $page_visible = true; - } - - // Shortcode checks. - if ( $values['shortcode'] && get_post( $page_id ) ) { - $shortcode_required = true; - $page = get_post( $page_id ); - if ( strstr( $page->post_content, $values['shortcode'] ) ) { - $shortcode_present = true; - } - } - - // Wrap up our findings into an output array. - $pages_output[] = array( - 'page_name' => $page_name, - 'page_id' => $page_id, - 'page_set' => $page_set, - 'page_exists' => $page_exists, - 'page_visible' => $page_visible, - 'shortcode' => $values['shortcode'], - 'shortcode_required' => $shortcode_required, - 'shortcode_present' => $shortcode_present, - ); - } - - return $pages_output; - } - - /** - * Get any query params needed. - * - * @return array - */ - public function get_collection_params() { - return array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ); - } - - /** - * Prepare the system status response - * - * @param array $system_status System status data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_item_for_response( $system_status, $request ) { - $data = $this->add_additional_fields_to_object( $system_status, $request ); - $data = $this->filter_response_by_context( $data, 'view' ); - - $response = rest_ensure_response( $data ); - - /** - * Filter the system status returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param mixed $system_status System status - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_system_status', $response, $system_status, $request ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php b/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php deleted file mode 100644 index dc1cdd24bd3..00000000000 --- a/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/deliveries endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Webhook Deliveries controller class. - * - * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Webhook_Deliveries_V1_Controller - */ -class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliveries_V1_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v2'; - - /** - * Prepare a single webhook delivery output for response. - * - * @param stdClass $log Delivery log object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_item_for_response( $log, $request ) { - $data = (array) $log; - - $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( $log ) ); - - /** - * Filter webhook delivery object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param stdClass $log Delivery log object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request ); - } - - /** - * Get the Webhook's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'webhook_delivery', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'duration' => array( - 'description' => __( 'The delivery duration, in seconds.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'summary' => array( - 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'request_url' => array( - 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'request_headers' => array( - 'description' => __( 'Request headers.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'request_body' => array( - 'description' => __( 'Request body.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_code' => array( - 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_message' => array( - 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'response_headers' => array( - 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'response_body' => array( - 'description' => __( 'The response body from the receiving server.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the webhook delivery was logged, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php b/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php deleted file mode 100644 index d30967f2392..00000000000 --- a/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php +++ /dev/null @@ -1,182 +0,0 @@ -post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $data = array( - 'id' => $webhook->get_id(), - 'name' => $webhook->get_name(), - 'status' => $webhook->get_status(), - 'topic' => $webhook->get_topic(), - 'resource' => $webhook->get_resource(), - 'event' => $webhook->get_event(), - 'hooks' => $webhook->get_hooks(), - 'delivery_url' => $webhook->get_delivery_url(), - 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $webhook->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), - ); - - $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( $webhook->get_id(), $request ) ); - - /** - * Filter webhook object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WC_Webhook $webhook Webhook object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); - } - - /** - * Get the default REST API version. - * - * @since 3.0.0 - * @return string - */ - protected function get_default_api_version() { - return 'wp_api_v2'; - } - - /** - * Get the Webhook's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'webhook', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Webhook status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'active', - 'enum' => array_keys( wc_get_webhook_statuses() ), - 'context' => array( 'view', 'edit' ), - ), - 'topic' => array( - 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'resource' => array( - 'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'event' => array( - 'description' => __( 'Webhook event.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'hooks' => array( - 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'delivery_url' => array( - 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'secret' => array( - 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-controller.php b/src/Controllers/Version3/class-wc-rest-controller.php deleted file mode 100644 index 5ee0bc41122..00000000000 --- a/src/Controllers/Version3/class-wc-rest-controller.php +++ /dev/null @@ -1,503 +0,0 @@ - - * - * NOTE THAT ONLY CODE RELEVANT FOR MOST ENDPOINTS SHOULD BE INCLUDED INTO THIS CLASS. - * If necessary extend this class and create new abstract classes like `WC_REST_CRUD_Controller` or `WC_REST_Terms_Controller`. - * - * @class WC_REST_Controller - * @package Automattic/WooCommerce/RestApi - * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ - */ - -if ( ! defined( 'ABSPATH' ) ) { - exit; -} - -/** - * Abstract Rest Controller Class - * - * @package Automattic/WooCommerce/RestApi - * @extends WP_REST_Controller - * @version 2.6.0 - */ -abstract class WC_REST_Controller extends WP_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = ''; - - /** - * Add the schema from additional fields to an schema array. - * - * The type of object is inferred from the passed schema. - * - * @param array $schema Schema array. - * - * @return array - */ - protected function add_additional_fields_schema( $schema ) { - if ( empty( $schema['title'] ) ) { - return $schema; - } - - /** - * Can't use $this->get_object_type otherwise we cause an inf loop. - */ - $object_type = $schema['title']; - - $additional_fields = $this->get_additional_fields( $object_type ); - - foreach ( $additional_fields as $field_name => $field_options ) { - if ( ! $field_options['schema'] ) { - continue; - } - - $schema['properties'][ $field_name ] = $field_options['schema']; - } - - $schema['properties'] = apply_filters( 'woocommerce_rest_' . $object_type . '_schema', $schema['properties'] ); - - return $schema; - } - - /** - * Get normalized rest base. - * - * @return string - */ - protected function get_normalized_rest_base() { - return preg_replace( '/\(.*\)\//i', '', $this->rest_base ); - } - - /** - * Check batch limit. - * - * @param array $items Request items. - * @return bool|WP_Error - */ - protected function check_batch_limit( $items ) { - $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); - $total = 0; - - if ( ! empty( $items['create'] ) ) { - $total += count( $items['create'] ); - } - - if ( ! empty( $items['update'] ) ) { - $total += count( $items['update'] ); - } - - if ( ! empty( $items['delete'] ) ) { - $total += count( $items['delete'] ); - } - - if ( $total > $limit ) { - /* translators: %s: items limit */ - return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce-rest-api' ), $limit ), array( 'status' => 413 ) ); - } - - return true; - } - - /** - * Bulk create, update and delete items. - * - * @param WP_REST_Request $request Full details about the request. - * @return array Of WP_Error or WP_REST_Response. - */ - public function batch_items( $request ) { - /** - * REST Server - * - * @var WP_REST_Server $wp_rest_server - */ - global $wp_rest_server; - - // Get the request params. - $items = array_filter( $request->get_params() ); - $query = $request->get_query_params(); - $response = array(); - - // Check batch limit. - $limit = $this->check_batch_limit( $items ); - if ( is_wp_error( $limit ) ) { - return $limit; - } - - if ( ! empty( $items['create'] ) ) { - foreach ( $items['create'] as $item ) { - $_item = new WP_REST_Request( 'POST' ); - - // Default parameters. - $defaults = array(); - $schema = $this->get_public_item_schema(); - foreach ( $schema['properties'] as $arg => $options ) { - if ( isset( $options['default'] ) ) { - $defaults[ $arg ] = $options['default']; - } - } - $_item->set_default_params( $defaults ); - - // Set request parameters. - $_item->set_body_params( $item ); - - // Set query (GET) parameters. - $_item->set_query_params( $query ); - - $_response = $this->create_item( $_item ); - - if ( is_wp_error( $_response ) ) { - $response['create'][] = array( - 'id' => 0, - 'error' => array( - 'code' => $_response->get_error_code(), - 'message' => $_response->get_error_message(), - 'data' => $_response->get_error_data(), - ), - ); - } else { - $response['create'][] = $wp_rest_server->response_to_data( $_response, '' ); - } - } - } - - if ( ! empty( $items['update'] ) ) { - foreach ( $items['update'] as $item ) { - $_item = new WP_REST_Request( 'PUT' ); - $_item->set_body_params( $item ); - $_response = $this->update_item( $_item ); - - if ( is_wp_error( $_response ) ) { - $response['update'][] = array( - 'id' => $item['id'], - 'error' => array( - 'code' => $_response->get_error_code(), - 'message' => $_response->get_error_message(), - 'data' => $_response->get_error_data(), - ), - ); - } else { - $response['update'][] = $wp_rest_server->response_to_data( $_response, '' ); - } - } - } - - if ( ! empty( $items['delete'] ) ) { - foreach ( $items['delete'] as $id ) { - $id = (int) $id; - - if ( 0 === $id ) { - continue; - } - - $_item = new WP_REST_Request( 'DELETE' ); - $_item->set_query_params( - array( - 'id' => $id, - 'force' => true, - ) - ); - $_response = $this->delete_item( $_item ); - - if ( is_wp_error( $_response ) ) { - $response['delete'][] = array( - 'id' => $id, - 'error' => array( - 'code' => $_response->get_error_code(), - 'message' => $_response->get_error_message(), - 'data' => $_response->get_error_data(), - ), - ); - } else { - $response['delete'][] = $wp_rest_server->response_to_data( $_response, '' ); - } - } - } - - return $response; - } - - /** - * Validate a text value for a text based setting. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string - */ - public function validate_setting_text_field( $value, $setting ) { - $value = is_null( $value ) ? '' : $value; - return wp_kses_post( trim( stripslashes( $value ) ) ); - } - - /** - * Validate select based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string|WP_Error - */ - public function validate_setting_select_field( $value, $setting ) { - if ( array_key_exists( $value, $setting['options'] ) ) { - return $value; - } else { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - /** - * Validate multiselect based settings. - * - * @since 3.0.0 - * @param array $values Values. - * @param array $setting Setting. - * @return array|WP_Error - */ - public function validate_setting_multiselect_field( $values, $setting ) { - if ( empty( $values ) ) { - return array(); - } - - if ( ! is_array( $values ) ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $final_values = array(); - foreach ( $values as $value ) { - if ( array_key_exists( $value, $setting['options'] ) ) { - $final_values[] = $value; - } - } - - return $final_values; - } - - /** - * Validate image_width based settings. - * - * @since 3.0.0 - * @param array $values Values. - * @param array $setting Setting. - * @return string|WP_Error - */ - public function validate_setting_image_width_field( $values, $setting ) { - if ( ! is_array( $values ) ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $current = $setting['value']; - if ( isset( $values['width'] ) ) { - $current['width'] = intval( $values['width'] ); - } - if ( isset( $values['height'] ) ) { - $current['height'] = intval( $values['height'] ); - } - if ( isset( $values['crop'] ) ) { - $current['crop'] = (bool) $values['crop']; - } - return $current; - } - - /** - * Validate radio based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string|WP_Error - */ - public function validate_setting_radio_field( $value, $setting ) { - return $this->validate_setting_select_field( $value, $setting ); - } - - /** - * Validate checkbox based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string|WP_Error - */ - public function validate_setting_checkbox_field( $value, $setting ) { - if ( in_array( $value, array( 'yes', 'no' ) ) ) { - return $value; - } elseif ( empty( $value ) ) { - $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; - return $value; - } else { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - } - - /** - * Validate textarea based settings. - * - * @since 3.0.0 - * @param string $value Value. - * @param array $setting Setting. - * @return string - */ - public function validate_setting_textarea_field( $value, $setting ) { - $value = is_null( $value ) ? '' : $value; - return wp_kses( - trim( stripslashes( $value ) ), - array_merge( - array( - 'iframe' => array( - 'src' => true, - 'style' => true, - 'id' => true, - 'class' => true, - ), - ), - wp_kses_allowed_html( 'post' ) - ) - ); - } - - /** - * Add meta query. - * - * @since 3.0.0 - * @param array $args Query args. - * @param array $meta_query Meta query. - * @return array - */ - protected function add_meta_query( $args, $meta_query ) { - if ( empty( $args['meta_query'] ) ) { - $args['meta_query'] = array(); - } - - $args['meta_query'][] = $meta_query; - - return $args['meta_query']; - } - - /** - * Get the batch schema, conforming to JSON Schema. - * - * @return array - */ - public function get_public_batch_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'batch', - 'type' => 'object', - 'properties' => array( - 'create' => array( - 'description' => __( 'List of created resources.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - ), - ), - 'update' => array( - 'description' => __( 'List of updated resources.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - ), - ), - 'delete' => array( - 'description' => __( 'List of delete resources.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'integer', - ), - ), - ), - ); - - return $schema; - } - - /** - * Gets an array of fields to be included on the response. - * - * Included fields are based on item schema and `_fields=` request argument. - * Updated from WordPress 5.3, included into this class to support old versions. - * - * @since 3.5.0 - * @param WP_REST_Request $request Full details about the request. - * @return array Fields to be included in the response. - */ - public function get_fields_for_response( $request ) { - $schema = $this->get_item_schema(); - $properties = isset( $schema['properties'] ) ? $schema['properties'] : array(); - - $additional_fields = $this->get_additional_fields(); - foreach ( $additional_fields as $field_name => $field_options ) { - // For back-compat, include any field with an empty schema - // because it won't be present in $this->get_item_schema(). - if ( is_null( $field_options['schema'] ) ) { - $properties[ $field_name ] = $field_options; - } - } - - // Exclude fields that specify a different context than the request context. - $context = $request['context']; - if ( $context ) { - foreach ( $properties as $name => $options ) { - if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) { - unset( $properties[ $name ] ); - } - } - } - - $fields = array_keys( $properties ); - - if ( ! isset( $request['_fields'] ) ) { - return $fields; - } - $requested_fields = wp_parse_list( $request['_fields'] ); - if ( 0 === count( $requested_fields ) ) { - return $fields; - } - // Trim off outside whitespace from the comma delimited list. - $requested_fields = array_map( 'trim', $requested_fields ); - // Always persist 'id', because it can be needed for add_additional_fields_to_object(). - if ( in_array( 'id', $fields, true ) ) { - $requested_fields[] = 'id'; - } - // Return the list of all requested fields which appear in the schema. - return array_reduce( - $requested_fields, - function( $response_fields, $field ) use ( $fields ) { - if ( in_array( $field, $fields, true ) ) { - $response_fields[] = $field; - return $response_fields; - } - // Check for nested fields if $field is not a direct match. - $nested_fields = explode( '.', $field ); - // A nested field is included so long as its top-level property is - // present in the schema. - if ( in_array( $nested_fields[0], $fields, true ) ) { - $response_fields[] = $field; - } - return $response_fields; - }, - array() - ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-coupons-controller.php b/src/Controllers/Version3/class-wc-rest-coupons-controller.php deleted file mode 100644 index 0df4a6a3395..00000000000 --- a/src/Controllers/Version3/class-wc-rest-coupons-controller.php +++ /dev/null @@ -1,27 +0,0 @@ - 405 ) ); - } - - /** - * Check if a given request has access to read an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return bool|WP_Error - */ - public function delete_item_permissions_check( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get object permalink. - * - * @param object $object Object. - * @return string - */ - protected function get_permalink( $object ) { - return ''; - } - - /** - * Prepares the object for the REST response. - * - * @since 3.0.0 - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. - */ - protected function prepare_object_for_response( $object, $request ) { - // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce-rest-api' ), __METHOD__ ), array( 'status' => 405 ) ); - } - - /** - * Prepares one object for create or update operation. - * - * @since 3.0.0 - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. - */ - protected function prepare_object_for_database( $request, $creating = false ) { - // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce-rest-api' ), __METHOD__ ), array( 'status' => 405 ) ); - } - - /** - * Get a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $data = $this->prepare_object_for_response( $object, $request ); - $response = rest_ensure_response( $data ); - - if ( $this->public ) { - $response->link_header( 'alternate', $this->get_permalink( $object ), array( 'type' => 'text/html' ) ); - } - - return $response; - } - - /** - * Save an object data. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. - * @return WC_Data|WP_Error - */ - protected function save_object( $request, $creating = false ) { - try { - $object = $this->prepare_object_for_database( $request, $creating ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - $object->save(); - - return $this->get_object( $object->get_id() ); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Create a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $object = $this->save_object( $request, true ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - try { - $this->update_additional_fields_for_object( $object, $request ); - - /** - * Fires after a single object is created or updated via the REST API. - * - * @param WC_Data $object Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating object, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); - } catch ( WC_Data_Exception $e ) { - $object->delete(); - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - $object->delete(); - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ) ); - - return $response; - } - - /** - * Update a single post. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $object = $this->get_object( (int) $request['id'] ); - - if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $object = $this->save_object( $request, false ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - try { - $this->update_additional_fields_for_object( $object, $request ); - - /** - * Fires after a single object is created or updated via the REST API. - * - * @param WC_Data $object Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating object, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); - return rest_ensure_response( $response ); - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = array(); - $args['offset'] = $request['offset']; - $args['order'] = $request['order']; - $args['orderby'] = $request['orderby']; - $args['paged'] = $request['page']; - $args['post__in'] = $request['include']; - $args['post__not_in'] = $request['exclude']; - $args['posts_per_page'] = $request['per_page']; - $args['name'] = $request['slug']; - $args['post_parent__in'] = $request['parent']; - $args['post_parent__not_in'] = $request['parent_exclude']; - $args['s'] = $request['search']; - - if ( 'date' === $args['orderby'] ) { - $args['orderby'] = 'date ID'; - } - - $args['date_query'] = array(); - // Set before into date query. Date query must be specified as an array of an array. - if ( isset( $request['before'] ) ) { - $args['date_query'][0]['before'] = $request['before']; - } - - // Set after into date query. Date query must be specified as an array of an array. - if ( isset( $request['after'] ) ) { - $args['date_query'][0]['after'] = $request['after']; - } - - // Force the post_type argument, since it's not a user input variable. - $args['post_type'] = $this->post_type; - - /** - * 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_{$this->post_type}_object_query", $args, $request ); - - return $this->prepare_items_query( $args, $request ); - } - - /** - * Get objects. - * - * @since 3.0.0 - * @param array $query_args Query args. - * @return array - */ - protected function get_objects( $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_filter( array_map( array( $this, 'get_object' ), $result ) ), - 'total' => (int) $total_posts, - 'pages' => (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ), - ); - } - - /** - * Get a collection of posts. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $query_args = $this->prepare_objects_query( $request ); - $query_results = $this->get_objects( $query_args ); - - $objects = array(); - foreach ( $query_results['objects'] as $object ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { - continue; - } - - $data = $this->prepare_object_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 = $this->rest_base; - $attrib_prefix = '(?P<'; - if ( strpos( $base, $attrib_prefix ) !== false ) { - $attrib_names = array(); - preg_match( '/\(\?P<[^>]+>.*\)/', $base, $attrib_names, PREG_OFFSET_CAPTURE ); - foreach ( $attrib_names as $attrib_name_match ) { - $beginning_offset = strlen( $attrib_prefix ); - $attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] ); - $attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset ); - if ( isset( $request[ $attrib_name ] ) ) { - $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); - } - } - } - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $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; - } - - /** - * Delete a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error - */ - public function delete_item( $request ) { - $force = (bool) $request['force']; - $object = $this->get_object( (int) $request['id'] ); - $result = false; - - if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); - - /** - * Filter whether an object is trashable. - * - * Return false to disable trash support for the object. - * - * @param boolean $supports_trash Whether the object type support trashing. - * @param WC_Data $object The object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); - - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_object_for_response( $object, $request ); - - // If we're forcing, then delete permanently. - if ( $force ) { - $object->delete( true ); - $result = 0 === $object->get_id(); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); - } - - // Otherwise, only trash if we haven't already. - if ( is_callable( array( $object, 'get_status' ) ) ) { - if ( 'trash' === $object->get_status() ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); - } - - $object->delete(); - $result = 'trash' === $object->get_status(); - } - } - - if ( ! $result ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); - } - - /** - * Fires after a single object is deleted or trashed via the REST API. - * - * @param WC_Data $object The deleted or trashed object. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return array Links for the given post. - */ - protected function prepare_links( $object, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param(); - $params['context']['default'] = 'view'; - - $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'default' => 10, - 'minimum' => 1, - 'maximum' => 100, - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['search'] = array( - 'description' => __( 'Limit results to those matching a string.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'id', - 'include', - 'title', - 'slug', - 'modified', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - if ( $this->hierarchical ) { - $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'sanitize_callback' => 'wp_parse_id_list', - 'default' => array(), - ); - } - - /** - * Filter collection parameters for the posts controller. - * - * The dynamic part of the filter `$this->post_type` refers to the post - * type slug for the controller. - * - * This filter registers the collection parameter, but does not map the - * collection parameter to an internal WP_Query parameter. Use the - * `rest_{$this->post_type}_query` filter to set WP_Query parameters. - * - * @param array $query_params JSON Schema-formatted collection parameters. - * @param WP_Post_Type $post_type Post type object. - */ - return apply_filters( "rest_{$this->post_type}_collection_params", $params, $this->post_type ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php b/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php deleted file mode 100644 index 78147fe9301..00000000000 --- a/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/downloads endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Customers controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Customer_Downloads_V2_Controller - */ -class WC_REST_Customer_Downloads_Controller extends WC_REST_Customer_Downloads_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; -} diff --git a/src/Controllers/Version3/class-wc-rest-customers-controller.php b/src/Controllers/Version3/class-wc-rest-customers-controller.php deleted file mode 100644 index 65ce592cd55..00000000000 --- a/src/Controllers/Version3/class-wc-rest-customers-controller.php +++ /dev/null @@ -1,307 +0,0 @@ -get_data(); - $format_date = array( 'date_created', 'date_modified' ); - - // Format date values. - foreach ( $format_date as $key ) { - // Date created is stored UTC, date modified is stored WP local time. - $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; - $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); - $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); - } - - return array( - 'id' => $object->get_id(), - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => $data['email'], - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'role' => $data['role'], - 'username' => $data['username'], - 'billing' => $data['billing'], - 'shipping' => $data['shipping'], - 'is_paying_customer' => $data['is_paying_customer'], - 'avatar_url' => $object->get_avatar_url(), - 'meta_data' => $data['meta_data'], - ); - } - - /** - * Get the Customer's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'customer', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'role' => array( - 'description' => __( 'Customer role.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_user', - ), - ), - 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'edit' ), - ), - 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'is_paying_customer' => array( - 'description' => __( 'Is the customer a paying customer?', 'woocommerce-rest-api' ), - 'type' => 'bool', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-data-continents-controller.php b/src/Controllers/Version3/class-wc-rest-data-continents-controller.php deleted file mode 100644 index 7b79f969397..00000000000 --- a/src/Controllers/Version3/class-wc-rest-data-continents-controller.php +++ /dev/null @@ -1,357 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => array( - 'continent' => array( - 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Return the list of countries and states for a given continent. - * - * @since 3.5.0 - * @param string $continent_code Continent code. - * @param WP_REST_Request $request Request data. - * @return array|mixed Response data, ready for insertion into collection data. - */ - public function get_continent( $continent_code = false, $request ) { - $continents = WC()->countries->get_continents(); - $countries = WC()->countries->get_countries(); - $states = WC()->countries->get_states(); - $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php'; - $data = array(); - - if ( ! array_key_exists( $continent_code, $continents ) ) { - return false; - } - - $continent_list = $continents[ $continent_code ]; - - $continent = array( - 'code' => $continent_code, - 'name' => $continent_list['name'], - ); - - $local_countries = array(); - foreach ( $continent_list['countries'] as $country_code ) { - if ( isset( $countries[ $country_code ] ) ) { - $country = array( - 'code' => $country_code, - 'name' => $countries[ $country_code ], - ); - - // If we have detailed locale information include that in the response. - if ( array_key_exists( $country_code, $locale_info ) ) { - // Defensive programming against unexpected changes in locale-info.php. - $country_data = wp_parse_args( - $locale_info[ $country_code ], array( - 'currency_code' => 'USD', - 'currency_pos' => 'left', - 'decimal_sep' => '.', - 'dimension_unit' => 'in', - 'num_decimals' => 2, - 'thousand_sep' => ',', - 'weight_unit' => 'lbs', - ) - ); - - $country = array_merge( $country, $country_data ); - } - - $local_states = array(); - if ( isset( $states[ $country_code ] ) ) { - foreach ( $states[ $country_code ] as $state_code => $state_name ) { - $local_states[] = array( - 'code' => $state_code, - 'name' => $state_name, - ); - } - } - $country['states'] = $local_states; - - // Allow only desired keys (e.g. filter out tax rates). - $allowed = array( - 'code', - 'currency_code', - 'currency_pos', - 'decimal_sep', - 'dimension_unit', - 'name', - 'num_decimals', - 'states', - 'thousand_sep', - 'weight_unit', - ); - $country = array_intersect_key( $country, array_flip( $allowed ) ); - - $local_countries[] = $country; - } - } - - $continent['countries'] = $local_countries; - return $continent; - } - - /** - * Return the list of states for all continents. - * - * @since 3.5.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $continents = WC()->countries->get_continents(); - $data = array(); - - foreach ( array_keys( $continents ) as $continent_code ) { - $continent = $this->get_continent( $continent_code, $request ); - $response = $this->prepare_item_for_response( $continent, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - - return rest_ensure_response( $data ); - } - - /** - * Return the list of locations for a given continent. - * - * @since 3.5.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $data = $this->get_continent( strtoupper( $request['location'] ), $request ); - if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return $this->prepare_item_for_response( $data, $request ); - } - - /** - * Prepare the data object for response. - * - * @since 3.5.0 - * @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 ); - - $response->add_links( $this->prepare_links( $item ) ); - - /** - * Filter the location list returned from the API. - * - * Allows modification of the loction data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param array $item The original list of continent(s), countries, and states. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_data_continent', $response, $item, $request ); - } - - /** - * Prepare links for the request. - * - * @param object $item Data object. - * @return array Links for the given continent. - */ - protected function prepare_links( $item ) { - $continent_code = strtolower( $item['code'] ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $continent_code ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - return $links; - } - - /** - * Get the location schema, conforming to JSON Schema. - * - * @since 3.5.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_continents', - 'type' => 'object', - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of continent.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'countries' => array( - 'type' => 'array', - 'description' => __( 'List of countries on this continent.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency_code' => array( - 'type' => 'string', - 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'currency_pos' => array( - 'type' => 'string', - 'description' => __( 'Currency symbol position for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'decimal_sep' => array( - 'type' => 'string', - 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'dimension_unit' => array( - 'type' => 'string', - 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'num_decimals' => array( - 'type' => 'integer', - 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'states' => array( - 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - 'thousand_sep' => array( - 'type' => 'string', - 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'weight_unit' => array( - 'type' => 'string', - 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-data-controller.php b/src/Controllers/Version3/class-wc-rest-data-controller.php deleted file mode 100644 index e6b794a2ba7..00000000000 --- a/src/Controllers/Version3/class-wc-rest-data-controller.php +++ /dev/null @@ -1,184 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Check whether a given request has permission to read site data. - * - * @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( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check whether a given request has permission to read site settings. - * - * @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( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Return the list of data resources. - * - * @since 3.5.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $data = array(); - $resources = array( - array( - 'slug' => 'continents', - 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce-rest-api' ), - ), - array( - 'slug' => 'countries', - 'description' => __( 'List of supported states in a given country.', 'woocommerce-rest-api' ), - ), - array( - 'slug' => 'currencies', - 'description' => __( 'List of supported currencies.', 'woocommerce-rest-api' ), - ), - ); - - foreach ( $resources as $resource ) { - $item = $this->prepare_item_for_response( (object) $resource, $request ); - $data[] = $this->prepare_response_for_collection( $item ); - } - - return rest_ensure_response( $data ); - } - - /** - * Prepare a data resource object for serialization. - * - * @param stdClass $resource Resource data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $resource, $request ) { - $data = array( - 'slug' => $resource->slug, - 'description' => $resource->description, - ); - - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, 'view' ); - - // Wrap the data in a response object. - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $resource ) ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param object $item Data object. - * @return array Links for the given country. - */ - protected function prepare_links( $item ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->slug ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Get the data index schema, conforming to JSON Schema. - * - * @since 3.5.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_index', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'Data resource ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Data resource description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-data-countries-controller.php b/src/Controllers/Version3/class-wc-rest-data-countries-controller.php deleted file mode 100644 index aaed5e2f30d..00000000000 --- a/src/Controllers/Version3/class-wc-rest-data-countries-controller.php +++ /dev/null @@ -1,240 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => array( - 'location' => array( - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get a list of countries and states. - * - * @param string $country_code Country code. - * @param WP_REST_Request $request Request data. - * @return array|mixed Response data, ready for insertion into collection data. - */ - public function get_country( $country_code = false, $request ) { - $countries = WC()->countries->get_countries(); - $states = WC()->countries->get_states(); - $data = array(); - - if ( ! array_key_exists( $country_code, $countries ) ) { - return false; - } - - $country = array( - 'code' => $country_code, - 'name' => $countries[ $country_code ], - ); - - $local_states = array(); - if ( isset( $states[ $country_code ] ) ) { - foreach ( $states[ $country_code ] as $state_code => $state_name ) { - $local_states[] = array( - 'code' => $state_code, - 'name' => $state_name, - ); - } - } - $country['states'] = $local_states; - return $country; - } - - /** - * Return the list of states for all countries. - * - * @since 3.5.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $countries = WC()->countries->get_countries(); - $data = array(); - - foreach ( array_keys( $countries ) as $country_code ) { - $country = $this->get_country( $country_code, $request ); - $response = $this->prepare_item_for_response( $country, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - - return rest_ensure_response( $data ); - } - - /** - * Return the list of states for a given country. - * - * @since 3.5.0 - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $data = $this->get_country( strtoupper( $request['location'] ), $request ); - if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return $this->prepare_item_for_response( $data, $request ); - } - - /** - * Prepare the data object for response. - * - * @since 3.5.0 - * @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 ); - - $response->add_links( $this->prepare_links( $item ) ); - - /** - * Filter the states list for a country returned from the API. - * - * Allows modification of the loction data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param array $data The original country's states list. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_data_country', $response, $item, $request ); - } - - /** - * Prepare links for the request. - * - * @param object $item Data object. - * @return array Links for the given country. - */ - protected function prepare_links( $item ) { - $country_code = strtolower( $item['code'] ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $country_code ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - - /** - * Get the location schema, conforming to JSON Schema. - * - * @since 3.5.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_countries', - 'type' => 'object', - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'states' => array( - 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'object', - 'context' => array( 'view' ), - 'readonly' => true, - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php b/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php deleted file mode 100644 index eb62a89f048..00000000000 --- a/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php +++ /dev/null @@ -1,221 +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' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/current', array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_current_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\w-]{3})', array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'location' => array( - 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), - 'type' => 'string', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Get currency information. - * - * @param string $code Currency code. - * @param WP_REST_Request $request Request data. - * @return array|mixed Response data, ready for insertion into collection data. - */ - public function get_currency( $code = false, $request ) { - $currencies = get_woocommerce_currencies(); - $data = array(); - - if ( ! array_key_exists( $code, $currencies ) ) { - return false; - } - - $currency = array( - 'code' => $code, - 'name' => $currencies[ $code ], - 'symbol' => get_woocommerce_currency_symbol( $code ), - ); - - return $currency; - } - - /** - * Return the list of currencies. - * - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $currencies = get_woocommerce_currencies(); - foreach ( array_keys( $currencies ) as $code ) { - $currency = $this->get_currency( $code, $request ); - $response = $this->prepare_item_for_response( $currency, $request ); - $data[] = $this->prepare_response_for_collection( $response ); - } - - return rest_ensure_response( $data ); - } - - /** - * Return information for a specific currency. - * - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); - if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - return $this->prepare_item_for_response( $data, $request ); - } - - /** - * Return information for the current site currency. - * - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function get_current_item( $request ) { - $currency = get_option( 'woocommerce_currency' ); - return $this->prepare_item_for_response( $this->get_currency( $currency, $request ), $request ); - } - - /** - * 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 ); - - $response->add_links( $this->prepare_links( $item ) ); - - /** - * Filter currency returned from the API. - * - * @param WP_REST_Response $response The response object. - * @param array $item Currency data. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'woocommerce_rest_prepare_data_currency', $response, $item, $request ); - } - - /** - * Prepare links for the request. - * - * @param object $item Data object. - * @return array Links for the given currency. - */ - protected function prepare_links( $item ) { - $code = strtoupper( $item['code'] ); - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $code ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - - /** - * Get the currency schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'data_currencies', - 'type' => 'object', - 'properties' => array( - 'code' => array( - 'type' => 'string', - 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'type' => 'string', - 'description' => __( 'Full name of currency.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'symbol' => array( - 'type' => 'string', - 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-network-orders-controller.php b/src/Controllers/Version3/class-wc-rest-network-orders-controller.php deleted file mode 100644 index 5b327a54bce..00000000000 --- a/src/Controllers/Version3/class-wc-rest-network-orders-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/notes endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Order Notes controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Order_Notes_V2_Controller - */ -class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; - - /** - * Prepare a single order note output for response. - * - * @param WP_Comment $note Order note object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $note, $request ) { - $data = array( - 'id' => (int) $note->comment_ID, - 'author' => __( 'woocommerce', 'woocommerce-rest-api' ) === $note->comment_author ? 'system' : $note->comment_author, - 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), - 'note' => $note->comment_content, - 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), - ); - - $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( $note ) ); - - /** - * Filter order note object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_Comment $note Order note object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); - } - - /** - * Create a single order note. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - // Create the note. - $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); - - if ( ! $note_id ) { - return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $note = get_comment( $note_id ); - $this->update_additional_fields_for_object( $note, $request ); - - /** - * Fires after a order note is created or updated via the REST API. - * - * @param WP_Comment $note New order note object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $note, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); - - return $response; - } - - /** - * Get the Order Notes schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'order_note', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'author' => array( - 'description' => __( 'Order note author.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'note' => array( - 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'customer_note' => array( - 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'added_by_user' => array( - 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php b/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php deleted file mode 100644 index 865634affe0..00000000000 --- a/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php +++ /dev/null @@ -1,86 +0,0 @@ -/refunds endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Order Refunds controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Order_Refunds_V2_Controller - */ -class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; - - /** - * Prepares one object for create or update operation. - * - * @since 3.0.0 - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $order = wc_get_order( (int) $request['order_id'] ); - - if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); - } - - if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); - } - - // Create the refund. - $refund = wc_create_refund( - array( - 'order_id' => $order->get_id(), - 'amount' => $request['amount'], - 'reason' => empty( $request['reason'] ) ? null : $request['reason'], - 'line_items' => empty( $request['line_items'] ) ? array() : $request['line_items'], - 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, - 'restock_items' => true, - ) - ); - - if ( is_wp_error( $refund ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); - } - - if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); - } - - if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - $refund->save_meta_data(); - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $coupon Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-orders-controller.php b/src/Controllers/Version3/class-wc-rest-orders-controller.php deleted file mode 100644 index 1d2ad09d5d7..00000000000 --- a/src/Controllers/Version3/class-wc-rest-orders-controller.php +++ /dev/null @@ -1,271 +0,0 @@ -get_items( 'coupon' ) as $coupon ) { - $order->remove_coupon( $coupon->get_code() ); - } - - foreach ( $request['coupon_lines'] as $item ) { - if ( is_array( $item ) ) { - if ( empty( $item['id'] ) ) { - if ( empty( $item['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); - } - - $results = $order->apply_coupon( wc_clean( $item['code'] ) ); - - if ( is_wp_error( $results ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); - } - } - } - } - - return true; - } - - /** - * Prepare a single order for create or update. - * - * @throws WC_REST_Exception When fails to set any item. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - $order = new WC_Order( $id ); - $schema = $this->get_item_schema(); - $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); - - // Handle all writable props. - foreach ( $data_keys as $key ) { - $value = $request[ $key ]; - - if ( ! is_null( $value ) ) { - switch ( $key ) { - case 'coupon_lines': - case 'status': - // Change should be done later so transitions have new data. - break; - case 'billing': - case 'shipping': - $this->update_address( $order, $value, $key ); - break; - case 'line_items': - case 'shipping_lines': - case 'fee_lines': - if ( is_array( $value ) ) { - foreach ( $value as $item ) { - if ( is_array( $item ) ) { - if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { - $order->remove_item( $item['id'] ); - } else { - $this->set_item( $order, $key, $item ); - } - } - } - } - break; - case 'meta_data': - if ( is_array( $value ) ) { - foreach ( $value as $meta ) { - $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - break; - default: - if ( is_callable( array( $order, "set_{$key}" ) ) ) { - $order->{"set_{$key}"}( $value ); - } - break; - } - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $order Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); - } - - /** - * Save an object data. - * - * @since 3.0.0 - * @throws WC_REST_Exception But all errors are validated before returning any data. - * @param WP_REST_Request $request Full details about the request. - * @param bool $creating If is creating a new object. - * @return WC_Data|WP_Error - */ - protected function save_object( $request, $creating = false ) { - try { - $object = $this->prepare_object_for_database( $request, $creating ); - - if ( is_wp_error( $object ) ) { - return $object; - } - - // Make sure gateways are loaded so hooks from gateways fire on save/create. - WC()->payment_gateways(); - - if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { - // Make sure customer exists. - if ( false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); - } - - // Make sure customer is part of blog. - if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { - add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); - } - } - - if ( $creating ) { - $object->set_created_via( 'rest-api' ); - $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); - $object->calculate_totals(); - } else { - // If items have changed, recalculate order totals. - if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { - $object->calculate_totals( true ); - } - } - - // Set coupons. - $this->calculate_coupons( $request, $object ); - - // Set status. - if ( ! empty( $request['status'] ) ) { - $object->set_status( $request['status'] ); - } - - $object->save(); - - // Actions for after the order is saved. - if ( true === $request['set_paid'] ) { - if ( $creating || $object->needs_payment() ) { - $object->payment_complete( $request['transaction_id'] ); - } - } - - return $this->get_object( $object->get_id() ); - } catch ( WC_Data_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); - } catch ( WC_REST_Exception $e ) { - return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); - } - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - // This is needed to get around an array to string notice in WC_REST_Orders_V2_Controller::prepare_objects_query. - $statuses = $request['status']; - unset( $request['status'] ); - $args = parent::prepare_objects_query( $request ); - - $args['post_status'] = array(); - foreach ( $statuses as $status ) { - if ( in_array( $status, $this->get_order_statuses(), true ) ) { - $args['post_status'][] = 'wc-' . $status; - } elseif ( 'any' === $status ) { - // Set status to "any" and short-circuit out. - $args['post_status'] = 'any'; - break; - } else { - $args['post_status'][] = $status; - } - } - - // Put the statuses back for further processing (next/prev links, etc). - $request['status'] = $statuses; - - return $args; - } - - /** - * Get the Order's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = parent::get_item_schema(); - - $schema['properties']['coupon_lines']['items']['properties']['discount']['readonly'] = true; - - return $schema; - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['status'] = array( - 'default' => 'any', - 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php b/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php deleted file mode 100644 index f48b155f3dd..00000000000 --- a/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php +++ /dev/null @@ -1,226 +0,0 @@ - $gateway->id, - 'title' => $gateway->title, - 'description' => $gateway->description, - 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', - 'enabled' => ( 'yes' === $gateway->enabled ), - 'method_title' => $gateway->get_method_title(), - 'method_description' => $gateway->get_method_description(), - 'method_supports' => $gateway->supports, - 'settings' => $this->get_settings( $gateway ), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $item, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $gateway, $request ) ); - - /** - * Filter payment gateway objects returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WC_Payment_Gateway $gateway Payment gateway object. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); - } - - /** - * Return settings associated with this payment gateway. - * - * @param WC_Payment_Gateway $gateway Gateway instance. - * - * @return array - */ - public function get_settings( $gateway ) { - $settings = array(); - $gateway->init_form_fields(); - foreach ( $gateway->form_fields as $id => $field ) { - // Make sure we at least have a title and type. - if ( empty( $field['title'] ) || empty( $field['type'] ) ) { - continue; - } - - // Ignore 'enabled' and 'description' which get included elsewhere. - if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { - continue; - } - - $data = array( - 'id' => $id, - 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - - /** - * Get the payment gateway schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'payment_gateway', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'absint', - ), - ), - 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - ), - 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'method_supports' => array( - 'description' => __( 'Supported features for this payment gateway.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - ), - ), - 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-posts-controller.php b/src/Controllers/Version3/class-wc-rest-posts-controller.php deleted file mode 100644 index 0db471b87a3..00000000000 --- a/src/Controllers/Version3/class-wc-rest-posts-controller.php +++ /dev/null @@ -1,724 +0,0 @@ -post_type, 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $post = get_post( (int) $request['id'] ); - - if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $post = get_post( (int) $request['id'] ); - - if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete an item. - * - * @param WP_REST_Request $request Full details about the request. - * @return bool|WP_Error - */ - public function delete_item_permissions_check( $request ) { - $post = get_post( (int) $request['id'] ); - - if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return boolean|WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $id = (int) $request['id']; - $post = get_post( $id ); - - if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $data = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $data ); - - if ( $this->public ) { - $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) ); - } - - return $response; - } - - /** - * Create a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); - } - - $post = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $post ) ) { - return $post; - } - - $post->post_type = $this->post_type; - $post_id = wp_insert_post( $post, true ); - - if ( is_wp_error( $post_id ) ) { - - if ( in_array( $post_id->get_error_code(), array( 'db_insert_error' ) ) ) { - $post_id->add_data( array( 'status' => 500 ) ); - } else { - $post_id->add_data( array( 'status' => 400 ) ); - } - return $post_id; - } - $post->ID = $post_id; - $post = get_post( $post_id ); - - $this->update_additional_fields_for_object( $post, $request ); - - // Add meta fields. - $meta_fields = $this->add_post_meta_fields( $post, $request ); - if ( is_wp_error( $meta_fields ) ) { - // Remove post. - $this->delete_post( $post ); - - return $meta_fields; - } - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post_id ) ) ); - - return $response; - } - - /** - * Add post meta fields. - * - * @param WP_Post $post Post Object. - * @param WP_REST_Request $request WP_REST_Request Object. - * @return bool|WP_Error - */ - protected function add_post_meta_fields( $post, $request ) { - return true; - } - - /** - * Delete post. - * - * @param WP_Post $post Post object. - */ - protected function delete_post( $post ) { - wp_delete_post( $post->ID, true ); - } - - /** - * Update a single post. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $id = (int) $request['id']; - $post = get_post( $id ); - - if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $post = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $post ) ) { - return $post; - } - // Convert the post object to an array, otherwise wp_update_post will expect non-escaped input. - $post_id = wp_update_post( (array) $post, true ); - if ( is_wp_error( $post_id ) ) { - if ( in_array( $post_id->get_error_code(), array( 'db_update_error' ) ) ) { - $post_id->add_data( array( 'status' => 500 ) ); - } else { - $post_id->add_data( array( 'status' => 400 ) ); - } - return $post_id; - } - - $post = get_post( $post_id ); - $this->update_additional_fields_for_object( $post, $request ); - - // Update meta fields. - $meta_fields = $this->update_post_meta_fields( $post, $request ); - if ( is_wp_error( $meta_fields ) ) { - return $meta_fields; - } - - /** - * Fires after a single item is created or updated via the REST API. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. - */ - do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - return rest_ensure_response( $response ); - } - - /** - * Get a collection of posts. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_items( $request ) { - $args = array(); - $args['offset'] = $request['offset']; - $args['order'] = $request['order']; - $args['orderby'] = $request['orderby']; - $args['paged'] = $request['page']; - $args['post__in'] = $request['include']; - $args['post__not_in'] = $request['exclude']; - $args['posts_per_page'] = $request['per_page']; - $args['name'] = $request['slug']; - $args['post_parent__in'] = $request['parent']; - $args['post_parent__not_in'] = $request['parent_exclude']; - $args['s'] = $request['search']; - - $args['date_query'] = array(); - // Set before into date query. Date query must be specified as an array of an array. - if ( isset( $request['before'] ) ) { - $args['date_query'][0]['before'] = $request['before']; - } - - // Set after into date query. Date query must be specified as an array of an array. - if ( isset( $request['after'] ) ) { - $args['date_query'][0]['after'] = $request['after']; - } - - if ( 'wc/v1' === $this->namespace ) { - if ( is_array( $request['filter'] ) ) { - $args = array_merge( $args, $request['filter'] ); - unset( $args['filter'] ); - } - } - - // Force the post_type argument, since it's not a user input variable. - $args['post_type'] = $this->post_type; - - /** - * 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_{$this->post_type}_query", $args, $request ); - $query_args = $this->prepare_items_query( $args, $request ); - - $posts_query = new WP_Query(); - $query_result = $posts_query->query( $query_args ); - - $posts = array(); - foreach ( $query_result as $post ) { - if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { - continue; - } - - $data = $this->prepare_item_for_response( $post, $request ); - $posts[] = $this->prepare_response_for_collection( $data ); - } - - $page = (int) $query_args['paged']; - $total_posts = $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; - } - - $max_pages = ceil( $total_posts / (int) $query_args['posts_per_page'] ); - - $response = rest_ensure_response( $posts ); - $response->header( 'X-WP-Total', (int) $total_posts ); - $response->header( 'X-WP-TotalPages', (int) $max_pages ); - - $request_params = $request->get_query_params(); - if ( ! empty( $request_params['filter'] ) ) { - // Normalize the pagination params. - unset( $request_params['filter']['posts_per_page'] ); - unset( $request_params['filter']['paged'] ); - } - $base = add_query_arg( $request_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; - } - - /** - * Delete a single item. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error - */ - public function delete_item( $request ) { - $id = (int) $request['id']; - $force = (bool) $request['force']; - $post = get_post( $id ); - - if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $supports_trash = EMPTY_TRASH_DAYS > 0; - - /** - * Filter whether an item is trashable. - * - * Return false to disable trash support for the item. - * - * @param boolean $supports_trash Whether the item type support trashing. - * @param WP_Post $post The Post object being considered for trashing support. - */ - $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); - - if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $post, $request ); - - // If we're forcing, then delete permanently. - if ( $force ) { - $result = wp_delete_post( $id, true ); - } else { - // If we don't support trashing for this type, error out. - if ( ! $supports_trash ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); - } - - // Otherwise, only trash if we haven't already. - if ( 'trash' === $post->post_status ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); - } - - // (Note that internally this falls through to `wp_delete_post` if - // the trash is disabled.) - $result = wp_trash_post( $id ); - } - - if ( ! $result ) { - /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); - } - - /** - * Fires after a single item is deleted or trashed via the REST API. - * - * @param object $post The deleted or trashed item. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return array Links for the given post. - */ - protected function prepare_links( $post, $request ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - return $links; - } - - /** - * Determine the allowed query_vars for a get_items() response and - * prepare for WP_Query. - * - * @param array $prepared_args Prepared arguments. - * @param WP_REST_Request $request Request object. - * @return array $query_args - */ - protected function prepare_items_query( $prepared_args = array(), $request = null ) { - - $valid_vars = array_flip( $this->get_allowed_query_vars() ); - $query_args = array(); - foreach ( $valid_vars as $var => $index ) { - if ( isset( $prepared_args[ $var ] ) ) { - /** - * Filter the query_vars used in `get_items` for the constructed query. - * - * The dynamic portion of the hook name, $var, refers to the query_var key. - * - * @param mixed $prepared_args[ $var ] The query_var value. - */ - $query_args[ $var ] = apply_filters( "woocommerce_rest_query_var-{$var}", $prepared_args[ $var ] ); - } - } - - $query_args['ignore_sticky_posts'] = true; - - if ( 'include' === $query_args['orderby'] ) { - $query_args['orderby'] = 'post__in'; - } elseif ( 'id' === $query_args['orderby'] ) { - $query_args['orderby'] = 'ID'; // ID must be capitalized. - } elseif ( 'slug' === $query_args['orderby'] ) { - $query_args['orderby'] = 'name'; - } - - return $query_args; - } - - /** - * Get all the WP Query vars that are allowed for the API request. - * - * @return array - */ - protected function get_allowed_query_vars() { - global $wp; - - /** - * Filter the publicly allowed query vars. - * - * Allows adjusting of the default query vars that are made public. - * - * @param array Array of allowed WP_Query query vars. - */ - $valid_vars = apply_filters( 'query_vars', $wp->public_query_vars ); - - $post_type_obj = get_post_type_object( $this->post_type ); - if ( current_user_can( $post_type_obj->cap->edit_posts ) ) { - /** - * Filter the allowed 'private' query vars for authorized users. - * - * If the user has the `edit_posts` capability, we also allow use of - * private query parameters, which are only undesirable on the - * frontend, but are safe for use in query strings. - * - * To disable anyway, use - * `add_filter( 'woocommerce_rest_private_query_vars', '__return_empty_array' );` - * - * @param array $private_query_vars Array of allowed query vars for authorized users. - * } - */ - $private = apply_filters( 'woocommerce_rest_private_query_vars', $wp->private_query_vars ); - $valid_vars = array_merge( $valid_vars, $private ); - } - // Define our own in addition to WP's normal vars. - $rest_valid = array( - 'date_query', - 'ignore_sticky_posts', - 'offset', - 'post__in', - 'post__not_in', - 'post_parent', - 'post_parent__in', - 'post_parent__not_in', - 'posts_per_page', - 'meta_query', - 'tax_query', - 'meta_key', - 'meta_value', - 'meta_compare', - 'meta_value_num', - ); - $valid_vars = array_merge( $valid_vars, $rest_valid ); - - /** - * Filter allowed query vars for the REST API. - * - * This filter allows you to add or remove query vars from the final allowed - * list for all requests, including unauthenticated ones. To alter the - * vars for editors only. - * - * @param array { - * Array of allowed WP_Query query vars. - * - * @param string $allowed_query_var The query var to allow. - * } - */ - $valid_vars = apply_filters( 'woocommerce_rest_query_vars', $valid_vars ); - - return $valid_vars; - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['context']['default'] = 'view'; - - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - '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-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( - 'date', - 'id', - 'include', - 'title', - 'slug', - 'modified', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - - $post_type_obj = get_post_type_object( $this->post_type ); - - if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) { - $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'sanitize_callback' => 'wp_parse_id_list', - 'default' => array(), - ); - } - - if ( 'wc/v1' === $this->namespace ) { - $params['filter'] = array( - 'type' => 'object', - 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce-rest-api' ), - ); - } - - return $params; - } - - /** - * Update post meta fields. - * - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return bool|WP_Error - */ - protected function update_post_meta_fields( $post, $request ) { - return true; - } -} diff --git a/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php b/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php deleted file mode 100644 index bbbdb6eb822..00000000000 --- a/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/terms endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 2.6.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Product Attribute Terms controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Product_Attribute_Terms_V2_Controller - */ -class WC_REST_Product_Attribute_Terms_Controller extends WC_REST_Product_Attribute_Terms_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; -} diff --git a/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php b/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php deleted file mode 100644 index 3506306c130..00000000000 --- a/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -term_id, 'display_type', true ); - - // Get category order. - $menu_order = get_term_meta( $item->term_id, 'order', true ); - - $data = array( - 'id' => (int) $item->term_id, - 'name' => $item->name, - 'slug' => $item->slug, - 'parent' => (int) $item->parent, - 'description' => $item->description, - 'display' => $display_type ? $display_type : 'default', - 'image' => null, - 'menu_order' => (int) $menu_order, - 'count' => (int) $item->count, - ); - - // Get category image. - $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); - if ( $image_id ) { - $attachment = get_post( $image_id ); - - $data['image'] = array( - 'id' => (int) $image_id, - 'date_created' => wc_rest_prepare_date_response( $attachment->post_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), - 'src' => wp_get_attachment_url( $image_id ), - 'name' => get_the_title( $attachment ), - 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), - ); - } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $item, $request ) ); - - /** - * Filter a term item returned from the API. - * - * Allows modification of the term data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param object $item The original term object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); - } - - /** - * Get the Category schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->taxonomy, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'default', - 'enum' => array( 'default', 'products', 'subcategories', 'both' ), - 'context' => array( 'view', 'edit' ), - ), - 'image' => array( - 'description' => __( 'Image data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Update term meta fields. - * - * @param WP_Term $term Term object. - * @param WP_REST_Request $request Request instance. - * @return bool|WP_Error - * - * @since 3.5.5 - */ - protected function update_term_meta_fields( $term, $request ) { - $id = (int) $term->term_id; - - if ( isset( $request['display'] ) ) { - update_term_meta( $id, 'display_type', 'default' === $request['display'] ? '' : $request['display'] ); - } - - if ( isset( $request['menu_order'] ) ) { - update_term_meta( $id, 'order', $request['menu_order'] ); - } - - if ( isset( $request['image'] ) ) { - if ( empty( $request['image']['id'] ) && ! empty( $request['image']['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $request['image']['src'] ) ); - - if ( is_wp_error( $upload ) ) { - return $upload; - } - - $image_id = wc_rest_set_uploaded_image_as_attachment( $upload ); - } else { - $image_id = isset( $request['image']['id'] ) ? absint( $request['image']['id'] ) : 0; - } - - // Check if image_id is a valid image attachment before updating the term meta. - if ( $image_id && wp_attachment_is_image( $image_id ) ) { - update_term_meta( $id, 'thumbnail_id', $image_id ); - - // Set the image alt. - if ( ! empty( $request['image']['alt'] ) ) { - update_post_meta( $image_id, '_wp_attachment_image_alt', wc_clean( $request['image']['alt'] ) ); - } - - // Set the image title. - if ( ! empty( $request['image']['name'] ) ) { - wp_update_post( - array( - 'ID' => $image_id, - 'post_title' => wc_clean( $request['image']['name'] ), - ) - ); - } - } else { - delete_term_meta( $id, 'thumbnail_id' ); - } - } - - return true; - } -} diff --git a/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php b/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php deleted file mode 100644 index aee1016454f..00000000000 --- a/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php +++ /dev/null @@ -1,1164 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( - 'product_id' => array( - 'required' => true, - 'description' => __( 'Unique identifier for the product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - 'review' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce-rest-api' ), - ), - 'reviewer' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce-rest-api' ), - ), - 'reviewer_email' => array( - 'required' => true, - 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce-rest-api' ), - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) - ); - } - - /** - * Check whether a given request has permission to read webhook deliveries. - * - * @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_product_reviews_permissions( 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $id = (int) $request['id']; - $review = get_comment( $id ); - - if ( $review && ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create a new product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $id = (int) $request['id']; - $review = get_comment( $id ); - - if ( $review && ! wc_rest_check_product_reviews_permissions( 'edit', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete a product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $id = (int) $request['id']; - $review = get_comment( $id ); - - if ( $review && ! wc_rest_check_product_reviews_permissions( 'delete', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param WP_REST_Request $request Full details about the request. - * @return boolean|WP_Error - */ - public function batch_items_permissions_check( $request ) { - if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Get all reviews. - * - * @param WP_REST_Request $request Full details about the request. - * @return array|WP_Error - */ - public function get_items( $request ) { - // Retrieve the list of registered collection query parameters. - $registered = $this->get_collection_params(); - - /* - * This array defines mappings between public API query parameters whose - * values are accepted as-passed, and their internal WP_Query parameter - * name equivalents (some are the same). Only values which are also - * present in $registered will be set. - */ - $parameter_mappings = array( - 'reviewer' => 'author__in', - 'reviewer_email' => 'author_email', - 'reviewer_exclude' => 'author__not_in', - 'exclude' => 'comment__not_in', - 'include' => 'comment__in', - 'offset' => 'offset', - 'order' => 'order', - 'per_page' => 'number', - 'product' => 'post__in', - 'search' => 'search', - 'status' => 'status', - ); - - $prepared_args = array(); - - /* - * For each known parameter which is both registered and present in the request, - * set the parameter's value on the query $prepared_args. - */ - foreach ( $parameter_mappings as $api_param => $wp_param ) { - if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { - $prepared_args[ $wp_param ] = $request[ $api_param ]; - } - } - - // Ensure certain parameter values default to empty strings. - foreach ( array( 'author_email', 'search' ) as $param ) { - if ( ! isset( $prepared_args[ $param ] ) ) { - $prepared_args[ $param ] = ''; - } - } - - if ( isset( $registered['orderby'] ) ) { - $prepared_args['orderby'] = $this->normalize_query_param( $request['orderby'] ); - } - - if ( isset( $prepared_args['status'] ) ) { - $prepared_args['status'] = 'approved' === $prepared_args['status'] ? 'approve' : $prepared_args['status']; - } - - $prepared_args['no_found_rows'] = false; - $prepared_args['date_query'] = array(); - - // Set before into date query. Date query must be specified as an array of an array. - if ( isset( $registered['before'], $request['before'] ) ) { - $prepared_args['date_query'][0]['before'] = $request['before']; - } - - // Set after into date query. Date query must be specified as an array of an array. - if ( isset( $registered['after'], $request['after'] ) ) { - $prepared_args['date_query'][0]['after'] = $request['after']; - } - - if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { - $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); - } - - /** - * Filters arguments, before passing to WP_Comment_Query, when querying reviews via the REST API. - * - * @since 3.5.0 - * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ - * @param array $prepared_args Array of arguments for WP_Comment_Query. - * @param WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( 'woocommerce_rest_product_review_query', $prepared_args, $request ); - - // Make sure that returns only reviews. - $prepared_args['type'] = 'review'; - - // Query reviews. - $query = new WP_Comment_Query(); - $query_result = $query->query( $prepared_args ); - $reviews = array(); - - foreach ( $query_result as $review ) { - if ( ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { - continue; - } - - $data = $this->prepare_item_for_response( $review, $request ); - $reviews[] = $this->prepare_response_for_collection( $data ); - } - - $total_reviews = (int) $query->found_comments; - $max_pages = (int) $query->max_num_pages; - - if ( $total_reviews < 1 ) { - // Out-of-bounds, run the query again without LIMIT for total count. - unset( $prepared_args['number'], $prepared_args['offset'] ); - - $query = new WP_Comment_Query(); - $prepared_args['count'] = true; - - $total_reviews = $query->query( $prepared_args ); - $max_pages = ceil( $total_reviews / $request['per_page'] ); - } - - $response = rest_ensure_response( $reviews ); - $response->header( 'X-WP-Total', $total_reviews ); - $response->header( 'X-WP-TotalPages', $max_pages ); - - $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); - - if ( $request['page'] > 1 ) { - $prev_page = $request['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 > $request['page'] ) { - $next_page = $request['page'] + 1; - $next_link = add_query_arg( 'page', $next_page, $base ); - - $response->link_header( 'next', $next_link ); - } - - return $response; - } - - /** - * Create a single review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function create_item( $request ) { - if ( ! empty( $request['id'] ) ) { - return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $product_id = (int) $request['product_id']; - - if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $prepared_review = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $prepared_review ) ) { - return $prepared_review; - } - - $prepared_review['comment_type'] = 'review'; - - /* - * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). - */ - if ( empty( $prepared_review['comment_content'] ) ) { - return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). - if ( ! isset( $prepared_review['comment_date_gmt'] ) ) { - $prepared_review['comment_date_gmt'] = current_time( 'mysql', true ); - } - - if ( ! empty( $_SERVER['REMOTE_ADDR'] ) && rest_is_ip_address( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) ) { // WPCS: input var ok, sanitization ok. - $prepared_review['comment_author_IP'] = wc_clean( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // WPCS: input var ok. - } else { - $prepared_review['comment_author_IP'] = '127.0.0.1'; - } - - if ( ! empty( $request['author_user_agent'] ) ) { - $prepared_review['comment_agent'] = $request['author_user_agent']; - } elseif ( $request->get_header( 'user_agent' ) ) { - $prepared_review['comment_agent'] = $request->get_header( 'user_agent' ); - } else { - $prepared_review['comment_agent'] = ''; - } - - $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); - if ( is_wp_error( $check_comment_lengths ) ) { - $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $prepared_review['comment_parent'] = 0; - $prepared_review['comment_author_url'] = ''; - $prepared_review['comment_approved'] = wp_allow_comment( $prepared_review, true ); - - if ( is_wp_error( $prepared_review['comment_approved'] ) ) { - $error_code = $prepared_review['comment_approved']->get_error_code(); - $error_message = $prepared_review['comment_approved']->get_error_message(); - - if ( 'comment_duplicate' === $error_code ) { - return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 409 ) ); - } - - if ( 'comment_flood' === $error_code ) { - return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 400 ) ); - } - - return $prepared_review['comment_approved']; - } - - /** - * Filters a review before it is inserted via the REST API. - * - * Allows modification of the review right before it is inserted via wp_insert_comment(). - * Returning a WP_Error value from the filter will shortcircuit insertion and allow - * skipping further processing. - * - * @since 3.5.0 - * @param array|WP_Error $prepared_review The prepared review data for wp_insert_comment(). - * @param WP_REST_Request $request Request used to insert the review. - */ - $prepared_review = apply_filters( 'woocommerce_rest_pre_insert_product_review', $prepared_review, $request ); - if ( is_wp_error( $prepared_review ) ) { - return $prepared_review; - } - - $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); - - if ( ! $review_id ) { - return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - if ( isset( $request['status'] ) ) { - $this->handle_status_param( $request['status'], $review_id ); - } - - update_comment_meta( $review_id, 'rating', ! empty( $request['rating'] ) ? $request['rating'] : '0' ); - - $review = get_comment( $review_id ); - - /** - * Fires after a comment is created or updated via the REST API. - * - * @param WP_Comment $review Inserted or updated comment object. - * @param WP_REST_Request $request Request object. - * @param bool $creating True when creating a comment, false when updating. - */ - do_action( 'woocommerce_rest_insert_product_review', $review, $request, true ); - - $fields_update = $this->update_additional_fields_for_object( $review, $request ); - if ( is_wp_error( $fields_update ) ) { - return $fields_update; - } - - $context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view'; - $request->set_param( 'context', $context ); - - $response = $this->prepare_item_for_response( $review, $request ); - $response = rest_ensure_response( $response ); - - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $review_id ) ) ); - - return $response; - } - - /** - * Get a single product review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response - */ - public function get_item( $request ) { - $review = $this->get_review( $request['id'] ); - if ( is_wp_error( $review ) ) { - return $review; - } - - $data = $this->prepare_item_for_response( $review, $request ); - $response = rest_ensure_response( $data ); - - return $response; - } - - /** - * Updates a review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. - */ - public function update_item( $request ) { - $review = $this->get_review( $request['id'] ); - if ( is_wp_error( $review ) ) { - return $review; - } - - $id = (int) $review->comment_ID; - - if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { - return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $prepared_args = $this->prepare_item_for_database( $request ); - if ( is_wp_error( $prepared_args ) ) { - return $prepared_args; - } - - if ( ! empty( $prepared_args['comment_post_ID'] ) ) { - if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - } - - if ( empty( $prepared_args ) && isset( $request['status'] ) ) { - // Only the comment status is being changed. - $change = $this->handle_status_param( $request['status'], $id ); - - if ( ! $change ) { - return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - } elseif ( ! empty( $prepared_args ) ) { - if ( is_wp_error( $prepared_args ) ) { - return $prepared_args; - } - - if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { - return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $prepared_args['comment_ID'] = $id; - - $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); - if ( is_wp_error( $check_comment_lengths ) ) { - $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - - $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); - - if ( false === $updated ) { - return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - if ( isset( $request['status'] ) ) { - $this->handle_status_param( $request['status'], $id ); - } - } - - if ( ! empty( $request['rating'] ) ) { - update_comment_meta( $id, 'rating', $request['rating'] ); - } - - $review = get_comment( $id ); - - /** This action is documented in includes/api/class-wc-rest-product-reviews-controller.php */ - do_action( 'woocommerce_rest_insert_product_review', $review, $request, false ); - - $fields_update = $this->update_additional_fields_for_object( $review, $request ); - - if ( is_wp_error( $fields_update ) ) { - return $fields_update; - } - - $request->set_param( 'context', 'edit' ); - - $response = $this->prepare_item_for_response( $review, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Deletes a review. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. - */ - public function delete_item( $request ) { - $review = $this->get_review( $request['id'] ); - if ( is_wp_error( $review ) ) { - return $review; - } - - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - /** - * Filters whether a review can be trashed. - * - * Return false to disable trash support for the post. - * - * @since 3.5.0 - * @param bool $supports_trash Whether the post type support trashing. - * @param WP_Comment $review The review object being considered for trashing support. - */ - $supports_trash = apply_filters( 'woocommerce_rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $review ); - - $request->set_param( 'context', 'edit' ); - - if ( $force ) { - $previous = $this->prepare_item_for_response( $review, $request ); - $result = wp_delete_comment( $review->comment_ID, true ); - $response = new WP_REST_Response(); - $response->set_data( - array( - 'deleted' => true, - 'previous' => $previous->get_data(), - ) - ); - } else { - // If this type doesn't support trashing, error out. - if ( ! $supports_trash ) { - /* translators: %s: force=true */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce-rest-api' ), 'force=true' ), array( 'status' => 501 ) ); - } - - if ( 'trash' === $review->comment_approved ) { - return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce-rest-api' ), array( 'status' => 410 ) ); - } - - $result = wp_trash_comment( $review->comment_ID ); - $review = get_comment( $review->comment_ID ); - $response = $this->prepare_item_for_response( $review, $request ); - } - - if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a review is deleted via the REST API. - * - * @param WP_Comment $review The deleted review data. - * @param WP_REST_Response $response The response returned from the API. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( 'woocommerce_rest_delete_review', $review, $response, $request ); - - return $response; - } - - /** - * Prepare a single product review output for response. - * - * @param WP_Comment $review Product review object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $review, $request ) { - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $fields = $this->get_fields_for_response( $request ); - $data = array(); - - if ( in_array( 'id', $fields, true ) ) { - $data['id'] = (int) $review->comment_ID; - } - if ( in_array( 'date_created', $fields, true ) ) { - $data['date_created'] = wc_rest_prepare_date_response( $review->comment_date ); - } - if ( in_array( 'date_created_gmt', $fields, true ) ) { - $data['date_created_gmt'] = wc_rest_prepare_date_response( $review->comment_date_gmt ); - } - if ( in_array( 'product_id', $fields, true ) ) { - $data['product_id'] = (int) $review->comment_post_ID; - } - if ( in_array( 'status', $fields, true ) ) { - $data['status'] = $this->prepare_status_response( (string) $review->comment_approved ); - } - if ( in_array( 'reviewer', $fields, true ) ) { - $data['reviewer'] = $review->comment_author; - } - if ( in_array( 'reviewer_email', $fields, true ) ) { - $data['reviewer_email'] = $review->comment_author_email; - } - if ( in_array( 'review', $fields, true ) ) { - $data['review'] = 'view' === $context ? wpautop( $review->comment_content ) : $review->comment_content; - } - if ( in_array( 'rating', $fields, true ) ) { - $data['rating'] = (int) get_comment_meta( $review->comment_ID, 'rating', true ); - } - if ( in_array( 'verified', $fields, true ) ) { - $data['verified'] = wc_review_is_from_verified_owner( $review->comment_ID ); - } - if ( in_array( 'reviewer_avatar_urls', $fields, true ) ) { - $data['reviewer_avatar_urls'] = rest_get_avatar_urls( $review->comment_author_email ); - } - - $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( $review ) ); - - /** - * Filter product reviews object returned from the REST API. - * - * @param WP_REST_Response $response The response object. - * @param WP_Comment $review Product review object used to create response. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); - } - - /** - * Prepare a single product review to be inserted into the database. - * - * @param WP_REST_Request $request Request object. - * @return array|WP_Error $prepared_review - */ - protected function prepare_item_for_database( $request ) { - if ( isset( $request['id'] ) ) { - $prepared_review['comment_ID'] = (int) $request['id']; - } - - if ( isset( $request['review'] ) ) { - $prepared_review['comment_content'] = $request['review']; - } - - if ( isset( $request['product_id'] ) ) { - $prepared_review['comment_post_ID'] = (int) $request['product_id']; - } - - if ( isset( $request['reviewer'] ) ) { - $prepared_review['comment_author'] = $request['reviewer']; - } - - if ( isset( $request['reviewer_email'] ) ) { - $prepared_review['comment_author_email'] = $request['reviewer_email']; - } - - if ( ! empty( $request['date_created'] ) ) { - $date_data = rest_get_date_with_gmt( $request['date_created'] ); - - if ( ! empty( $date_data ) ) { - list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; - } - } elseif ( ! empty( $request['date_created_gmt'] ) ) { - $date_data = rest_get_date_with_gmt( $request['date_created_gmt'], true ); - - if ( ! empty( $date_data ) ) { - list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; - } - } - - /** - * Filters a review after it is prepared for the database. - * - * Allows modification of the review right after it is prepared for the database. - * - * @since 3.5.0 - * @param array $prepared_review The prepared review data for `wp_insert_comment`. - * @param WP_REST_Request $request The current request. - */ - return apply_filters( 'woocommerce_rest_preprocess_product_review', $prepared_review, $request ); - } - - /** - * Prepare links for the request. - * - * @param WP_Comment $review Product review object. - * @return array Links for the given product review. - */ - protected function prepare_links( $review ) { - $links = array( - 'self' => array( - 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $review->comment_ID ) ), - ), - 'collection' => array( - 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), - ), - ); - - if ( 0 !== (int) $review->comment_post_ID ) { - $links['up'] = array( - 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $review->comment_post_ID ) ), - ); - } - - if ( 0 !== (int) $review->user_id ) { - $links['reviewer'] = array( - 'href' => rest_url( 'wp/v2/users/' . $review->user_id ), - 'embeddable' => true, - ); - } - - return $links; - } - - /** - * Get the Product Review's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'product_review', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the review was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'product_id' => array( - 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Status of the review.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'approved', - 'enum' => array( 'approved', 'hold', 'spam', 'unspam', 'trash', 'untrash' ), - 'context' => array( 'view', 'edit' ), - ), - 'reviewer' => array( - 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'reviewer_email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'email', - 'context' => array( 'view', 'edit' ), - ), - 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'arg_options' => array( - 'sanitize_callback' => 'wp_filter_post_kses', - ), - ), - 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - if ( get_option( 'show_avatars' ) ) { - $avatar_properties = array(); - $avatar_sizes = rest_get_avatar_sizes(); - - foreach ( $avatar_sizes as $size ) { - $avatar_properties[ $size ] = array( - /* translators: %d: avatar image size in pixels */ - 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce-rest-api' ), $size ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'embed', 'view', 'edit' ), - ); - } - $schema['properties']['reviewer_avatar_urls'] = array( - 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - 'properties' => $avatar_properties, - ); - } - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for collections. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - $params['context']['default'] = 'view'; - - $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - ); - $params['before'] = array( - 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'date-time', - ); - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - ); - $params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - ); - $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ); - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( - 'asc', - 'desc', - ), - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'date_gmt', - 'enum' => array( - 'date', - 'date_gmt', - 'id', - 'include', - 'product', - ), - ); - $params['reviewer'] = array( - 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['reviewer_exclude'] = array( - 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['reviewer_email'] = array( - 'default' => null, - 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce-rest-api' ), - 'format' => 'email', - 'type' => 'string', - ); - $params['product'] = array( - 'default' => array(), - 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - ); - $params['status'] = array( - 'default' => 'approved', - 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce-rest-api' ), - 'sanitize_callback' => 'sanitize_key', - 'type' => 'string', - 'enum' => array( - 'all', - 'hold', - 'approved', - 'spam', - 'trash', - ), - ); - - /** - * Filter collection parameters for the reviews controller. - * - * This filter registers the collection parameter, but does not map the - * collection parameter to an internal WP_Comment_Query parameter. Use the - * `wc_rest_review_query` filter to set WP_Comment_Query parameters. - * - * @since 3.5.0 - * @param array $params JSON Schema-formatted collection parameters. - */ - return apply_filters( 'woocommerce_rest_product_review_collection_params', $params ); - } - - /** - * Get the reivew, if the ID is valid. - * - * @since 3.5.0 - * @param int $id Supplied ID. - * @return WP_Comment|WP_Error Comment object if ID is valid, WP_Error otherwise. - */ - protected function get_review( $id ) { - $id = (int) $id; - $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - - if ( 0 >= $id ) { - return $error; - } - - $review = get_comment( $id ); - if ( empty( $review ) ) { - return $error; - } - - if ( ! empty( $review->comment_post_ID ) ) { - $post = get_post( (int) $review->comment_post_ID ); - - if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - } - - return $review; - } - - /** - * Prepends internal property prefix to query parameters to match our response fields. - * - * @since 3.5.0 - * @param string $query_param Query parameter. - * @return string - */ - protected function normalize_query_param( $query_param ) { - $prefix = 'comment_'; - - switch ( $query_param ) { - case 'id': - $normalized = $prefix . 'ID'; - break; - case 'product': - $normalized = $prefix . 'post_ID'; - break; - case 'include': - $normalized = 'comment__in'; - break; - default: - $normalized = $prefix . $query_param; - break; - } - - return $normalized; - } - - /** - * Checks comment_approved to set comment status for single comment output. - * - * @since 3.5.0 - * @param string|int $comment_approved comment status. - * @return string Comment status. - */ - protected function prepare_status_response( $comment_approved ) { - switch ( $comment_approved ) { - case 'hold': - case '0': - $status = 'hold'; - break; - case 'approve': - case '1': - $status = 'approved'; - break; - case 'spam': - case 'trash': - default: - $status = $comment_approved; - break; - } - - return $status; - } - - /** - * Sets the comment_status of a given review object when creating or updating a review. - * - * @since 3.5.0 - * @param string|int $new_status New review status. - * @param int $id Review ID. - * @return bool Whether the status was changed. - */ - protected function handle_status_param( $new_status, $id ) { - $old_status = wp_get_comment_status( $id ); - - if ( $new_status === $old_status ) { - return false; - } - - switch ( $new_status ) { - case 'approved': - case 'approve': - case '1': - $changed = wp_set_comment_status( $id, 'approve' ); - break; - case 'hold': - case '0': - $changed = wp_set_comment_status( $id, 'hold' ); - break; - case 'spam': - $changed = wp_spam_comment( $id ); - break; - case 'unspam': - $changed = wp_unspam_comment( $id ); - break; - case 'trash': - $changed = wp_trash_comment( $id ); - break; - case 'untrash': - $changed = wp_untrash_comment( $id ); - break; - default: - $changed = false; - break; - } - - return $changed; - } -} diff --git a/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php b/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php deleted file mode 100644 index 716e40db7f4..00000000000 --- a/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/variations endpoints. - * - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API variations controller class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Product_Variations_V2_Controller - */ -class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; - - /** - * Prepare a single variation output for response. - * - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response - */ - public function prepare_object_for_response( $object, $request ) { - $data = array( - 'id' => $object->get_id(), - 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), - 'description' => wc_format_content( $object->get_description() ), - 'permalink' => $object->get_permalink(), - 'sku' => $object->get_sku(), - 'price' => $object->get_price(), - 'regular_price' => $object->get_regular_price(), - 'sale_price' => $object->get_sale_price(), - 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), - 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), - 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), - 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), - 'on_sale' => $object->is_on_sale(), - 'status' => $object->get_status(), - 'purchasable' => $object->is_purchasable(), - 'virtual' => $object->is_virtual(), - 'downloadable' => $object->is_downloadable(), - 'downloads' => $this->get_downloads( $object ), - 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, - 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, - 'tax_status' => $object->get_tax_status(), - 'tax_class' => $object->get_tax_class(), - 'manage_stock' => $object->managing_stock(), - 'stock_quantity' => $object->get_stock_quantity(), - 'stock_status' => $object->get_stock_status(), - 'backorders' => $object->get_backorders(), - 'backorders_allowed' => $object->backorders_allowed(), - 'backordered' => $object->is_on_backorder(), - 'weight' => $object->get_weight(), - 'dimensions' => array( - 'length' => $object->get_length(), - 'width' => $object->get_width(), - 'height' => $object->get_height(), - ), - 'shipping_class' => $object->get_shipping_class(), - 'shipping_class_id' => $object->get_shipping_class_id(), - 'image' => $this->get_image( $object ), - 'attributes' => $this->get_attributes( $object ), - 'menu_order' => $object->get_menu_order(), - 'meta_data' => $object->get_meta_data(), - ); - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - $response = rest_ensure_response( $data ); - $response->add_links( $this->prepare_links( $object, $request ) ); - - /** - * Filter the data for a response. - * - * The dynamic portion of the hook name, $this->post_type, - * refers to object type being prepared for the response. - * - * @param WP_REST_Response $response The response object. - * @param WC_Data $object Object data. - * @param WP_REST_Request $request Request object. - */ - return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); - } - - /** - * Prepare a single variation for create or update. - * - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - if ( isset( $request['id'] ) ) { - $variation = wc_get_product( absint( $request['id'] ) ); - } else { - $variation = new WC_Product_Variation(); - } - - $variation->set_parent_id( absint( $request['product_id'] ) ); - - // Status. - if ( isset( $request['status'] ) ) { - $variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); - } - - // SKU. - if ( isset( $request['sku'] ) ) { - $variation->set_sku( wc_clean( $request['sku'] ) ); - } - - // Thumbnail. - if ( isset( $request['image'] ) ) { - if ( is_array( $request['image'] ) ) { - $variation = $this->set_variation_image( $variation, $request['image'] ); - } else { - $variation->set_image_id( '' ); - } - } - - // Virtual variation. - if ( isset( $request['virtual'] ) ) { - $variation->set_virtual( $request['virtual'] ); - } - - // Downloadable variation. - if ( isset( $request['downloadable'] ) ) { - $variation->set_downloadable( $request['downloadable'] ); - } - - // Downloads. - if ( $variation->get_downloadable() ) { - // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); - } - - // Download limit. - if ( isset( $request['download_limit'] ) ) { - $variation->set_download_limit( $request['download_limit'] ); - } - - // Download expiry. - if ( isset( $request['download_expiry'] ) ) { - $variation->set_download_expiry( $request['download_expiry'] ); - } - } - - // Shipping data. - $variation = $this->save_product_shipping_data( $variation, $request ); - - // Stock handling. - if ( isset( $request['manage_stock'] ) ) { - $variation->set_manage_stock( $request['manage_stock'] ); - } - - if ( isset( $request['stock_status'] ) ) { - $variation->set_stock_status( $request['stock_status'] ); - } - - if ( isset( $request['backorders'] ) ) { - $variation->set_backorders( $request['backorders'] ); - } - - if ( $variation->get_manage_stock() ) { - if ( isset( $request['stock_quantity'] ) ) { - $variation->set_stock_quantity( $request['stock_quantity'] ); - } elseif ( isset( $request['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); - $variation->set_stock_quantity( $stock_quantity ); - } - } else { - $variation->set_backorders( 'no' ); - $variation->set_stock_quantity( '' ); - } - - // Regular Price. - if ( isset( $request['regular_price'] ) ) { - $variation->set_regular_price( $request['regular_price'] ); - } - - // Sale Price. - if ( isset( $request['sale_price'] ) ) { - $variation->set_sale_price( $request['sale_price'] ); - } - - if ( isset( $request['date_on_sale_from'] ) ) { - $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); - } - - if ( isset( $request['date_on_sale_from_gmt'] ) ) { - $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); - } - - if ( isset( $request['date_on_sale_to'] ) ) { - $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); - } - - if ( isset( $request['date_on_sale_to_gmt'] ) ) { - $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); - } - - // Tax class. - if ( isset( $request['tax_class'] ) ) { - $variation->set_tax_class( $request['tax_class'] ); - } - - // Description. - if ( isset( $request['description'] ) ) { - $variation->set_description( wp_kses_post( $request['description'] ) ); - } - - // Update taxonomies. - if ( isset( $request['attributes'] ) ) { - $attributes = array(); - $parent = wc_get_product( $variation->get_parent_id() ); - - if ( ! $parent ) { - return new WP_Error( - // Translators: %d parent ID. - "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce-rest-api' ), $variation->get_parent_id() ), array( - 'status' => 404, - ) - ); - } - - $parent_attributes = $parent->get_attributes(); - - foreach ( $request['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = sanitize_title( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { - continue; - } - - $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); - $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; - - if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { - // If dealing with a taxonomy, we need to get the slug from the name posted to the API. - $term = get_term_by( 'name', $attribute_value, $attribute_name ); - - if ( $term && ! is_wp_error( $term ) ) { - $attribute_value = $term->slug; - } else { - $attribute_value = sanitize_title( $attribute_value ); - } - } - - $attributes[ $attribute_key ] = $attribute_value; - } - - $variation->set_attributes( $attributes ); - } - - // Menu order. - if ( $request['menu_order'] ) { - $variation->set_menu_order( $request['menu_order'] ); - } - - // Meta data. - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $variation Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); - } - - /** - * Get the image for a product variation. - * - * @param WC_Product_Variation $variation Variation data. - * @return array - */ - protected function get_image( $variation ) { - if ( ! $variation->get_image_id() ) { - return; - } - - $attachment_id = $variation->get_image_id(); - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - return; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - return; - } - - if ( ! isset( $image ) ) { - return array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - } - - /** - * Set variation image. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product_Variation $variation Variation instance. - * @param array $image Image data. - * @return WC_Product_Variation - */ - protected function set_variation_image( $variation, $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $variation->get_id(), array( $image ) ) ) { - throw new WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $variation->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: attachment ID */ - throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); - } - - $variation->set_image_id( $attachment_id ); - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); - } - - return $variation; - } - - /** - * Get the Variation's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'status' => array( - 'description' => __( 'Variation status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_keys( get_post_statuses() ), - 'context' => array( 'view', 'edit' ), - ), - 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Prepare objects query. - * - * @since 3.0.0 - * @param WP_REST_Request $request Full details about the request. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); - - // Set post_status. - $args['post_status'] = $request['status']; - - // Filter by sku. - if ( ! empty( $request['sku'] ) ) { - $skus = explode( ',', $request['sku'] ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $request['sku']; - } - - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', - ) - ); - } - - // Filter by tax class. - if ( ! empty( $request['tax_class'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_tax_class', - 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', - ) - ); - } - - // Price filter. - if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { - $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. - } - - // Filter product based on stock_status. - if ( ! empty( $request['stock_status'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, - array( - 'key' => '_stock_status', - 'value' => $request['stock_status'], - ) - ); - } - - // Filter by on sale products. - if ( is_bool( $request['on_sale'] ) ) { - $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; - $on_sale_ids = wc_get_product_ids_on_sale(); - - // Use 0 when there's no on sale products to avoid return all products. - $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; - - $args[ $on_sale_key ] += $on_sale_ids; - } - - // Force the post_type argument, since it's not a user input variable. - if ( ! empty( $request['sku'] ) ) { - $args['post_type'] = array( 'product', 'product_variation' ); - } else { - $args['post_type'] = $this->post_type; - } - - $args['post_parent'] = $request['product_id']; - - return $args; - } - - /** - * Get the query params for collections of attachments. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - unset( - $params['in_stock'], - $params['type'], - $params['featured'], - $params['category'], - $params['tag'], - $params['shipping_class'], - $params['attribute'], - $params['attribute_term'] - ); - - $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } -} diff --git a/src/Controllers/Version3/class-wc-rest-products-controller.php b/src/Controllers/Version3/class-wc-rest-products-controller.php deleted file mode 100644 index a6401bf6d91..00000000000 --- a/src/Controllers/Version3/class-wc-rest-products-controller.php +++ /dev/null @@ -1,1341 +0,0 @@ -get_image_id() ) { - $attachment_ids[] = $product->get_image_id(); - } - - // Add gallery images. - $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); - - // Build image data. - foreach ( $attachment_ids as $attachment_id ) { - $attachment_post = get_post( $attachment_id ); - if ( is_null( $attachment_post ) ) { - continue; - } - - $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); - if ( ! is_array( $attachment ) ) { - continue; - } - - $images[] = array( - 'id' => (int) $attachment_id, - 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), - 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), - 'src' => current( $attachment ), - 'name' => get_the_title( $attachment_id ), - 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), - ); - } - - return $images; - } - - /** - * Make extra product orderby features supported by WooCommerce available to the WC API. - * This includes 'price', 'popularity', and 'rating'. - * - * @param WP_REST_Request $request Request data. - * @return array - */ - protected function prepare_objects_query( $request ) { - $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); - - // Set post_status. - $args['post_status'] = $request['status']; - - // Taxonomy query to filter products by type, category, - // tag, shipping class, and attribute. - $tax_query = array(); - - // Map between taxonomy name and arg's key. - $taxonomies = array( - 'product_cat' => 'category', - 'product_tag' => 'tag', - 'product_shipping_class' => 'shipping_class', - ); - - // Set tax_query for each passed arg. - foreach ( $taxonomies as $taxonomy => $key ) { - if ( ! empty( $request[ $key ] ) ) { - $tax_query[] = array( - 'taxonomy' => $taxonomy, - 'field' => 'term_id', - 'terms' => $request[ $key ], - ); - } - } - - // Filter product type by slug. - if ( ! empty( $request['type'] ) ) { - $tax_query[] = array( - 'taxonomy' => 'product_type', - 'field' => 'slug', - 'terms' => $request['type'], - ); - } - - // Filter by attribute and term. - if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { - if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { - $tax_query[] = array( - 'taxonomy' => $request['attribute'], - 'field' => 'term_id', - 'terms' => $request['attribute_term'], - ); - } - } - - // Build tax_query if taxonomies are set. - if ( ! empty( $tax_query ) ) { - if ( ! empty( $args['tax_query'] ) ) { - $args['tax_query'] = array_merge( $tax_query, $args['tax_query'] ); // WPCS: slow query ok. - } else { - $args['tax_query'] = $tax_query; // WPCS: slow query ok. - } - } - - // Filter featured. - if ( is_bool( $request['featured'] ) ) { - $args['tax_query'][] = array( - 'taxonomy' => 'product_visibility', - 'field' => 'name', - 'terms' => 'featured', - 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', - ); - } - - // Filter by sku. - if ( ! empty( $request['sku'] ) ) { - $skus = explode( ',', $request['sku'] ); - // Include the current string as a SKU too. - if ( 1 < count( $skus ) ) { - $skus[] = $request['sku']; - } - - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, array( - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', - ) - ); - } - - // Filter by tax class. - if ( ! empty( $request['tax_class'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, array( - 'key' => '_tax_class', - 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', - ) - ); - } - - // Price filter. - if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { - $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. - } - - // Filter product by stock_status. - if ( ! empty( $request['stock_status'] ) ) { - $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. - $args, array( - 'key' => '_stock_status', - 'value' => $request['stock_status'], - ) - ); - } - - // Filter by on sale products. - if ( is_bool( $request['on_sale'] ) ) { - $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; - $on_sale_ids = wc_get_product_ids_on_sale(); - - // Use 0 when there's no on sale products to avoid return all products. - $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; - - $args[ $on_sale_key ] += $on_sale_ids; - } - - // Force the post_type argument, since it's not a user input variable. - if ( ! empty( $request['sku'] ) ) { - $args['post_type'] = array( 'product', 'product_variation' ); - } else { - $args['post_type'] = $this->post_type; - } - - $orderby = $request->get_param( 'orderby' ); - $order = $request->get_param( 'order' ); - - $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); - $args['orderby'] = $ordering_args['orderby']; - $args['order'] = $ordering_args['order']; - if ( $ordering_args['meta_key'] ) { - $args['meta_key'] = $ordering_args['meta_key']; // WPCS: slow query ok. - } - - return $args; - } - - /** - * Set product images. - * - * @throws WC_REST_Exception REST API exceptions. - * @param WC_Product $product Product instance. - * @param array $images Images data. - * @return WC_Product - */ - protected function set_product_images( $product, $images ) { - $images = is_array( $images ) ? array_filter( $images ) : array(); - - if ( ! empty( $images ) ) { - $gallery = array(); - - foreach ( $images as $index => $image ) { - $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; - - if ( 0 === $attachment_id && isset( $image['src'] ) ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { - throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); - } else { - continue; - } - } - - $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); - } - - if ( ! wp_attachment_is_image( $attachment_id ) ) { - /* translators: %s: image ID */ - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); - } - - $featured_image = $product->get_image_id(); - - if ( 0 === $index ) { - $product->set_image_id( $attachment_id ); - } else { - $gallery[] = $attachment_id; - } - - // Set the image alt if present. - if ( ! empty( $image['alt'] ) ) { - update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); - } - - // Set the image name if present. - if ( ! empty( $image['name'] ) ) { - wp_update_post( - array( - 'ID' => $attachment_id, - 'post_title' => $image['name'], - ) - ); - } - } - - $product->set_gallery_image_ids( $gallery ); - } else { - $product->set_image_id( '' ); - $product->set_gallery_image_ids( array() ); - } - - return $product; - } - - /** - * Prepare a single product for create or update. - * - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - * @return WP_Error|WC_Data - */ - protected function prepare_object_for_database( $request, $creating = false ) { - $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; - - // Type is the most important part here because we need to be using the correct class and methods. - if ( isset( $request['type'] ) ) { - $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); - - if ( ! class_exists( $classname ) ) { - $classname = 'WC_Product_Simple'; - } - - $product = new $classname( $id ); - } elseif ( isset( $request['id'] ) ) { - $product = wc_get_product( $id ); - } else { - $product = new WC_Product_Simple(); - } - - if ( 'variation' === $product->get_type() ) { - return new WP_Error( - "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( - 'status' => 404, - ) - ); - } - - // Post title. - if ( isset( $request['name'] ) ) { - $product->set_name( wp_filter_post_kses( $request['name'] ) ); - } - - // Post content. - if ( isset( $request['description'] ) ) { - $product->set_description( wp_filter_post_kses( $request['description'] ) ); - } - - // Post excerpt. - if ( isset( $request['short_description'] ) ) { - $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); - } - - // Post status. - if ( isset( $request['status'] ) ) { - $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); - } - - // Post slug. - if ( isset( $request['slug'] ) ) { - $product->set_slug( $request['slug'] ); - } - - // Menu order. - if ( isset( $request['menu_order'] ) ) { - $product->set_menu_order( $request['menu_order'] ); - } - - // Comment status. - if ( isset( $request['reviews_allowed'] ) ) { - $product->set_reviews_allowed( $request['reviews_allowed'] ); - } - - // Virtual. - if ( isset( $request['virtual'] ) ) { - $product->set_virtual( $request['virtual'] ); - } - - // Tax status. - if ( isset( $request['tax_status'] ) ) { - $product->set_tax_status( $request['tax_status'] ); - } - - // Tax Class. - if ( isset( $request['tax_class'] ) ) { - $product->set_tax_class( $request['tax_class'] ); - } - - // Catalog Visibility. - if ( isset( $request['catalog_visibility'] ) ) { - $product->set_catalog_visibility( $request['catalog_visibility'] ); - } - - // Purchase Note. - if ( isset( $request['purchase_note'] ) ) { - $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); - } - - // Featured Product. - if ( isset( $request['featured'] ) ) { - $product->set_featured( $request['featured'] ); - } - - // Shipping data. - $product = $this->save_product_shipping_data( $product, $request ); - - // SKU. - if ( isset( $request['sku'] ) ) { - $product->set_sku( wc_clean( $request['sku'] ) ); - } - - // Attributes. - if ( isset( $request['attributes'] ) ) { - $attributes = array(); - - foreach ( $request['attributes'] as $attribute ) { - $attribute_id = 0; - $attribute_name = ''; - - // Check ID for global attributes or name for product attributes. - if ( ! empty( $attribute['id'] ) ) { - $attribute_id = absint( $attribute['id'] ); - $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); - } elseif ( ! empty( $attribute['name'] ) ) { - $attribute_name = wc_clean( $attribute['name'] ); - } - - if ( ! $attribute_id && ! $attribute_name ) { - continue; - } - - if ( $attribute_id ) { - - if ( isset( $attribute['options'] ) ) { - $options = $attribute['options']; - - if ( ! is_array( $attribute['options'] ) ) { - // Text based attributes - Posted values are term names. - $options = explode( WC_DELIMITER, $options ); - } - - $values = array_map( 'wc_sanitize_term_text_based', $options ); - $values = array_filter( $values, 'strlen' ); - } else { - $values = array(); - } - - if ( ! empty( $values ) ) { - // Add attribute to array, but don't set values. - $attribute_object = new WC_Product_Attribute(); - $attribute_object->set_id( $attribute_id ); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } elseif ( isset( $attribute['options'] ) ) { - // Custom attribute - Add attribute to array and set the values. - if ( is_array( $attribute['options'] ) ) { - $values = $attribute['options']; - } else { - $values = explode( WC_DELIMITER, $attribute['options'] ); - } - $attribute_object = new WC_Product_Attribute(); - $attribute_object->set_name( $attribute_name ); - $attribute_object->set_options( $values ); - $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); - $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); - $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); - $attributes[] = $attribute_object; - } - } - $product->set_attributes( $attributes ); - } - - // Sales and prices. - if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { - $product->set_regular_price( '' ); - $product->set_sale_price( '' ); - $product->set_date_on_sale_to( '' ); - $product->set_date_on_sale_from( '' ); - $product->set_price( '' ); - } else { - // Regular Price. - if ( isset( $request['regular_price'] ) ) { - $product->set_regular_price( $request['regular_price'] ); - } - - // Sale Price. - if ( isset( $request['sale_price'] ) ) { - $product->set_sale_price( $request['sale_price'] ); - } - - if ( isset( $request['date_on_sale_from'] ) ) { - $product->set_date_on_sale_from( $request['date_on_sale_from'] ); - } - - if ( isset( $request['date_on_sale_from_gmt'] ) ) { - $product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); - } - - if ( isset( $request['date_on_sale_to'] ) ) { - $product->set_date_on_sale_to( $request['date_on_sale_to'] ); - } - - if ( isset( $request['date_on_sale_to_gmt'] ) ) { - $product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); - } - } - - // Product parent ID. - if ( isset( $request['parent_id'] ) ) { - $product->set_parent_id( $request['parent_id'] ); - } - - // Sold individually. - if ( isset( $request['sold_individually'] ) ) { - $product->set_sold_individually( $request['sold_individually'] ); - } - - // Stock status; stock_status has priority over in_stock. - if ( isset( $request['stock_status'] ) ) { - $stock_status = $request['stock_status']; - } else { - $stock_status = $product->get_stock_status(); - } - - // Stock data. - if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { - // Manage stock. - if ( isset( $request['manage_stock'] ) ) { - $product->set_manage_stock( $request['manage_stock'] ); - } - - // Backorders. - if ( isset( $request['backorders'] ) ) { - $product->set_backorders( $request['backorders'] ); - } - - if ( $product->is_type( 'grouped' ) ) { - $product->set_manage_stock( 'no' ); - $product->set_backorders( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( $stock_status ); - } elseif ( $product->is_type( 'external' ) ) { - $product->set_manage_stock( 'no' ); - $product->set_backorders( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( 'instock' ); - } elseif ( $product->get_manage_stock() ) { - // Stock status is always determined by children so sync later. - if ( ! $product->is_type( 'variable' ) ) { - $product->set_stock_status( $stock_status ); - } - - // Stock quantity. - if ( isset( $request['stock_quantity'] ) ) { - $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); - } elseif ( isset( $request['inventory_delta'] ) ) { - $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); - $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); - $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); - } - } else { - // Don't manage stock. - $product->set_manage_stock( 'no' ); - $product->set_stock_quantity( '' ); - $product->set_stock_status( $stock_status ); - } - } elseif ( ! $product->is_type( 'variable' ) ) { - $product->set_stock_status( $stock_status ); - } - - // Upsells. - if ( isset( $request['upsell_ids'] ) ) { - $upsells = array(); - $ids = $request['upsell_ids']; - - if ( ! empty( $ids ) ) { - foreach ( $ids as $id ) { - if ( $id && $id > 0 ) { - $upsells[] = $id; - } - } - } - - $product->set_upsell_ids( $upsells ); - } - - // Cross sells. - if ( isset( $request['cross_sell_ids'] ) ) { - $crosssells = array(); - $ids = $request['cross_sell_ids']; - - if ( ! empty( $ids ) ) { - foreach ( $ids as $id ) { - if ( $id && $id > 0 ) { - $crosssells[] = $id; - } - } - } - - $product->set_cross_sell_ids( $crosssells ); - } - - // Product categories. - if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { - $product = $this->save_taxonomy_terms( $product, $request['categories'] ); - } - - // Product tags. - if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { - $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); - } - - // Downloadable. - if ( isset( $request['downloadable'] ) ) { - $product->set_downloadable( $request['downloadable'] ); - } - - // Downloadable options. - if ( $product->get_downloadable() ) { - - // Downloadable files. - if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { - $product = $this->save_downloadable_files( $product, $request['downloads'] ); - } - - // Download limit. - if ( isset( $request['download_limit'] ) ) { - $product->set_download_limit( $request['download_limit'] ); - } - - // Download expiry. - if ( isset( $request['download_expiry'] ) ) { - $product->set_download_expiry( $request['download_expiry'] ); - } - } - - // Product url and button text for external products. - if ( $product->is_type( 'external' ) ) { - if ( isset( $request['external_url'] ) ) { - $product->set_product_url( $request['external_url'] ); - } - - if ( isset( $request['button_text'] ) ) { - $product->set_button_text( $request['button_text'] ); - } - } - - // Save default attributes for variable products. - if ( $product->is_type( 'variable' ) ) { - $product = $this->save_default_attributes( $product, $request ); - } - - // Set children for a grouped product. - if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { - $product->set_children( $request['grouped_products'] ); - } - - // Check for featured/gallery images, upload it and set it. - if ( isset( $request['images'] ) ) { - $product = $this->set_product_images( $product, $request['images'] ); - } - - // Allow set meta_data. - if ( is_array( $request['meta_data'] ) ) { - foreach ( $request['meta_data'] as $meta ) { - $product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); - } - } - - if ( ! empty( $request['date_created'] ) ) { - $date = rest_parse_date( $request['date_created'] ); - - if ( $date ) { - $product->set_date_created( $date ); - } - } - - if ( ! empty( $request['date_created_gmt'] ) ) { - $date = rest_parse_date( $request['date_created_gmt'], true ); - - if ( $date ) { - $product->set_date_created( $date ); - } - } - - /** - * Filters an object before it is inserted via the REST API. - * - * The dynamic portion of the hook name, `$this->post_type`, - * refers to the object type slug. - * - * @param WC_Data $product Object object. - * @param WP_REST_Request $request Request object. - * @param bool $creating If is creating a new object. - */ - return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); - } - - /** - * Get the Product's schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $weight_unit = get_option( 'woocommerce_weight_unit' ); - $dimension_unit = get_option( 'woocommerce_dimension_unit' ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => $this->post_type, - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Product type.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'simple', - 'enum' => array_keys( wc_get_product_types() ), - 'context' => array( 'view', 'edit' ), - ), - 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'publish', - 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), - 'context' => array( 'view', 'edit' ), - ), - 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'visible', - 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'Product description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - ), - 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => -1, - 'context' => array( 'view', 'edit' ), - ), - 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'taxable', - 'enum' => array( 'taxable', 'shipping', 'none' ), - 'context' => array( 'view', 'edit' ), - ), - 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'instock', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'default' => 'no', - 'enum' => array( 'no', 'notify', 'yes' ), - 'context' => array( 'view', 'edit' ), - ), - 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'weight' => array( - /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'length' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'width' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'height' => array( - /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => true, - 'context' => array( 'view', 'edit' ), - ), - 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ), - ), - 'images' => array( - 'description' => __( 'List of images.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), - 'type' => 'date-time', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'view', 'edit' ), - ), - 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'integer', - ), - 'readonly' => true, - ), - 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - ), - 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), - 'type' => 'array', - 'context' => array( 'view', 'edit' ), - 'items' => array( - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - ), - ), - ), - ), - ); - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Add new options for 'orderby' to the collection params. - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); - - unset( $params['in_stock'] ); - $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'enum' => array_keys( wc_get_product_stock_status_options() ), - 'sanitize_callback' => 'sanitize_text_field', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - - /** - * Get product data. - * - * @param WC_Product $product Product instance. - * @param string $context Request context. - * Options: 'view' and 'edit'. - * @return array - */ - protected function get_product_data( $product, $context = 'view' ) { - $data = parent::get_product_data( $product, $context ); - - // Replace in_stock with stock_status. - $pos = array_search( 'in_stock', array_keys( $data ), true ); - $array_section_1 = array_slice( $data, 0, $pos, true ); - $array_section_2 = array_slice( $data, $pos + 1, null, true ); - - return $array_section_1 + array( 'stock_status' => $product->get_stock_status( $context ) ) + $array_section_2; - } -} diff --git a/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php deleted file mode 100644 index 85d4ae34795..00000000000 --- a/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php +++ /dev/null @@ -1,143 +0,0 @@ - $name ) { - $results = $wpdb->get_results( - $wpdb->prepare( " - SELECT count(meta_id) AS total - FROM $wpdb->postmeta - WHERE meta_key = 'discount_type' - AND meta_value = %s - ", $slug ) - ); - - $total = isset( $results[0] ) ? (int) $results[0]->total : 0; - - $data[] = array( - 'slug' => $slug, - 'name' => $name, - 'total' => $total, - ); - } - - set_transient( 'rest_api_coupons_type_count', $data, YEAR_IN_SECONDS ); - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_count', $response, $report, $request ); - } - - /** - * 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_coupon_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Coupon type name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of coupons.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php deleted file mode 100644 index 38867bd7135..00000000000 --- a/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php +++ /dev/null @@ -1,154 +0,0 @@ - $total ) { - if ( in_array( $role, array( 'administrator', 'shop_manager' ), true ) ) { - continue; - } - - $total_customers += (int) $total; - } - - $customers_query = new WP_User_Query( - array( - 'role__not_in' => array( 'administrator', 'shop_manager' ), - 'number' => 0, - 'fields' => 'ID', - 'count_total' => true, - 'meta_query' => array( // WPCS: slow query ok. - array( - 'key' => 'paying_customer', - 'value' => 1, - 'compare' => '=', - ), - ), - ) - ); - - $total_paying = (int) $customers_query->get_total(); - - $data = array( - array( - 'slug' => 'paying', - 'name' => __( 'Paying customer', 'woocommerce-rest-api' ), - 'total' => $total_paying, - ), - array( - 'slug' => 'non_paying', - 'name' => __( 'Non-paying customer', 'woocommerce-rest-api' ), - 'total' => $total_customers - $total_paying, - ), - ); - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_count', $response, $report, $request ); - } - - /** - * 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_customer_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Customer type name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of customers.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php deleted file mode 100644 index 4c7c9289806..00000000000 --- a/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php +++ /dev/null @@ -1,127 +0,0 @@ - $name ) { - if ( ! isset( $totals->$slug ) ) { - continue; - } - - $data[] = array( - 'slug' => str_replace( 'wc-', '', $slug ), - 'name' => $name, - 'total' => (int) $totals->$slug, - ); - } - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_count', $response, $report, $request ); - } - - /** - * 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_order_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Order status name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of orders.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php deleted file mode 100644 index d855b6298b9..00000000000 --- a/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php +++ /dev/null @@ -1,133 +0,0 @@ - 'product_type', - 'hide_empty' => false, - ) - ); - $data = array(); - - foreach ( $terms as $product_type ) { - if ( ! isset( $types[ $product_type->name ] ) ) { - continue; - } - - $data[] = array( - 'slug' => $product_type->name, - 'name' => $types[ $product_type->name ], - 'total' => (int) $product_type->count, - ); - } - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_count', $response, $report, $request ); - } - - /** - * 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_product_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Product type name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of products.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php b/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php deleted file mode 100644 index d585d586d27..00000000000 --- a/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php +++ /dev/null @@ -1,132 +0,0 @@ - true, - 'post_type' => 'product', - 'meta_key' => 'rating', // WPCS: slow query ok. - 'meta_value' => '', // WPCS: slow query ok. - ); - - for ( $i = 1; $i <= 5; $i++ ) { - $query_data['meta_value'] = $i; - - $data[] = array( - 'slug' => 'rated_' . $i . '_out_of_5', - /* translators: %s: average rating */ - 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce-rest-api' ), $i ), - 'total' => (int) get_comments( $query_data ), - ); - } - - return $data; - } - - /** - * Prepare a report object for serialization. - * - * @param stdClass $report Report data. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. - */ - public function prepare_item_for_response( $report, $request ) { - $data = array( - 'slug' => $report->slug, - 'name' => $report->name, - 'total' => $report->total, - ); - - $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_reviews_count', $response, $report, $request ); - } - - /** - * 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_review_total', - 'type' => 'object', - 'properties' => array( - 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Review type name.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - 'total' => array( - 'description' => __( 'Amount of reviews.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-report-sales-controller.php b/src/Controllers/Version3/class-wc-rest-report-sales-controller.php deleted file mode 100644 index bde4bd0ae51..00000000000 --- a/src/Controllers/Version3/class-wc-rest-report-sales-controller.php +++ /dev/null @@ -1,27 +0,0 @@ - 'orders/totals', - 'description' => __( 'Orders totals.', 'woocommerce-rest-api' ), - ); - $reports[] = array( - 'slug' => 'products/totals', - 'description' => __( 'Products totals.', 'woocommerce-rest-api' ), - ); - $reports[] = array( - 'slug' => 'customers/totals', - 'description' => __( 'Customers totals.', 'woocommerce-rest-api' ), - ); - $reports[] = array( - 'slug' => 'coupons/totals', - 'description' => __( 'Coupons totals.', 'woocommerce-rest-api' ), - ); - $reports[] = array( - 'slug' => 'reviews/totals', - 'description' => __( 'Reviews totals.', 'woocommerce-rest-api' ), - ); - $reports[] = array( - 'slug' => 'categories/totals', - 'description' => __( 'Categories totals.', 'woocommerce-rest-api' ), - ); - $reports[] = array( - 'slug' => 'tags/totals', - 'description' => __( 'Tags totals.', 'woocommerce-rest-api' ), - ); - $reports[] = array( - 'slug' => 'attributes/totals', - 'description' => __( 'Attributes totals.', 'woocommerce-rest-api' ), - ); - - return $reports; - } -} diff --git a/src/Controllers/Version3/class-wc-rest-setting-options-controller.php b/src/Controllers/Version3/class-wc-rest-setting-options-controller.php deleted file mode 100644 index b7255694912..00000000000 --- a/src/Controllers/Version3/class-wc-rest-setting-options-controller.php +++ /dev/null @@ -1,250 +0,0 @@ - 404 ) ); - } - - $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores - - if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - $filtered_settings = array(); - foreach ( $settings as $setting ) { - $option_key = $setting['option_key']; - $setting = $this->filter_setting( $setting ); - $default = isset( $setting['default'] ) ? $setting['default'] : ''; - // Get the option value. - if ( is_array( $option_key ) ) { - $option = get_option( $option_key[0] ); - $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; - } else { - $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); - $setting['value'] = $admin_setting_value; - } - - if ( 'multi_select_countries' === $setting['type'] ) { - $setting['options'] = WC()->countries->get_countries(); - $setting['type'] = 'multiselect'; - } elseif ( 'single_select_country' === $setting['type'] ) { - $setting['type'] = 'select'; - $setting['options'] = $this->get_countries_and_states(); - } elseif ( 'single_select_page' === $setting['type'] ) { - $pages = get_pages( - array( - 'sort_column' => 'menu_order', - 'sort_order' => 'ASC', - 'hierarchical' => 0, - ) - ); - $options = array(); - foreach ( $pages as $page ) { - $options[ $page->ID ] = ! empty( $page->post_title ) ? $page->post_title : '#' . $page->ID; - } - $setting['type'] = 'select'; - $setting['options'] = $options; - } - - $filtered_settings[] = $setting; - } - - return $filtered_settings; - } - - /** - * Returns a list of countries and states for use in the base location setting. - * - * @since 3.0.7 - * @return array Array of states and countries. - */ - private function get_countries_and_states() { - $countries = WC()->countries->get_countries(); - if ( ! $countries ) { - return array(); - } - $output = array(); - foreach ( $countries as $key => $value ) { - $states = WC()->countries->get_states( $key ); - - if ( $states ) { - foreach ( $states as $state_key => $state_value ) { - $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; - } - } else { - $output[ $key ] = $value; - } - } - return $output; - } - - /** - * Get the settings schema, conforming to JSON Schema. - * - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'setting', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'group_id' => array( - 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - ), - 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'mixed', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - 'context' => array( 'view', 'edit' ), - 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), - 'readonly' => true, - ), - 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce-rest-api' ), - 'type' => 'object', - 'context' => array( 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-settings-controller.php b/src/Controllers/Version3/class-wc-rest-settings-controller.php deleted file mode 100644 index 0762c090fd4..00000000000 --- a/src/Controllers/Version3/class-wc-rest-settings-controller.php +++ /dev/null @@ -1,112 +0,0 @@ -namespace, '/' . $this->rest_base . '/batch', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), - ), - 'schema' => array( $this, 'get_public_batch_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 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-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Update a setting. - * - * @param WP_REST_Request $request Request data. - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $options_controller = new WC_REST_Setting_Options_Controller(); - $response = $options_controller->update_item( $request ); - - return $response; - } - - /** - * Get the groups schema, conforming to JSON Schema. - * - * @since 3.0.0 - * @return array - */ - public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'setting_group', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } -} diff --git a/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php deleted file mode 100644 index 297943ae544..00000000000 --- a/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/locations endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Shipping Zone Locations class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Shipping_Zone_Locations_V2_Controller - */ -class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zone_Locations_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; -} diff --git a/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php deleted file mode 100644 index efb56f49afd..00000000000 --- a/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php +++ /dev/null @@ -1,27 +0,0 @@ -/methods endpoint. - * - * @package Automattic/WooCommerce/RestApi - * @since 3.0.0 - */ - -defined( 'ABSPATH' ) || exit; - -/** - * REST API Shipping Zone Methods class. - * - * @package Automattic/WooCommerce/RestApi - * @extends WC_REST_Shipping_Zone_Methods_V2_Controller - */ -class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zone_Methods_V2_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v3'; -} diff --git a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php deleted file mode 100644 index 250269663d0..00000000000 --- a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php +++ /dev/null @@ -1,125 +0,0 @@ - 404 ) ); - } - - return $zone; - } - - /** - * Check whether a given request has permission to read Shipping Zones. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create Shipping Zones. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check whether a given request has permission to edit Shipping Zones. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_items_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check whether a given request has permission to delete Shipping Zones. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function delete_items_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - -} diff --git a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php b/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php deleted file mode 100644 index 881d18dc3c1..00000000000 --- a/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php +++ /dev/null @@ -1,27 +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(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array_merge( - $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - array( - 'name' => array( - 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), - 'required' => true, - ), - ) - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)', - array( - 'args' => array( - 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), - 'type' => 'integer', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'default' => false, - 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'batch_items_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_batch_schema' ), - ) - ); - } - - /** - * Check if a given request has access to read the terms. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'read' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to create a term. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function create_item_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'create' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to read a term. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_item_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'read' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to update a term. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function update_item_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'edit' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access to delete a term. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function delete_item_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'delete' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check if a given request has access batch create, update and delete items. - * - * @param WP_REST_Request $request Full details about the request. - * @return boolean|WP_Error - */ - public function batch_items_permissions_check( $request ) { - $permissions = $this->check_permissions( $request, 'batch' ); - if ( is_wp_error( $permissions ) ) { - return $permissions; - } - - if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Check permissions. - * - * @param WP_REST_Request $request Full details about the request. - * @param string $context Request context. - * @return bool|WP_Error - */ - protected function check_permissions( $request, $context = 'read' ) { - // Get taxonomy. - $taxonomy = $this->get_taxonomy( $request ); - if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - // Check permissions for a single term. - $id = intval( $request['id'] ); - if ( $id ) { - $term = get_term( $id, $taxonomy ); - - if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { - return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); - } - - return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id ); - } - - return wc_rest_check_product_term_permissions( $taxonomy, $context ); - } - - /** - * Get terms associated with a taxonomy. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error - */ - public function get_items( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $prepared_args = array( - 'exclude' => $request['exclude'], - 'include' => $request['include'], - 'order' => $request['order'], - 'orderby' => $request['orderby'], - 'product' => $request['product'], - 'hide_empty' => $request['hide_empty'], - 'number' => $request['per_page'], - 'search' => $request['search'], - 'slug' => $request['slug'], - ); - - if ( ! empty( $request['offset'] ) ) { - $prepared_args['offset'] = $request['offset']; - } else { - $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; - } - - $taxonomy_obj = get_taxonomy( $taxonomy ); - - if ( $taxonomy_obj->hierarchical && isset( $request['parent'] ) ) { - if ( 0 === $request['parent'] ) { - // Only query top-level terms. - $prepared_args['parent'] = 0; - } else { - if ( $request['parent'] ) { - $prepared_args['parent'] = $request['parent']; - } - } - } - - /** - * Filter the query arguments, before passing them to `get_terms()`. - * - * Enables adding extra arguments or setting defaults for a terms - * collection request. - * - * @see https://developer.wordpress.org/reference/functions/get_terms/ - * - * @param array $prepared_args Array of arguments to be - * passed to get_terms. - * @param WP_REST_Request $request The current request. - */ - $prepared_args = apply_filters( "woocommerce_rest_{$taxonomy}_query", $prepared_args, $request ); - - if ( ! empty( $prepared_args['product'] ) ) { - $query_result = $this->get_terms_for_product( $prepared_args, $request ); - $total_terms = $this->total_terms; - } else { - $query_result = get_terms( $taxonomy, $prepared_args ); - - $count_args = $prepared_args; - unset( $count_args['number'] ); - unset( $count_args['offset'] ); - $total_terms = wp_count_terms( $taxonomy, $count_args ); - - // Ensure we don't return results when offset is out of bounds. - // See https://core.trac.wordpress.org/ticket/35935. - if ( $prepared_args['offset'] && $prepared_args['offset'] >= $total_terms ) { - $query_result = array(); - } - - // wp_count_terms can return a falsy value when the term has no children. - if ( ! $total_terms ) { - $total_terms = 0; - } - } - $response = array(); - foreach ( $query_result as $term ) { - $data = $this->prepare_item_for_response( $term, $request ); - $response[] = $this->prepare_response_for_collection( $data ); - } - - $response = rest_ensure_response( $response ); - - // Store pagination values for headers then unset for count query. - $per_page = (int) $prepared_args['number']; - $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); - - $response->header( 'X-WP-Total', (int) $total_terms ); - $max_pages = ceil( $total_terms / $per_page ); - $response->header( 'X-WP-TotalPages', (int) $max_pages ); - - $base = str_replace( '(?P[\d]+)', $request['attribute_id'], $this->rest_base ); - $base = add_query_arg( $request->get_query_params(), rest_url( '/' . $this->namespace . '/' . $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; - } - - /** - * Create a single term for a taxonomy. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function create_item( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $name = $request['name']; - $args = array(); - $schema = $this->get_item_schema(); - - if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { - $args['description'] = $request['description']; - } - if ( isset( $request['slug'] ) ) { - $args['slug'] = $request['slug']; - } - if ( isset( $request['parent'] ) ) { - if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - $args['parent'] = $request['parent']; - } - - $term = wp_insert_term( $name, $taxonomy, $args ); - if ( is_wp_error( $term ) ) { - $error_data = array( 'status' => 400 ); - - // If we're going to inform the client that the term exists, - // give them the identifier they can actually use. - $term_id = $term->get_error_data( 'term_exists' ); - if ( $term_id ) { - $error_data['resource_id'] = $term_id; - } - - return new WP_Error( $term->get_error_code(), $term->get_error_message(), $error_data ); - } - - $term = get_term( $term['term_id'], $taxonomy ); - - $this->update_additional_fields_for_object( $term, $request ); - - // Add term data. - $meta_fields = $this->update_term_meta_fields( $term, $request ); - if ( is_wp_error( $meta_fields ) ) { - wp_delete_term( $term->term_id, $taxonomy ); - - return $meta_fields; - } - - /** - * Fires after a single term is created or updated via the REST API. - * - * @param WP_Term $term Inserted Term object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating term, false when updating. - */ - do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, true ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $term, $request ); - $response = rest_ensure_response( $response ); - $response->set_status( 201 ); - - $base = '/' . $this->namespace . '/' . $this->rest_base; - if ( ! empty( $request['attribute_id'] ) ) { - $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); - } - - $response->header( 'Location', rest_url( $base . '/' . $term->term_id ) ); - - return $response; - } - - /** - * Get a single term from a taxonomy. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function get_item( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $term = get_term( (int) $request['id'], $taxonomy ); - - if ( is_wp_error( $term ) ) { - return $term; - } - - $response = $this->prepare_item_for_response( $term, $request ); - - return rest_ensure_response( $response ); - } - - /** - * Update a single term from a taxonomy. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Request|WP_Error - */ - public function update_item( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $term = get_term( (int) $request['id'], $taxonomy ); - $schema = $this->get_item_schema(); - $prepared_args = array(); - - if ( isset( $request['name'] ) ) { - $prepared_args['name'] = $request['name']; - } - if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { - $prepared_args['description'] = $request['description']; - } - if ( isset( $request['slug'] ) ) { - $prepared_args['slug'] = $request['slug']; - } - if ( isset( $request['parent'] ) ) { - if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); - } - $prepared_args['parent'] = $request['parent']; - } - - // Only update the term if we haz something to update. - if ( ! empty( $prepared_args ) ) { - $update = wp_update_term( $term->term_id, $term->taxonomy, $prepared_args ); - if ( is_wp_error( $update ) ) { - return $update; - } - } - - $term = get_term( (int) $request['id'], $taxonomy ); - - $this->update_additional_fields_for_object( $term, $request ); - - // Update term data. - $meta_fields = $this->update_term_meta_fields( $term, $request ); - if ( is_wp_error( $meta_fields ) ) { - return $meta_fields; - } - - /** - * Fires after a single term is created or updated via the REST API. - * - * @param WP_Term $term Inserted Term object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating term, false when updating. - */ - do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, false ); - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $term, $request ); - return rest_ensure_response( $response ); - } - - /** - * Delete a single term from a taxonomy. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error - */ - public function delete_item( $request ) { - $taxonomy = $this->get_taxonomy( $request ); - $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - - // We don't support trashing for this type, error out. - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); - } - - $term = get_term( (int) $request['id'], $taxonomy ); - // Get default category id. - $default_category_id = absint( get_option( 'default_product_cat', 0 ) ); - - // Prevent deleting the default product category. - if ( $default_category_id === (int) $request['id'] ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $term, $request ); - - $retval = wp_delete_term( $term->term_id, $term->taxonomy ); - if ( ! $retval ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); - } - - /** - * Fires after a single term is deleted via the REST API. - * - * @param WP_Term $term The deleted term. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. - */ - do_action( "woocommerce_rest_delete_{$taxonomy}", $term, $response, $request ); - - return $response; - } - - /** - * Prepare links for the request. - * - * @param object $term Term object. - * @param WP_REST_Request $request Full details about the request. - * @return array Links for the given term. - */ - protected function prepare_links( $term, $request ) { - $base = '/' . $this->namespace . '/' . $this->rest_base; - - if ( ! empty( $request['attribute_id'] ) ) { - $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); - } - - $links = array( - 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $term->term_id ), - ), - 'collection' => array( - 'href' => rest_url( $base ), - ), - ); - - if ( $term->parent ) { - $parent_term = get_term( (int) $term->parent, $term->taxonomy ); - if ( $parent_term ) { - $links['up'] = array( - 'href' => rest_url( trailingslashit( $base ) . $parent_term->term_id ), - ); - } - } - - return $links; - } - - /** - * Update term meta fields. - * - * @param WP_Term $term Term object. - * @param WP_REST_Request $request Full details about the request. - * @return bool|WP_Error - */ - protected function update_term_meta_fields( $term, $request ) { - return true; - } - - /** - * Get the terms attached to a product. - * - * This is an alternative to `get_terms()` that uses `get_the_terms()` - * instead, which hits the object cache. There are a few things not - * supported, notably `include`, `exclude`. In `self::get_items()` these - * are instead treated as a full query. - * - * @param array $prepared_args Arguments for `get_terms()`. - * @param WP_REST_Request $request Full details about the request. - * @return array List of term objects. (Total count in `$this->total_terms`). - */ - protected function get_terms_for_product( $prepared_args, $request ) { - $taxonomy = $this->get_taxonomy( $request ); - - $query_result = get_the_terms( $prepared_args['product'], $taxonomy ); - if ( empty( $query_result ) ) { - $this->total_terms = 0; - return array(); - } - - // get_items() verifies that we don't have `include` set, and default. - // ordering is by `name`. - if ( ! in_array( $prepared_args['orderby'], array( 'name', 'none', 'include' ), true ) ) { - switch ( $prepared_args['orderby'] ) { - case 'id': - $this->sort_column = 'term_id'; - break; - case 'slug': - case 'term_group': - case 'description': - case 'count': - $this->sort_column = $prepared_args['orderby']; - break; - } - usort( $query_result, array( $this, 'compare_terms' ) ); - } - if ( strtolower( $prepared_args['order'] ) !== 'asc' ) { - $query_result = array_reverse( $query_result ); - } - - // Pagination. - $this->total_terms = count( $query_result ); - $query_result = array_slice( $query_result, $prepared_args['offset'], $prepared_args['number'] ); - - return $query_result; - } - - /** - * Comparison function for sorting terms by a column. - * - * Uses `$this->sort_column` to determine field to sort by. - * - * @param stdClass $left Term object. - * @param stdClass $right Term object. - * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left. - */ - protected function compare_terms( $left, $right ) { - $col = $this->sort_column; - $left_val = $left->$col; - $right_val = $right->$col; - - if ( is_int( $left_val ) && is_int( $right_val ) ) { - return $left_val - $right_val; - } - - return strcmp( $left_val, $right_val ); - } - - /** - * Get the query params for collections - * - * @return array - */ - public function get_collection_params() { - $params = parent::get_collection_params(); - - if ( '' !== $this->taxonomy && taxonomy_exists( $this->taxonomy ) ) { - $taxonomy = get_taxonomy( $this->taxonomy ); - } else { - $taxonomy = new stdClass(); - $taxonomy->hierarchical = true; - } - - $params['context']['default'] = 'view'; - - $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), - '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-rest-api' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', - ), - 'default' => array(), - 'sanitize_callback' => 'wp_parse_id_list', - ); - if ( ! $taxonomy->hierarchical ) { - $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - } - $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_key', - 'default' => 'asc', - 'enum' => array( - 'asc', - 'desc', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['orderby'] = array( - 'description' => __( 'Sort collection by resource attribute.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'sanitize_callback' => 'sanitize_key', - 'default' => 'name', - 'enum' => array( - 'id', - 'include', - 'name', - 'slug', - 'term_group', - 'description', - 'count', - ), - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['hide_empty'] = array( - 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce-rest-api' ), - 'type' => 'boolean', - 'default' => false, - 'validate_callback' => 'rest_validate_request_arg', - ); - if ( $taxonomy->hierarchical ) { - $params['parent'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', - ); - } - $params['product'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce-rest-api' ), - 'type' => 'integer', - 'default' => null, - 'validate_callback' => 'rest_validate_request_arg', - ); - $params['slug'] = array( - 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce-rest-api' ), - 'type' => 'string', - 'validate_callback' => 'rest_validate_request_arg', - ); - - return $params; - } - - /** - * Get taxonomy. - * - * @param WP_REST_Request $request Full details about the request. - * @return int|WP_Error - */ - protected function get_taxonomy( $request ) { - // Check if taxonomy is defined. - // Prevents check for attribute taxonomy more than one time for each query. - if ( '' !== $this->taxonomy ) { - return $this->taxonomy; - } - - if ( ! empty( $request['attribute_id'] ) ) { - $taxonomy = wc_attribute_taxonomy_name_by_id( (int) $request['attribute_id'] ); - - $this->taxonomy = $taxonomy; - } - - return $this->taxonomy; - } -} diff --git a/src/Controllers/Version3/class-wc-rest-webhooks-controller.php b/src/Controllers/Version3/class-wc-rest-webhooks-controller.php deleted file mode 100644 index 7b2817290fa..00000000000 --- a/src/Controllers/Version3/class-wc-rest-webhooks-controller.php +++ /dev/null @@ -1,37 +0,0 @@ -init(); - } - - /** - * Return the version of the package. - * - * @return string - */ - public static function get_version() { - return self::VERSION; - } - - /** - * Return the path to the package. - * - * @return string - */ - public static function get_path() { - return dirname( __DIR__ ); - } -} diff --git a/src/Server.php b/src/Server.php deleted file mode 100644 index 1c589c0da75..00000000000 --- a/src/Server.php +++ /dev/null @@ -1,181 +0,0 @@ -get_rest_namespaces() as $namespace => $controllers ) { - foreach ( $controllers as $controller_name => $controller_class ) { - $this->controllers[ $namespace ][ $controller_name ] = new $controller_class(); - $this->controllers[ $namespace ][ $controller_name ]->register_routes(); - } - } - } - - /** - * Get API namespaces - new namespaces should be registered here. - * - * @return array List of Namespaces and Main controller classes. - */ - protected function get_rest_namespaces() { - return apply_filters( - 'woocommerce_rest_api_get_rest_namespaces', - [ - 'wc/v1' => $this->get_v1_controllers(), - 'wc/v2' => $this->get_v2_controllers(), - 'wc/v3' => $this->get_v3_controllers(), - ] - ); - } - - /** - * List of controllers in the wc/v1 namespace. - * - * @return array - */ - protected function get_v1_controllers() { - return [ - 'coupons' => 'WC_REST_Coupons_V1_Controller', - 'customer-downloads' => 'WC_REST_Customer_Downloads_V1_Controller', - 'customers' => 'WC_REST_Customers_V1_Controller', - 'order-notes' => 'WC_REST_Order_Notes_V1_Controller', - 'order-refunds' => 'WC_REST_Order_Refunds_V1_Controller', - 'orders' => 'WC_REST_Orders_V1_Controller', - 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V1_Controller', - 'product-attributes' => 'WC_REST_Product_Attributes_V1_Controller', - 'product-categories' => 'WC_REST_Product_Categories_V1_Controller', - 'product-reviews' => 'WC_REST_Product_Reviews_V1_Controller', - 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V1_Controller', - 'product-tags' => 'WC_REST_Product_Tags_V1_Controller', - 'products' => 'WC_REST_Products_V1_Controller', - 'reports-sales' => 'WC_REST_Report_Sales_V1_Controller', - 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V1_Controller', - 'reports' => 'WC_REST_Reports_V1_Controller', - 'tax-classes' => 'WC_REST_Tax_Classes_V1_Controller', - 'taxes' => 'WC_REST_Taxes_V1_Controller', - 'webhooks' => 'WC_REST_Webhooks_V1_Controller', - 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V1_Controller', - ]; - } - - /** - * List of controllers in the wc/v2 namespace. - * - * @return array - */ - protected function get_v2_controllers() { - return [ - 'coupons' => 'WC_REST_Coupons_V2_Controller', - 'customer-downloads' => 'WC_REST_Customer_Downloads_V2_Controller', - 'customers' => 'WC_REST_Customers_V2_Controller', - 'network-orders' => 'WC_REST_Network_Orders_V2_Controller', - 'order-notes' => 'WC_REST_Order_Notes_V2_Controller', - 'order-refunds' => 'WC_REST_Order_Refunds_V2_Controller', - 'orders' => 'WC_REST_Orders_V2_Controller', - 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V2_Controller', - 'product-attributes' => 'WC_REST_Product_Attributes_V2_Controller', - 'product-categories' => 'WC_REST_Product_Categories_V2_Controller', - 'product-reviews' => 'WC_REST_Product_Reviews_V2_Controller', - 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V2_Controller', - 'product-tags' => 'WC_REST_Product_Tags_V2_Controller', - 'products' => 'WC_REST_Products_V2_Controller', - 'product-variations' => 'WC_REST_Product_Variations_V2_Controller', - 'reports-sales' => 'WC_REST_Report_Sales_V2_Controller', - 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V2_Controller', - 'reports' => 'WC_REST_Reports_V2_Controller', - 'settings' => 'WC_REST_Settings_V2_Controller', - 'settings-options' => 'WC_REST_Setting_Options_V2_Controller', - 'shipping-zones' => 'WC_REST_Shipping_Zones_V2_Controller', - 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_V2_Controller', - 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_V2_Controller', - 'tax-classes' => 'WC_REST_Tax_Classes_V2_Controller', - 'taxes' => 'WC_REST_Taxes_V2_Controller', - 'webhooks' => 'WC_REST_Webhooks_V2_Controller', - 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V2_Controller', - 'system-status' => 'WC_REST_System_Status_V2_Controller', - 'system-status-tools' => 'WC_REST_System_Status_Tools_V2_Controller', - 'shipping-methods' => 'WC_REST_Shipping_Methods_V2_Controller', - 'payment-gateways' => 'WC_REST_Payment_Gateways_V2_Controller', - ]; - } - - /** - * List of controllers in the wc/v3 namespace. - * - * @return array - */ - protected function get_v3_controllers() { - return [ - 'coupons' => 'WC_REST_Coupons_Controller', - 'customer-downloads' => 'WC_REST_Customer_Downloads_Controller', - 'customers' => 'WC_REST_Customers_Controller', - 'network-orders' => 'WC_REST_Network_Orders_Controller', - 'order-notes' => 'WC_REST_Order_Notes_Controller', - 'order-refunds' => 'WC_REST_Order_Refunds_Controller', - 'orders' => 'WC_REST_Orders_Controller', - 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_Controller', - 'product-attributes' => 'WC_REST_Product_Attributes_Controller', - 'product-categories' => 'WC_REST_Product_Categories_Controller', - 'product-reviews' => 'WC_REST_Product_Reviews_Controller', - 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_Controller', - 'product-tags' => 'WC_REST_Product_Tags_Controller', - 'products' => 'WC_REST_Products_Controller', - 'product-variations' => 'WC_REST_Product_Variations_Controller', - 'reports-sales' => 'WC_REST_Report_Sales_Controller', - 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_Controller', - 'reports-orders-totals' => 'WC_REST_Report_Orders_Totals_Controller', - 'reports-products-totals' => 'WC_REST_Report_Products_Totals_Controller', - 'reports-customers-totals' => 'WC_REST_Report_Customers_Totals_Controller', - 'reports-coupons-totals' => 'WC_REST_Report_Coupons_Totals_Controller', - 'reports-reviews-totals' => 'WC_REST_Report_Reviews_Totals_Controller', - 'reports' => 'WC_REST_Reports_Controller', - 'settings' => 'WC_REST_Settings_Controller', - 'settings-options' => 'WC_REST_Setting_Options_Controller', - 'shipping-zones' => 'WC_REST_Shipping_Zones_Controller', - 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_Controller', - 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_Controller', - 'tax-classes' => 'WC_REST_Tax_Classes_Controller', - 'taxes' => 'WC_REST_Taxes_Controller', - 'webhooks' => 'WC_REST_Webhooks_Controller', - 'system-status' => 'WC_REST_System_Status_Controller', - 'system-status-tools' => 'WC_REST_System_Status_Tools_Controller', - 'shipping-methods' => 'WC_REST_Shipping_Methods_Controller', - 'payment-gateways' => 'WC_REST_Payment_Gateways_Controller', - 'data' => 'WC_REST_Data_Controller', - 'data-continents' => 'WC_REST_Data_Continents_Controller', - 'data-countries' => 'WC_REST_Data_Countries_Controller', - 'data-currencies' => 'WC_REST_Data_Currencies_Controller', - ]; - } -} diff --git a/src/Utilities/ImageAttachment.php b/src/Utilities/ImageAttachment.php deleted file mode 100644 index 115aa7d0279..00000000000 --- a/src/Utilities/ImageAttachment.php +++ /dev/null @@ -1,93 +0,0 @@ -id = (int) $id; - $this->object_id = (int) $object_id; - } - - /** - * Upload an attachment file. - * - * @throws \WC_REST_Exception REST API exceptions. - * @param string $src URL to file. - */ - public function upload_image_from_src( $src ) { - $upload = wc_rest_upload_image_from_url( esc_url_raw( $src ) ); - - if ( is_wp_error( $upload ) ) { - if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $this->object_id, $images ) ) { - throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); - } else { - return; - } - } - - $this->id = wc_rest_set_uploaded_image_as_attachment( $upload, $this->object_id ); - - if ( ! wp_attachment_is_image( $this->id ) ) { - /* translators: %s: image ID */ - throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $this->id ), 400 ); - } - } - - /** - * Update attachment alt text. - * - * @param string $text Text to set. - */ - public function update_alt_text( $text ) { - if ( ! $this->id ) { - return; - } - update_post_meta( $this->id, '_wp_attachment_image_alt', wc_clean( $text ) ); - } - - /** - * Update attachment name. - * - * @param string $text Text to set. - */ - public function update_name( $text ) { - if ( ! $this->id ) { - return; - } - wp_update_post( - array( - 'ID' => $this->id, - 'post_title' => $text, - ) - ); - } -} diff --git a/src/Utilities/SingletonTrait.php b/src/Utilities/SingletonTrait.php deleted file mode 100644 index 37aef2e35c7..00000000000 --- a/src/Utilities/SingletonTrait.php +++ /dev/null @@ -1,49 +0,0 @@ -wp_tests_dir = getenv( 'WP_TESTS_DIR' ) ? getenv( 'WP_TESTS_DIR' ) : rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; - $this->tests_dir = dirname( __FILE__ ); - $this->plugin_dir = dirname( $this->tests_dir ); - - if ( file_exists( dirname( $this->plugin_dir ) . '/woocommerce/woocommerce.php' ) ) { - // From plugin directory. - $this->plugins_dir = dirname( $this->plugin_dir ); - } else { - // Travis. - $this->plugins_dir = getenv( 'WP_CORE_DIR' ) . '/wp-content/plugins'; - } - - $this->wc_tests_dir = $this->plugins_dir . '/woocommerce/tests'; - - $this->setup_hooks(); - $this->load_framework(); - } - - /** - * Get tests dir. - * - * @return string - */ - public function get_dir() { - return dirname( __FILE__ ); - } - - /** - * Setup hooks. - */ - protected function setup_hooks() { - // Give access to tests_add_filter() function. - require_once $this->wp_tests_dir . '/includes/functions.php'; - - \tests_add_filter( 'muplugins_loaded', function() { - require_once $this->plugins_dir . '/woocommerce/woocommerce.php'; - require_once $this->plugin_dir . '/woocommerce-rest-api.php'; - } ); - - \tests_add_filter( 'setup_theme', function() { - echo \esc_html( 'Installing WooCommerce...' . PHP_EOL ); - - define( 'WP_UNINSTALL_PLUGIN', true ); - define( 'WC_REMOVE_ALL_DATA', true ); - include $this->plugins_dir . '/woocommerce/uninstall.php'; - - \WC_Install::install(); - - $GLOBALS['wp_roles'] = null; // WPCS: override ok. - \wp_roles(); - } ); - } - - /** - * Load the testing framework. - */ - protected function load_framework() { - // Start up the WP testing environment. - require_once $this->wp_tests_dir . '/includes/bootstrap.php'; - - // WooCommerce Core Testing Framework. - require_once $this->wc_tests_dir . '/legacy/framework/class-wc-unit-test-factory.php'; - require_once $this->wc_tests_dir . '/legacy/framework/vendor/class-wp-test-spy-rest-server.php'; - require_once $this->wc_tests_dir . '/legacy/includes/wp-http-testcase.php'; - require_once $this->wc_tests_dir . '/legacy/framework/class-wc-unit-test-case.php'; - require_once $this->wc_tests_dir . '/legacy/framework/class-wc-rest-unit-test-case.php'; - - require_once $this->tests_dir . '/Helpers/AdminNotesHelper.php'; - require_once $this->tests_dir . '/Helpers/CouponHelper.php'; - require_once $this->tests_dir . '/Helpers/CustomerHelper.php'; - require_once $this->tests_dir . '/Helpers/OrderHelper.php'; - require_once $this->tests_dir . '/Helpers/ProductHelper.php'; - require_once $this->tests_dir . '/Helpers/ShippingHelper.php'; - require_once $this->tests_dir . '/Helpers/SettingsHelper.php'; - require_once $this->tests_dir . '/Helpers/QueueHelper.php'; - require_once $this->tests_dir . '/AbstractRestApiTest.php'; - } -} - -Bootstrap::instance()->init(); diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh deleted file mode 100755 index 8ab83ff1a13..00000000000 --- a/unit-tests/bin/install.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash - -if [ $# -lt 3 ]; then - echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" - exit 1 -fi - -DB_NAME=$1 -DB_USER=$2 -DB_PASS=$3 -DB_HOST=${4-localhost} -WP_VERSION=${5-latest} -SKIP_DB_CREATE=${6-false} - -TMPDIR=${TMPDIR-/tmp} -TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//") -WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib} -WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress/} - -# Error if WP < 5 -if [[ $WP_VERSION =~ ^([0-9]+)[0-9\.]+\-? ]]; then - if [ "5" -gt "${BASH_REMATCH[1]}" ]; then - echo "You must use WordPress 5.0 or greater." - exit 1 - fi -fi - -download() { - if [ `which curl` ]; then - curl -s "$1" > "$2"; - elif [ `which wget` ]; then - wget -nv -O "$2" "$1" - fi -} - -if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then - WP_TESTS_TAG="branches/$WP_VERSION" -elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then - if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then - # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x - WP_TESTS_TAG="tags/${WP_VERSION%??}" - else - WP_TESTS_TAG="tags/$WP_VERSION" - fi -elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - WP_TESTS_TAG="trunk" -else - # http serves a single offer, whereas https serves multiple. we only want one - download http://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json - grep '[0-9]+\.[0-9]+(\.[0-9]+)?' $TMPDIR/wp-latest.json - LATEST_VERSION=$(grep -o '"version":"[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//') - if [[ -z "$LATEST_VERSION" ]]; then - echo "Latest WordPress version could not be found" - exit 1 - fi - WP_TESTS_TAG="tags/$LATEST_VERSION" -fi - -set -ex - -install_wp() { - - if [ -d $WP_CORE_DIR ]; then - return; - fi - - mkdir -p $WP_CORE_DIR - - if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - mkdir -p $TMPDIR/wordpress-nightly - download https://wordpress.org/nightly-builds/wordpress-latest.zip $TMPDIR/wordpress-nightly/wordpress-nightly.zip - unzip -q $TMPDIR/wordpress-nightly/wordpress-nightly.zip -d $TMPDIR/wordpress-nightly/ - mv $TMPDIR/wordpress-nightly/wordpress/* $WP_CORE_DIR - else - if [ $WP_VERSION == 'latest' ]; then - local ARCHIVE_NAME='latest' - elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then - # https serves multiple offers, whereas http serves single. - download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json - if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then - # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x - LATEST_VERSION=${WP_VERSION%??} - else - # otherwise, scan the releases and get the most up to date minor version of the major release - local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'` - LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1) - fi - if [[ -z "$LATEST_VERSION" ]]; then - local ARCHIVE_NAME="wordpress-$WP_VERSION" - else - local ARCHIVE_NAME="wordpress-$LATEST_VERSION" - fi - else - local ARCHIVE_NAME="wordpress-$WP_VERSION" - fi - download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz - tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR - fi - - download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php -} - -install_test_suite() { - # portable in-place argument for both GNU sed and Mac OSX sed - if [[ $(uname -s) == 'Darwin' ]]; then - local ioption='-i .bak' - else - local ioption='-i' - fi - - # set up testing suite if it doesn't yet exist - if [ ! -d $WP_TESTS_DIR ]; then - # set up testing suite - mkdir -p $WP_TESTS_DIR - svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes - svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data - fi - - if [ ! -f wp-tests-config.php ]; then - download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php - # remove all forward slashes in the end - WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php - fi - -} - -install_db() { - - if [ ${SKIP_DB_CREATE} = "true" ]; then - return 0 - fi - - # parse DB_HOST for port or socket references - local PARTS=(${DB_HOST//\:/ }) - local DB_HOSTNAME=${PARTS[0]}; - local DB_SOCK_OR_PORT=${PARTS[1]}; - local EXTRA="" - - if ! [ -z $DB_HOSTNAME ] ; then - if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then - EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" - elif ! [ -z $DB_SOCK_OR_PORT ] ; then - EXTRA=" --socket=$DB_SOCK_OR_PORT" - elif ! [ -z $DB_HOSTNAME ] ; then - EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" - fi - fi - - # create database - mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA -} - -install_deps() { - - # Script Variables - WP_SITE_URL="http://local.wordpress.test" - BRANCH=$TRAVIS_BRANCH - REPO=$TRAVIS_REPO_SLUG - WORKING_DIR="$PWD" - - if [ "$TRAVIS_PULL_REQUEST_BRANCH" != "" ]; then - BRANCH=$TRAVIS_PULL_REQUEST_BRANCH - REPO=$TRAVIS_PULL_REQUEST_SLUG - fi - - # Set up WordPress using wp-cli - mkdir -p "$WP_CORE_DIR" - cd "$WP_CORE_DIR" - - curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar - php wp-cli.phar core config --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS --dbhost=$DB_HOST --dbprefix=wptests_ - php wp-cli.phar core install --url="$WP_SITE_URL" --title="Example" --admin_user=admin --admin_password=password --admin_email=info@example.com --path=$WP_CORE_DIR --skip-email - - # Install WooCommerce and WooCommerce Admin - cd "wp-content/plugins/" - - git clone --depth 1 https://github.com/woocommerce/woocommerce.git - - cd "woocommerce" - composer install - - cd "$WP_CORE_DIR" - php wp-cli.phar plugin activate woocommerce - - if [ "$BRANCH" != "" ]; then - # Install the correct branch of the plugin, if running from Travis CI. - php wp-cli.phar plugin install https://github.com/$REPO/archive/$BRANCH.zip --activate - fi - - # Back to original dir - cd "$WORKING_DIR" -} - -install_wp -install_test_suite -install_db -install_deps diff --git a/unit-tests/bin/phpcs.sh b/unit-tests/bin/phpcs.sh deleted file mode 100755 index 5a2c8b48a05..00000000000 --- a/unit-tests/bin/phpcs.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -if [[ ${RUN_PHPCS} == 1 ]]; then - CHANGED_FILES=`git diff --name-only --diff-filter=ACMR $TRAVIS_COMMIT_RANGE | grep \\\\.php | awk '{print}' ORS=' '` - IGNORE="" - - if [ "$CHANGED_FILES" != "" ]; then - echo "Running Code Sniffer." - ./vendor/bin/phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES - fi -fi diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh deleted file mode 100755 index 12e95676881..00000000000 --- a/unit-tests/bin/phpunit.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -$HOME/.composer/vendor/bin/phpunit -c phpunit.xml $@ \ No newline at end of file diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php deleted file mode 100644 index 075a160c555..00000000000 --- a/woocommerce-rest-api.php +++ /dev/null @@ -1,68 +0,0 @@ - -

-

- composer install', - '' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '' - ); - ?> -

-
- Date: Thu, 23 Jul 2020 00:07:29 +0530 Subject: [PATCH 316/440] Keep only unit test files for merge into core. --- .../unit-tests/Tests/Version3/functions.php | 251 ------------------ 1 file changed, 251 deletions(-) delete mode 100644 tests/legacy/unit-tests/api/unit-tests/Tests/Version3/functions.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/functions.php b/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/functions.php deleted file mode 100644 index 3b3b27eb5c9..00000000000 --- a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/functions.php +++ /dev/null @@ -1,251 +0,0 @@ -http_responder = array( $this, 'mock_http_responses' ); - - $upload_dir_info = wp_upload_dir(); - $this->upload_dir_path = $upload_dir_info['path']; - $this->upload_dir_url = $upload_dir_info['url']; - $this->file_name = 'Dr1Bczxq4q.png'; - } - - /** - * Run tear down code for unit tests. - */ - public function tearDown() { - parent::tearDown(); - - // remove files created in the wc_rest_upload_image_from_url() tests. - $file_path = $this->upload_dir_path . '/' . $this->file_name; - - if ( file_exists( $file_path ) ) { - unlink( $file_path ); - } - } - - /** - * Test wc_rest_prepare_date_response(). - * - * @since 2.6.0 - */ - public function test_wc_rest_prepare_date_response() { - $this->assertEquals( '2016-06-06T06:06:06', wc_rest_prepare_date_response( '2016-06-06 06:06:06' ) ); - } - - /** - * Test wc_rest_upload_image_from_url() should return error when unable to download image. - */ - public function test_wc_rest_upload_image_from_url_should_return_error_when_unable_to_download_image() { - $expected_error_message = 'Error getting remote image http://somedomain.com/nonexistent-image.png. Error: Not found.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/nonexistent-image.png' ); - - $this->assertWPError( $result ); - $this->assertEquals( $expected_error_message, $result->get_error_message() ); - } - - /** - * Test wc_rest_upload_image_from_url() should return error when invalid image is passed. - * - * @requires PHP 5.4 - */ - public function test_wc_rest_upload_image_from_url_should_return_error_when_invalid_image_is_passed() { - // empty file. - $expected_error_message = 'Invalid image: File is empty.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-1.png' ); - - $this->assertWPError( $result ); - $this->assertStringStartsWith( $expected_error_message, $result->get_error_message() ); - - // unsupported mime type. - $expected_error_message = 'Invalid image: Sorry, this file type is not permitted for security reasons.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-2.png' ); - - $this->assertWPError( $result ); - $this->assertEquals( $expected_error_message, $result->get_error_message() ); - } - - /** - * Test wc_rest_upload_image_from_url() should download image and return an array containing - * information about it. - * - * @requires PHP 5.4 - */ - public function test_wc_rest_upload_image_from_url_should_download_image_and_return_array() { - $expected_result = array( - 'file' => $this->upload_dir_path . '/' . $this->file_name, - 'url' => $this->upload_dir_url . '/' . $this->file_name, - 'type' => 'image/png', - ); - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/' . $this->file_name ); - - $this->assertEquals( $expected_result, $result ); - } - - /** - * Test wc_rest_set_uploaded_image_as_attachment(). - * - * @since 2.6.0 - */ - public function test_wc_rest_set_uploaded_image_as_attachment() { - $this->assertInternalType( - 'int', - wc_rest_set_uploaded_image_as_attachment( - array( - 'file' => '', - 'url' => '', - ) - ) - ); - } - - /** - * Test wc_rest_validate_reports_request_arg(). - * - * @since 2.6.0 - */ - public function test_wc_rest_validate_reports_request_arg() { - $request = new WP_REST_Request( - 'GET', - '/wc/v3/foo', - array( - 'args' => array( - 'date' => array( - 'type' => 'string', - 'format' => 'date', - ), - ), - ) - ); - - // Success. - $this->assertTrue( wc_rest_validate_reports_request_arg( '2016-06-06', $request, 'date' ) ); - - // Error. - $error = wc_rest_validate_reports_request_arg( 'foo', $request, 'date' ); - $this->assertEquals( 'The date you provided is invalid.', $error->get_error_message() ); - } - - /** - * Test wc_rest_urlencode_rfc3986(). - * - * @since 2.6.0 - */ - public function test_wc_rest_urlencode_rfc3986() { - $this->assertEquals( 'https%3A%2F%2Fwoocommerce.com%2F', wc_rest_urlencode_rfc3986( 'https://woocommerce.com/' ) ); - } - - /** - * Test wc_rest_check_post_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_post_permissions() { - $this->assertFalse( wc_rest_check_post_permissions( 'shop_order' ) ); - } - - /** - * Test wc_rest_check_user_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_user_permissions() { - $this->assertFalse( wc_rest_check_user_permissions() ); - } - - /** - * Test wc_rest_check_product_term_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_product_term_permissions() { - $this->assertFalse( wc_rest_check_product_term_permissions( 'product_cat' ) ); - } - - /** - * Test wc_rest_check_manager_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_manager_permissions() { - $this->assertFalse( wc_rest_check_manager_permissions( 'reports' ) ); - } - - /** - * Helper method to define mocked HTTP responses using WP_HTTP_TestCase. - * Thanks to WP_HTTP_TestCase, it is not necessary to perform a regular request - * to an external server which would significantly slow down the tests. - * - * This function is called by WP_HTTP_TestCase::http_request_listner(). - * - * @param array $request Request arguments. - * @param string $url URL of the request. - * - * @return array|false mocked response or false to let WP perform a regular request. - */ - protected function mock_http_responses( $request, $url ) { - $mocked_response = false; - - if ( 'http://somedomain.com/nonexistent-image.png' === $url ) { - $mocked_response = array( - 'response' => array( - 'code' => 404, - 'message' => 'Not found.', - ), - ); - } elseif ( 'http://somedomain.com/invalid-image-1.png' === $url ) { - // empty image. - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } elseif ( 'http://somedomain.com/invalid-image-2.png' === $url ) { - // image with an unsupported mime type. - // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( Automattic\WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/file.txt', $request['filename'] ); - - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } elseif ( 'http://somedomain.com/' . $this->file_name === $url ) { - // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( Automattic\WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/Dr1Bczxq4q.png', $request['filename'] ); - - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } - - return $mocked_response; - } -} From 880b82a0373b5b019294409b4d29f861b8964261 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 23 Jul 2020 00:29:41 +0530 Subject: [PATCH 317/440] Keep only source to merge with core. --- .editorconfig | 24 - .gitattributes | 7 - .gitignore | 35 - .scrutinizer.yml | 118 - .travis.yml | 26 - README.md | 67 - composer.json | 46 - composer.lock | 1934 ----------------- package-lock.json | 1618 -------------- package.json | 31 - phpcs.xml | 40 - phpunit.xml | 17 - unit-tests/AbstractRestApiTest.php | 213 -- unit-tests/Bootstrap.php | 134 -- unit-tests/Helpers/AdminNotesHelper.php | 83 - unit-tests/Helpers/CouponHelper.php | 147 -- unit-tests/Helpers/CustomerHelper.php | 138 -- unit-tests/Helpers/OrderHelper.php | 129 -- unit-tests/Helpers/ProductHelper.php | 310 --- unit-tests/Helpers/QueueHelper.php | 62 - unit-tests/Helpers/SettingsHelper.php | 82 - unit-tests/Helpers/ShippingHelper.php | 50 - unit-tests/Tests/Version2/coupons.php | 471 ---- unit-tests/Tests/Version2/customers.php | 566 ----- unit-tests/Tests/Version2/orders.php | 721 ------ .../Tests/Version2/payment-gateways.php | 337 --- unit-tests/Tests/Version2/product-reviews.php | 468 ---- .../Tests/Version2/product-variations.php | 495 ----- unit-tests/Tests/Version2/products.php | 536 ----- unit-tests/Tests/Version2/settings.php | 892 -------- .../Tests/Version2/shipping-methods.php | 143 -- unit-tests/Tests/Version2/shipping-zones.php | 800 ------- unit-tests/Tests/Version2/system-status.php | 355 --- unit-tests/Tests/Version3/coupons.php | 471 ---- unit-tests/Tests/Version3/customers.php | 634 ------ unit-tests/Tests/Version3/functions.php | 251 --- unit-tests/Tests/Version3/orders.php | 778 ------- .../Tests/Version3/payment-gateways.php | 345 --- unit-tests/Tests/Version3/product-reviews.php | 470 ---- .../Tests/Version3/product-variations.php | 496 ----- unit-tests/Tests/Version3/products.php | 861 -------- .../Tests/Version3/reports-coupons-totals.php | 103 - .../Version3/reports-customers-totals.php | 119 - .../Tests/Version3/reports-orders-totals.php | 92 - .../Version3/reports-products-totals.php | 99 - .../Tests/Version3/reports-reviews-totals.php | 98 - unit-tests/Tests/Version3/settings.php | 895 -------- .../Tests/Version3/shipping-methods.php | 143 -- unit-tests/Tests/Version3/shipping-zones.php | 825 ------- unit-tests/Tests/Version3/system-status.php | 487 ----- unit-tests/bin/install.sh | 202 -- unit-tests/bin/phpcs.sh | 11 - unit-tests/bin/phpunit.sh | 2 - unit-tests/data/Dr1Bczxq4q.png | Bin 10325 -> 0 bytes unit-tests/data/file.txt | 1 - woocommerce-rest-api.php | 68 - 56 files changed, 18546 deletions(-) delete mode 100644 .editorconfig delete mode 100644 .gitattributes delete mode 100644 .gitignore delete mode 100644 .scrutinizer.yml delete mode 100644 .travis.yml delete mode 100644 README.md delete mode 100644 composer.json delete mode 100644 composer.lock delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 phpcs.xml delete mode 100644 phpunit.xml delete mode 100644 unit-tests/AbstractRestApiTest.php delete mode 100755 unit-tests/Bootstrap.php delete mode 100644 unit-tests/Helpers/AdminNotesHelper.php delete mode 100644 unit-tests/Helpers/CouponHelper.php delete mode 100644 unit-tests/Helpers/CustomerHelper.php delete mode 100644 unit-tests/Helpers/OrderHelper.php delete mode 100644 unit-tests/Helpers/ProductHelper.php delete mode 100644 unit-tests/Helpers/QueueHelper.php delete mode 100644 unit-tests/Helpers/SettingsHelper.php delete mode 100644 unit-tests/Helpers/ShippingHelper.php delete mode 100644 unit-tests/Tests/Version2/coupons.php delete mode 100644 unit-tests/Tests/Version2/customers.php delete mode 100644 unit-tests/Tests/Version2/orders.php delete mode 100644 unit-tests/Tests/Version2/payment-gateways.php delete mode 100644 unit-tests/Tests/Version2/product-reviews.php delete mode 100644 unit-tests/Tests/Version2/product-variations.php delete mode 100644 unit-tests/Tests/Version2/products.php delete mode 100644 unit-tests/Tests/Version2/settings.php delete mode 100644 unit-tests/Tests/Version2/shipping-methods.php delete mode 100644 unit-tests/Tests/Version2/shipping-zones.php delete mode 100644 unit-tests/Tests/Version2/system-status.php delete mode 100644 unit-tests/Tests/Version3/coupons.php delete mode 100644 unit-tests/Tests/Version3/customers.php delete mode 100644 unit-tests/Tests/Version3/functions.php delete mode 100644 unit-tests/Tests/Version3/orders.php delete mode 100644 unit-tests/Tests/Version3/payment-gateways.php delete mode 100644 unit-tests/Tests/Version3/product-reviews.php delete mode 100644 unit-tests/Tests/Version3/product-variations.php delete mode 100644 unit-tests/Tests/Version3/products.php delete mode 100644 unit-tests/Tests/Version3/reports-coupons-totals.php delete mode 100644 unit-tests/Tests/Version3/reports-customers-totals.php delete mode 100644 unit-tests/Tests/Version3/reports-orders-totals.php delete mode 100644 unit-tests/Tests/Version3/reports-products-totals.php delete mode 100644 unit-tests/Tests/Version3/reports-reviews-totals.php delete mode 100644 unit-tests/Tests/Version3/settings.php delete mode 100644 unit-tests/Tests/Version3/shipping-methods.php delete mode 100644 unit-tests/Tests/Version3/shipping-zones.php delete mode 100644 unit-tests/Tests/Version3/system-status.php delete mode 100755 unit-tests/bin/install.sh delete mode 100755 unit-tests/bin/phpcs.sh delete mode 100755 unit-tests/bin/phpunit.sh delete mode 100644 unit-tests/data/Dr1Bczxq4q.png delete mode 100644 unit-tests/data/file.txt delete mode 100644 woocommerce-rest-api.php diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index c3dfa83750f..00000000000 --- a/.editorconfig +++ /dev/null @@ -1,24 +0,0 @@ -# This file is for unifying the coding style for different editors and IDEs -# editorconfig.org - -# WordPress Coding Standards -# https://make.wordpress.org/core/handbook/coding-standards/ - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 4 -tab_width = 4 -indent_style = tab -insert_final_newline = true -trim_trailing_whitespace = true - -[*.txt] -trim_trailing_whitespace = false - -[*.{md,json,yml}] -trim_trailing_whitespace = false -indent_style = space -indent_size = 2 diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index b5d3da03cbb..00000000000 --- a/.gitattributes +++ /dev/null @@ -1,7 +0,0 @@ -/.* export-ignore -/phpcs.xml export-ignore -/phpunit.* export-ignore -/unit-tests export-ignore -/vendor export-ignore -/README.md export-ignore -/readme.txt export-ignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index b19a8d1f0ae..00000000000 --- a/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -# Editors -project.xml -project.properties -/nbproject/private/ -.buildpath -.project -.settings* -.idea -.vscode -*.sublime-project -*.sublime-workspace -.sublimelinterrc - -# Grunt -/node_modules/ -none - -# Sass -.sass-cache/ - -# OS X metadata -.DS_Store - -# Windows junk -Thumbs.db - -# Unit tests -/tmp -/unit-tests/bin/tmp - -# Logs -/logs - -# composer -vendor/ diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 04bbd2b73b4..00000000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,118 +0,0 @@ -tools: - php_code_sniffer: - config: - standard: WordPress - sensiolabs_security_checker: true -checks: - php: - avoid_closing_tag: false - avoid_superglobals: false - coding_standard: - name: WordPress - no_exit: false - no_global_keyword: false - one_class_per_file: false - psr2_class_declaration: false - psr2_control_structure_declaration: false - psr2_switch_declaration: false - variable_existence: false - verify_access_scope_valid: false - verify_argument_usable_as_reference: false - verify_property_names: false -filter: - dependency_paths: - - wordpress/ - - woocommerce/ - excluded_paths: - - src/Controllers/Version1/ - - src/Controllers/Version2/ - - src/Controllers/Version3/ - - tests/ - - vendor/ - - classmap.php -coding_style: - php: - indentation: - general: - use_tabs: true - size: 4 - switch: - indent_case: true - spaces: - around_operators: - concatenation: true - negation: true - within: - brackets: true - grouping: true - function_call: true - function_declaration: true - if: true - for: true - while: true - switch: true - catch: true - before_left_brace: - class: true - function: true - if: true - else: true - for: true - while: true - do: true - switch: true - try: true - catch: true - finally: true - before_keywords: - else: true - while: true - catch: true - finally: true - ternary_operator: - before_condition: true - after_condition: true - before_alternative: true - after_alternative: true - in_short_version: false - other: - before_comma: false - after_comma: true - before_semicolon: false - after_semicolon: true - after_type_cast: true - braces: - classes_functions: - class: end-of-line - function: end-of-line - closure: end-of-line - if: - opening: undefined - always: true - else_on_new_line: false - for: - opening: undefined - always: true - while: - opening: undefined - always: true - do_while: - opening: undefined - always: true - while_on_new_line: false - switch: - opening: undefined - try: - opening: undefined - catch_on_new_line: false - finally_on_new_line: false -build: - tests: - override: - command: "php -v" - nodes: - analysis: - dependencies: - before: - - composer require --dev johnpbloch/wordpress-core - - composer require --dev woocommerce/woocommerce diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c907c8983a9..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: php -dist: trusty -sudo: required -cache: - directories: - - vendor - - $HOME/.composer/cache -matrix: - include: - - name: "PHP 7.2 unit tests, PHP Coding standards check" - php: 7.2 - env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress RUN_PHPCS=1 - - name: "PHP 7.1 unit tests" - php: 7.1 - env: WP_VERSION=latest WP_MULTISITE=0 WP_CORE_DIR=/tmp/wordpress - -before_script: - - export PATH="$HOME/.composer/vendor/bin:$PATH" - - phpenv config-rm xdebug.ini - - composer install - - composer global require "phpunit/phpunit=4.8.*|6.5.*" - - bash unit-tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION - -script: - - bash unit-tests/bin/phpunit.sh - - bash unit-tests/bin/phpcs.sh diff --git a/README.md b/README.md deleted file mode 100644 index 9a2eff0a244..00000000000 --- a/README.md +++ /dev/null @@ -1,67 +0,0 @@ -WooCommerce REST API -=== - -license -Latest Stable Version -Build Status -Scrutinizer Code Quality - -This repository is home to the WooCommerce REST API package. - -The stable version of this package is bundled with [WooCommerce core](https://github.com/woocommerce/woocommerce) releases, but it can also be used as a standalone plugin so bleeding-edge API features can be tested or used by other feature plugins. - -## Using this package as a plugin - -After checking out the code to your `wp-content/plugins` directory, you'll need to run `composer install` in the plugin directory (`wp-content/plugins/woocommerce-rest-api`) to install dependencies and to enable the autoloader. Without performing this step, if you activate the plugin it will simply show an admin notice. - -## API documentation - -- [Usage documentation for the REST API can be found here](https://github.com/woocommerce/woocommerce/wiki/Getting-started-with-the-REST-API). -- [Contribution documentation can be found here.](https://github.com/woocommerce/woocommerce/wiki/Contributing-to-the-WooCommerce-REST-API) - -### Versions - -| Namespace | Status | Docs | -| -------- | -------- | -------- | -| `wc/v4` | Development | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/) | -| `wc/v3` | Stable | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/) | -| `wc/v2` | Deprecated - October 2020 | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v2.html) | -| `wc/v1` | Deprecated - April 2019 | [Link](https://woocommerce.github.io/woocommerce-rest-api-docs/wp-api-v1.html) | - -Note: API Versions are kept around for 2 years after being replaced, and may be removed in the next major version after that date passes. - -## Using this package in other projects - -This package is [hosted on Packagist](https://packagist.org/packages/woocommerce/woocommerce-rest-api) and can be included using composer.json: - -```json -"require": { - "woocommerce/woocommerce-rest-api": "1.0" -}, -``` - -Since multiple versions of this package may be included at the same time, it includes a special package-version autoloader. This dependency is also on Packagist: - -```json - "automattic/jetpack-autoloader": "^1" -``` - -And using this autoloader requires the following include in your codebase: - -``` -$autoloader = __DIR__ . '/vendor/autoload_packages.php'; -``` - -If you choose to use your own autoloader, please note you won't be able to determine which version of the package is running since it could use the version in WooCommerce core or your version. The namespaces would conflict. All of our feature plugins and packages use the package autoloader. - -## Contributing - -Please read the [WooCommerce contributor guidelines](https://github.com/woocommerce/woocommerce/blob/master/.github/CONTRIBUTING.md) for more information how you can contribute to WooCommerce, and [the REST API contribution documentation here](https://github.com/woocommerce/woocommerce/wiki/Contributing-to-the-WooCommerce-REST-API). - -Within this package, namespaces and endpoint classes are located within the `src/RestAPI/` directory. If you need to change the behavior of an endpoint, you can do so in these classes. - -Run tests using `phpunit` in the root of the package. All pull-requests must pass unit tests in order to be accepted. - -## Translation - -For strings located in API endpoints, use `woocommerce` as your text-domain. These endpoints will be translated in the WooCommerce Core PO/MO files. diff --git a/composer.json b/composer.json deleted file mode 100644 index 537262ed3c2..00000000000 --- a/composer.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "woocommerce/woocommerce-rest-api", - "description": "The WooCommerce core REST API.", - "homepage": "https://github.com/woocommerce/woocommerce-rest-api", - "license": "GPL-3.0-or-later", - "type": "wordpress-plugin", - "prefer-stable": true, - "minimum-stability": "dev", - "require": { - "automattic/jetpack-autoloader": "^1.6.0" - }, - "require-dev": { - "phpunit/phpunit": "6.5.14", - "woocommerce/woocommerce-sniffs": "0.0.9" - }, - "scripts": { - "post-install-cmd": [ - "composer dump-autoload" - ], - "post-update-cmd": [ - "composer dump-autoload" - ], - "test": [ - "phpunit" - ], - "phpcs": [ - "phpcs -s -p" - ], - "phpcs-pre-commit": [ - "phpcs -s -p -n" - ], - "phpcbf": [ - "phpcbf -p" - ] - }, - "autoload": { - "classmap": [ - "src/Controllers/Version1", - "src/Controllers/Version2", - "src/Controllers/Version3" - ], - "psr-4": { - "Automattic\\WooCommerce\\RestApi\\": "src" - } - } -} diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 35c89885f43..00000000000 --- a/composer.lock +++ /dev/null @@ -1,1934 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "18fc7a15ab7921e538dea77490edd41b", - "packages": [ - { - "name": "automattic/jetpack-autoloader", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7", - "reference": "3bcbe1ae19febd6beeb181cf11af0bf0b7abe7e7", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5" - }, - "type": "composer-plugin", - "extra": { - "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin" - }, - "autoload": { - "psr-4": { - "Automattic\\Jetpack\\Autoloader\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0-or-later" - ], - "description": "Creates a custom autoloader for a plugin or theme.", - "time": "2020-03-26T07:57:53+00:00" - } - ], - "packages-dev": [ - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.5.0", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "e749410375ff6fb7a040a68878c656c2e610b132" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132", - "reference": "e749410375ff6fb7a040a68878c656c2e610b132", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0", - "php": "^5.3|^7", - "squizlabs/php_codesniffer": "^2|^3" - }, - "require-dev": { - "composer/composer": "*", - "phpcompatibility/php-compatibility": "^9.0", - "sensiolabs/security-checker": "^4.1.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "time": "2018-10-26T13:21:45+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2019-10-21T16:45:58+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.9.3", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", - "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "time": "2019-08-09T12:45:53+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" - }, - { - "name": "phar-io/version", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" - }, - { - "name": "phpcompatibility/php-compatibility", - "version": "9.3.4", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "1f37659196e4f3113ea506a7efba201c52303bf1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/1f37659196e4f3113ea506a7efba201c52303bf1", - "reference": "1f37659196e4f3113ea506a7efba201c52303bf1", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" - }, - "conflict": { - "squizlabs/php_codesniffer": "2.6.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "homepage": "https://github.com/wimg", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" - } - ], - "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", - "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", - "keywords": [ - "compatibility", - "phpcs", - "standards" - ], - "time": "2019-11-15T04:12:02+00:00" - }, - { - "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/b862bc32f7e860d0b164b199bd995e690b4b191c", - "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c", - "shasum": "" - }, - "require": { - "phpcompatibility/php-compatibility": "^9.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5", - "paragonie/random_compat": "dev-master", - "paragonie/sodium_compat": "dev-master" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } - ], - "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", - "homepage": "http://phpcompatibility.com/", - "keywords": [ - "compatibility", - "paragonie", - "phpcs", - "polyfill", - "standards" - ], - "time": "2019-11-04T15:17:54+00:00" - }, - { - "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "41bef18ba688af638b7310666db28e1ea9158b2f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/41bef18ba688af638b7310666db28e1ea9158b2f", - "reference": "41bef18ba688af638b7310666db28e1ea9158b2f", - "shasum": "" - }, - "require": { - "phpcompatibility/php-compatibility": "^9.0", - "phpcompatibility/phpcompatibility-paragonie": "^1.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } - ], - "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", - "homepage": "http://phpcompatibility.com/", - "keywords": [ - "compatibility", - "phpcs", - "standards", - "wordpress" - ], - "time": "2019-08-28T14:22:28+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2018-08-07T13:53:10+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-09-12T14:27:41+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "shasum": "" - }, - "require": { - "php": "^7.1", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "^7.1", - "mockery/mockery": "~1", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2019-08-22T18:11:29+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.9.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", - "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2019-10-03T11:07:50+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "5.3.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-xdebug": "^2.5.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2018-04-06T15:36:58+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2017-02-26T11:10:40+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2017-11-27T05:48:46+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "6.5.14", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.9", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.5.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2019-02-01T05:22:47+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.10", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5.11" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "abandoned": true, - "time": "2018-08-09T05:50:03+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" - }, - { - "name": "sebastian/comparator", - "version": "2.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2018-02-01T13:46:46+00:00" - }, - { - "name": "sebastian/diff", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2017-08-03T08:09:46+00:00" - }, - { - "name": "sebastian/environment", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2017-07-01T08:51:00+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2019-09-14T09:02:43+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.5.3", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", - "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2019-12-04T04:46:47+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.13.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.13-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "time": "2019-11-27T13:56:44+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2019-06-13T22:48:21+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "vimeo/psalm": "<3.6.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2019-11-24T13:36:37+00:00" - }, - { - "name": "woocommerce/woocommerce-sniffs", - "version": "0.0.9", - "source": { - "type": "git", - "url": "https://github.com/woocommerce/woocommerce-sniffs.git", - "reference": "7677a84e9a355fe1e088f704090be891e7a6d427" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/7677a84e9a355fe1e088f704090be891e7a6d427", - "reference": "7677a84e9a355fe1e088f704090be891e7a6d427", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "0.5.0", - "php": ">=7.0", - "phpcompatibility/phpcompatibility-wp": "2.1.0", - "wp-coding-standards/wpcs": "2.2.0" - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Claudio Sanches", - "email": "claudio@automattic.com" - } - ], - "description": "WooCommerce sniffs", - "keywords": [ - "phpcs", - "standards", - "woocommerce", - "wordpress" - ], - "time": "2019-11-11T15:48:34+00:00" - }, - { - "name": "wp-coding-standards/wpcs", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/f90e8692ce97b693633db7ab20bfa78d930f536a", - "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.3.1" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", - "phpcompatibility/php-compatibility": "^9.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Contributors", - "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", - "keywords": [ - "phpcs", - "standards", - "wordpress" - ], - "time": "2019-11-11T12:34:03+00:00" - } - ], - "aliases": [], - "minimum-stability": "dev", - "stability-flags": [], - "prefer-stable": true, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] -} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index b1506082765..00000000000 --- a/package-lock.json +++ /dev/null @@ -1,1618 +0,0 @@ -{ - "name": "woocommerce-rest-api", - "version": "1.0.5", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/runtime": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", - "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - } - }, - "@samverschueren/stream-to-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", - "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", - "dev": true, - "requires": { - "any-observable": "^0.3.0" - } - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.5.0.tgz", - "integrity": "sha512-Onhn+z72D2O2Pb2ql2xukJ55rglumsVo1H6Fmyi8mlU9SvKdBk/pUSUAiBY/d9bAOF7VVWajX3sths/+g6ZiAQ==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "any-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", - "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - } - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", - "dev": true, - "requires": { - "slice-ansi": "0.0.4", - "string-width": "^1.0.1" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "date-fns": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", - "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "del": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", - "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", - "dev": true, - "requires": { - "globby": "^10.0.1", - "graceful-fs": "^4.2.2", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.1", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "elegant-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "execa": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", - "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^3.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "fast-glob": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", - "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2" - } - }, - "fastq": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", - "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", - "dev": true, - "requires": { - "reusify": "^1.0.0" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "dev": true - }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "husky": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.0.10.tgz", - "integrity": "sha512-Ptm4k2DqOwxeK/kzu5RaJmNRoGvESrgDXObFcZ8aJZcyXyMBHhM2FqZj6zYKdetadmP3wCwxEHCBuB9xGlRp8A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "ci-info": "^2.0.0", - "cosmiconfig": "^6.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^4.2.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - } - }, - "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "dev": true - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-observable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", - "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", - "dev": true, - "requires": { - "symbol-observable": "^1.1.0" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "dev": true - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "lint-staged": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz", - "integrity": "sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "commander": "^2.20.0", - "cosmiconfig": "^5.2.1", - "debug": "^4.1.1", - "dedent": "^0.7.0", - "del": "^5.0.0", - "execa": "^2.0.3", - "listr": "^0.14.3", - "log-symbols": "^3.0.0", - "micromatch": "^4.0.2", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.1.1", - "string-argv": "^0.3.0", - "stringify-object": "^3.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "listr": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", - "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", - "dev": true, - "requires": { - "@samverschueren/stream-to-observable": "^0.3.0", - "is-observable": "^1.1.0", - "is-promise": "^2.1.0", - "is-stream": "^1.1.0", - "listr-silent-renderer": "^1.1.1", - "listr-update-renderer": "^0.5.0", - "listr-verbose-renderer": "^0.5.0", - "p-map": "^2.0.0", - "rxjs": "^6.3.3" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - } - } - }, - "listr-silent-renderer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", - "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", - "dev": true - }, - "listr-update-renderer": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", - "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "elegant-spinner": "^1.0.1", - "figures": "^1.7.0", - "indent-string": "^3.0.0", - "log-symbols": "^1.0.2", - "log-update": "^2.3.0", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "^1.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "listr-verbose-renderer": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", - "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "cli-cursor": "^2.1.0", - "date-fns": "^1.27.2", - "figures": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "log-update": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", - "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "cli-cursor": "^2.0.0", - "wrap-ansi": "^3.0.1" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", - "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - } - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, - "wrap-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", - "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "yaml": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", - "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.6.3" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 2d17f61330a..00000000000 --- a/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "woocommerce-rest-api", - "title": "WooCommerce REST API", - "version": "1.0.10", - "homepage": "https://woocommerce.com/", - "repository": { - "type": "git", - "url": "https://github.com/woocommerce/woocommerce-rest-api.git" - }, - "license": "GPL-3.0+", - "main": "Gruntfile.js", - "devDependencies": { - "husky": "4.0.10", - "lint-staged": "9.5.0" - }, - "engines": { - "node": ">=10.15.0", - "npm": ">=6.4.1" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "*.php": [ - "php -d display_errors=1 -l", - "composer run-script phpcs-pre-commit" - ] - } -} diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index ceb59896bf8..00000000000 --- a/phpcs.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - WooCommerce dev PHP_CodeSniffer ruleset. - - - tests/ - apigen/ - */node_modules/* - */vendor/* - - - - - - - - - - - - - - - - tests/ - - - - * - - - - tests/ - - - - i18n/ - * - - diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index 9119520176d..00000000000 --- a/phpunit.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - ./unit-tests/Tests - - - diff --git a/unit-tests/AbstractRestApiTest.php b/unit-tests/AbstractRestApiTest.php deleted file mode 100644 index 3646b4681ff..00000000000 --- a/unit-tests/AbstractRestApiTest.php +++ /dev/null @@ -1,213 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup test class. - */ - public function setUp() { - parent::setUp(); - wp_set_current_user( self::$user ); - } - - /** - * Test route registration. - */ - public function test_register_routes() { - $actual_routes = $this->server->get_routes(); - $expected_routes = $this->routes; - - foreach ( $expected_routes as $expected_route ) { - $this->assertArrayHasKey( $expected_route, $actual_routes ); - } - } - - /** - * Validate that the returned API schema matches what is expected. - * - * @return void - */ - public function test_schema_properties() { - $request = new \WP_REST_Request( 'OPTIONS', $this->routes[0] ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( count( array_keys( $this->properties ) ), count( $properties ), print_r( array_diff( array_keys( $properties ), array_keys( $this->properties ) ), true ) ); - - foreach ( array_keys( $this->properties ) as $property ) { - $this->assertArrayHasKey( $property, $properties ); - } - } - - /** - * Test creation using this method. - * If read-only, test to confirm this. - */ - abstract public function test_create(); - - /** - * Test get/read using this method. - */ - abstract public function test_read(); - - /** - * Test updates using this method. - * If read-only, test to confirm this. - */ - abstract public function test_update(); - - /** - * Test delete using this method. - * If read-only, test to confirm this. - */ - abstract public function test_delete(); - - /** - * Perform a request and return the status and returned data. - * - * @param string $endpoint Endpoint to hit. - * @param string $type Type of request e.g GET or POST. - * @param array $params Request body or query. - * @return object - */ - protected function do_request( $endpoint, $type = 'GET', $params = [] ) { - $request = new \WP_REST_Request( $type, untrailingslashit( $endpoint ) ); - 'GET' === $type ? $request->set_query_params( $params ) : $request->set_body_params( $params ); - $response = $this->server->dispatch( $request ); - - return (object) array( - 'status' => $response->get_status(), - 'data' => json_decode( wp_json_encode( $response->get_data() ), true ), - 'raw' => $response->get_data(), - ); - } - - /** - * Test the request/response matched the data we sent. - * - * @param array $response Array of response data from do_request above. - * @param int $status_code Expected status code. - * @param array $data Array of expected data. - */ - protected function assertExpectedResponse( $response, $status_code = 200, $data = array() ) { - $this->assertObjectHasAttribute( 'status', $response ); - $this->assertObjectHasAttribute( 'data', $response ); - $this->assertEquals( $status_code, $response->status, print_r( $response->data, true ) ); - - if ( $data ) { - foreach ( $data as $key => $value ) { - if ( ! isset( $response->data[ $key ] ) ) { - continue; - } - switch ( $key ) { - case 'meta_data': - $this->assertMetaData( $value, $response->data[ $key ] ); - break; - default: - if ( is_array( $value ) ) { - $this->assertArraySubset( $value, $response->data[ $key ] ); - } else { - $this->assertEquals( $value, $response->data[ $key ] ); - } - } - } - } - } - - /** - * Test meta data in a response matches what we expect. - * - * @param array $expected_meta_data Array of data. - * @param array $actual_meta_data Array of data. - */ - protected function assertMetaData( $expected_meta_data, $actual_meta_data ) { - $this->assertTrue( is_array( $actual_meta_data ) ); - $this->assertEquals( count( $expected_meta_data ), count( $actual_meta_data ) ); - - foreach ( $actual_meta_data as $key => $meta ) { - $this->assertArrayHasKey( 'id', $meta ); - $this->assertArrayHasKey( 'key', $meta ); - $this->assertArrayHasKey( 'value', $meta ); - $this->assertEquals( $expected_meta_data[ $key ]['key'], $meta['key'] ); - $this->assertEquals( $expected_meta_data[ $key ]['value'], $meta['value'] ); - } - } - - /** - * Return array of properties for a given context. - * - * @param string $context Context to use. - * @return array - */ - protected function get_properties( $context = 'edit' ) { - return array_keys( array_filter( $this->properties, function( $contexts ) use( $context ) { - return in_array( $context, $contexts ); - } ) ); - } -} diff --git a/unit-tests/Bootstrap.php b/unit-tests/Bootstrap.php deleted file mode 100755 index b10c7f8eae5..00000000000 --- a/unit-tests/Bootstrap.php +++ /dev/null @@ -1,134 +0,0 @@ -wp_tests_dir = getenv( 'WP_TESTS_DIR' ) ? getenv( 'WP_TESTS_DIR' ) : rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib'; - $this->tests_dir = dirname( __FILE__ ); - $this->plugin_dir = dirname( $this->tests_dir ); - - if ( file_exists( dirname( $this->plugin_dir ) . '/woocommerce/woocommerce.php' ) ) { - // From plugin directory. - $this->plugins_dir = dirname( $this->plugin_dir ); - } else { - // Travis. - $this->plugins_dir = getenv( 'WP_CORE_DIR' ) . '/wp-content/plugins'; - } - - $this->wc_tests_dir = $this->plugins_dir . '/woocommerce/tests'; - - $this->setup_hooks(); - $this->load_framework(); - } - - /** - * Get tests dir. - * - * @return string - */ - public function get_dir() { - return dirname( __FILE__ ); - } - - /** - * Setup hooks. - */ - protected function setup_hooks() { - // Give access to tests_add_filter() function. - require_once $this->wp_tests_dir . '/includes/functions.php'; - - \tests_add_filter( 'muplugins_loaded', function() { - require_once $this->plugins_dir . '/woocommerce/woocommerce.php'; - require_once $this->plugin_dir . '/woocommerce-rest-api.php'; - } ); - - \tests_add_filter( 'setup_theme', function() { - echo \esc_html( 'Installing WooCommerce...' . PHP_EOL ); - - define( 'WP_UNINSTALL_PLUGIN', true ); - define( 'WC_REMOVE_ALL_DATA', true ); - include $this->plugins_dir . '/woocommerce/uninstall.php'; - - \WC_Install::install(); - - $GLOBALS['wp_roles'] = null; // WPCS: override ok. - \wp_roles(); - } ); - } - - /** - * Load the testing framework. - */ - protected function load_framework() { - // Start up the WP testing environment. - require_once $this->wp_tests_dir . '/includes/bootstrap.php'; - - // WooCommerce Core Testing Framework. - require_once $this->wc_tests_dir . '/legacy/framework/class-wc-unit-test-factory.php'; - require_once $this->wc_tests_dir . '/legacy/framework/vendor/class-wp-test-spy-rest-server.php'; - require_once $this->wc_tests_dir . '/legacy/includes/wp-http-testcase.php'; - require_once $this->wc_tests_dir . '/legacy/framework/class-wc-unit-test-case.php'; - require_once $this->wc_tests_dir . '/legacy/framework/class-wc-rest-unit-test-case.php'; - - require_once $this->tests_dir . '/Helpers/AdminNotesHelper.php'; - require_once $this->tests_dir . '/Helpers/CouponHelper.php'; - require_once $this->tests_dir . '/Helpers/CustomerHelper.php'; - require_once $this->tests_dir . '/Helpers/OrderHelper.php'; - require_once $this->tests_dir . '/Helpers/ProductHelper.php'; - require_once $this->tests_dir . '/Helpers/ShippingHelper.php'; - require_once $this->tests_dir . '/Helpers/SettingsHelper.php'; - require_once $this->tests_dir . '/Helpers/QueueHelper.php'; - require_once $this->tests_dir . '/AbstractRestApiTest.php'; - } -} - -Bootstrap::instance()->init(); diff --git a/unit-tests/Helpers/AdminNotesHelper.php b/unit-tests/Helpers/AdminNotesHelper.php deleted file mode 100644 index de1c6c9da13..00000000000 --- a/unit-tests/Helpers/AdminNotesHelper.php +++ /dev/null @@ -1,83 +0,0 @@ -query( "TRUNCATE TABLE {$wpdb->prefix}wc_admin_notes" ); // @codingStandardsIgnoreLine. - $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}wc_admin_note_actions" ); // @codingStandardsIgnoreLine. - } - - /** - * Create two notes that we can use for notes REST API tests - */ - public static function add_notes_for_tests() { - $data_store = WC_Data_Store::load( 'admin-note' ); - - $note_1 = new WC_Admin_Note(); - $note_1->set_title( 'PHPUNIT_TEST_NOTE_1_TITLE' ); - $note_1->set_content( 'PHPUNIT_TEST_NOTE_1_CONTENT' ); - $note_1->set_content_data( (object) array( 'amount' => 1.23 ) ); - $note_1->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL ); - $note_1->set_icon( 'info' ); - $note_1->set_name( 'PHPUNIT_TEST_NOTE_NAME' ); - $note_1->set_source( 'PHPUNIT_TEST' ); - $note_1->add_action( - 'PHPUNIT_TEST_NOTE_1_ACTION_1_SLUG', - 'PHPUNIT_TEST_NOTE_1_ACTION_1_LABEL', - '?s=PHPUNIT_TEST_NOTE_1_ACTION_1_URL' - ); - $note_1->add_action( - 'PHPUNIT_TEST_NOTE_1_ACTION_2_SLUG', - 'PHPUNIT_TEST_NOTE_1_ACTION_2_LABEL', - '?s=PHPUNIT_TEST_NOTE_1_ACTION_2_URL' - ); - $note_1->save(); - - $note_2 = new WC_Admin_Note(); - $note_2->set_title( 'PHPUNIT_TEST_NOTE_2_TITLE' ); - $note_2->set_content( 'PHPUNIT_TEST_NOTE_2_CONTENT' ); - $note_2->set_content_data( (object) array( 'amount' => 4.56 ) ); - $note_2->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_WARNING ); - $note_2->set_icon( 'info' ); - $note_2->set_name( 'PHPUNIT_TEST_NOTE_NAME' ); - $note_2->set_source( 'PHPUNIT_TEST' ); - $note_2->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED ); - // This note has no actions. - $note_2->save(); - - $note_3 = new WC_Admin_Note(); - $note_3->set_title( 'PHPUNIT_TEST_NOTE_3_TITLE' ); - $note_3->set_content( 'PHPUNIT_TEST_NOTE_3_CONTENT' ); - $note_3->set_content_data( (object) array( 'amount' => 7.89 ) ); - $note_3->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL ); - $note_3->set_icon( 'info' ); - $note_3->set_name( 'PHPUNIT_TEST_NOTE_NAME' ); - $note_3->set_source( 'PHPUNIT_TEST' ); - $note_3->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_SNOOZED ); - $note_3->set_date_reminder( time() - HOUR_IN_SECONDS ); - // This note has no actions. - $note_3->save(); - - } -} diff --git a/unit-tests/Helpers/CouponHelper.php b/unit-tests/Helpers/CouponHelper.php deleted file mode 100644 index 2b65987bff5..00000000000 --- a/unit-tests/Helpers/CouponHelper.php +++ /dev/null @@ -1,147 +0,0 @@ - $coupon_code, - 'post_type' => 'shop_coupon', - 'post_status' => 'publish', - 'post_excerpt' => 'This is a dummy coupon', - ) - ); - - $meta = wp_parse_args( - $meta, - array( - 'discount_type' => 'fixed_cart', - 'coupon_amount' => '1', - 'individual_use' => 'no', - 'product_ids' => '', - 'exclude_product_ids' => '', - 'usage_limit' => '', - 'usage_limit_per_user' => '', - 'limit_usage_to_x_items' => '', - 'expiry_date' => '', - 'free_shipping' => 'no', - 'exclude_sale_items' => 'no', - 'product_categories' => array(), - 'exclude_product_categories' => array(), - 'minimum_amount' => '', - 'maximum_amount' => '', - 'customer_email' => array(), - 'usage_count' => '0', - ) - ); - - // Update meta. - foreach ( $meta as $key => $value ) { - update_post_meta( $coupon_id, $key, $value ); - } - - return new WC_Coupon( $coupon_code ); - } - - /** - * Delete a coupon. - * - * @param $coupon_id - * - * @return bool - */ - public static function delete_coupon( $coupon_id ) { - wp_delete_post( $coupon_id, true ); - - return true; - } - - /** - * Register a custom coupon type. - * - * @param string $coupon_type - */ - public static function register_custom_type( $coupon_type ) { - static $filters_added = false; - if ( isset( self::$custom_types[ $coupon_type ] ) ) { - return; - } - - self::$custom_types[ $coupon_type ] = "Testing custom type {$coupon_type}"; - - if ( ! $filters_added ) { - add_filter( 'woocommerce_coupon_discount_types', array( __CLASS__, 'filter_discount_types' ) ); - add_filter( 'woocommerce_coupon_get_discount_amount', array( __CLASS__, 'filter_get_discount_amount' ), 10, 5 ); - add_filter( 'woocommerce_coupon_is_valid_for_product', '__return_true' ); - $filters_added = true; - } - } - - /** - * Unregister custom coupon type. - * - * @param $coupon_type - */ - public static function unregister_custom_type( $coupon_type ) { - unset( self::$custom_types[ $coupon_type ] ); - if ( empty( self::$custom_types ) ) { - remove_filter( 'woocommerce_coupon_discount_types', array( __CLASS__, 'filter_discount_types' ) ); - remove_filter( 'woocommerce_coupon_get_discount_amount', array( __CLASS__, 'filter_get_discount_amount' ) ); - remove_filter( 'woocommerce_coupon_is_valid_for_product', '__return_true' ); - } - } - - /** - * Register custom discount types. - * - * @param array $discount_types - * @return array - */ - public static function filter_discount_types( $discount_types ) { - return array_merge( $discount_types, self::$custom_types ); - } - - /** - * Get custom discount type amount. Works like 'percent' type. - * - * @param float $discount - * @param float $discounting_amount - * @param array|null $item - * @param bool $single - * @param WC_Coupon $coupon - * - * @return float - */ - public static function filter_get_discount_amount( $discount, $discounting_amount, $item, $single, $coupon ) { - if ( ! isset( self::$custom_types [ $coupon->get_discount_type() ] ) ) { - return $discount; - } - - return (float) $coupon->get_amount() * ( $discounting_amount / 100 ); - } -} diff --git a/unit-tests/Helpers/CustomerHelper.php b/unit-tests/Helpers/CustomerHelper.php deleted file mode 100644 index 5751cf31f32..00000000000 --- a/unit-tests/Helpers/CustomerHelper.php +++ /dev/null @@ -1,138 +0,0 @@ - 0, - 'date_modified' => null, - 'country' => 'US', - 'state' => 'PA', - 'postcode' => '19123', - 'city' => 'Philadelphia', - 'address' => '123 South Street', - 'address_2' => 'Apt 1', - 'shipping_country' => 'US', - 'shipping_state' => 'PA', - 'shipping_postcode' => '19123', - 'shipping_city' => 'Philadelphia', - 'shipping_address' => '123 South Street', - 'shipping_address_2' => 'Apt 1', - 'is_vat_exempt' => false, - 'calculated_shipping' => false, - ); - - self::set_customer_details( $customer_data ); - - $customer = new WC_Customer( 0, true ); - - return $customer; - } - - /** - * Creates a customer in the tests DB. - */ - public static function create_customer( $username = 'testcustomer', $password = 'hunter2', $email = 'test@woo.local' ) { - $customer = new WC_Customer(); - $customer->set_billing_country( 'US' ); - $customer->set_first_name( 'Justin' ); - $customer->set_billing_state( 'PA' ); - $customer->set_billing_postcode( '19123' ); - $customer->set_billing_city( 'Philadelphia' ); - $customer->set_billing_address( '123 South Street' ); - $customer->set_billing_address_2( 'Apt 1' ); - $customer->set_shipping_country( 'US' ); - $customer->set_shipping_state( 'PA' ); - $customer->set_shipping_postcode( '19123' ); - $customer->set_shipping_city( 'Philadelphia' ); - $customer->set_shipping_address( '123 South Street' ); - $customer->set_shipping_address_2( 'Apt 1' ); - $customer->set_username( $username ); - $customer->set_password( $password ); - $customer->set_email( $email ); - $customer->save(); - return $customer; - } - - /** - * Get the expected output for the store's base location settings. - * - * @return array - */ - public static function get_expected_store_location() { - return array( 'GB', '', '', '' ); - } - - /** - * Get the customer's shipping and billing info from the session. - * - * @return array - */ - public static function get_customer_details() { - return WC()->session->get( 'customer' ); - } - - /** - * Get the user's chosen shipping method. - * - * @return array - */ - public static function get_chosen_shipping_methods() { - return WC()->session->get( 'chosen_shipping_methods' ); - } - - /** - * Get the "Tax Based On" WooCommerce option. - * - * @return string base or billing - */ - public static function get_tax_based_on() { - return get_option( 'woocommerce_tax_based_on' ); - } - - /** - * Set the the current customer's billing details in the session. - * - * @param string $default_shipping_method Shipping Method slug - */ - public static function set_customer_details( $customer_details ) { - WC()->session->set( 'customer', array_map( 'strval', $customer_details ) ); - } - - /** - * Set the user's chosen shipping method. - * - * @param string $chosen_shipping_method Shipping Method slug - */ - public static function set_chosen_shipping_methods( $chosen_shipping_methods ) { - WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods ); - } - - /** - * Set the "Tax Based On" WooCommerce option. - * - * @param string $default_shipping_method Shipping Method slug - */ - public static function set_tax_based_on( $default_shipping_method ) { - update_option( 'woocommerce_tax_based_on', $default_shipping_method ); - } -} diff --git a/unit-tests/Helpers/OrderHelper.php b/unit-tests/Helpers/OrderHelper.php deleted file mode 100644 index 59f72d1dcb2..00000000000 --- a/unit-tests/Helpers/OrderHelper.php +++ /dev/null @@ -1,129 +0,0 @@ -get_items() as $item ) { - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::delete_product( $item['product_id'] ); - } - - ShippingHelper::delete_simple_flat_rate(); - - // Delete the order post. - $order->delete( true ); - } - - /** - * Create a order. - * - * @since 2.4 - * @version 3.0 New parameter $product. - * - * @param int $customer_id - * @param WC_Product $product - * - * @return WC_Order - */ - public static function create_order( $customer_id = 1, $product = null ) { - - if ( ! is_a( $product, 'WC_Product' ) ) { - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - } - - ShippingHelper::create_simple_flat_rate(); - - $order_data = array( - 'status' => 'pending', - 'customer_id' => $customer_id, - 'customer_note' => '', - 'total' => '', - ); - - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // Required, else wc_create_order throws an exception - $order = wc_create_order( $order_data ); - - // Add order products - $item = new WC_Order_Item_Product(); - $item->set_props( - array( - 'product' => $product, - 'quantity' => 4, - 'subtotal' => wc_get_price_excluding_tax( $product, array( 'qty' => 4 ) ), - 'total' => wc_get_price_excluding_tax( $product, array( 'qty' => 4 ) ), - ) - ); - $item->save(); - $order->add_item( $item ); - - // Set billing address - $order->set_billing_first_name( 'Jeroen' ); - $order->set_billing_last_name( 'Sormani' ); - $order->set_billing_company( 'WooCompany' ); - $order->set_billing_address_1( 'WooAddress' ); - $order->set_billing_address_2( '' ); - $order->set_billing_city( 'WooCity' ); - $order->set_billing_state( 'NY' ); - $order->set_billing_postcode( '123456' ); - $order->set_billing_country( 'US' ); - $order->set_billing_email( 'admin@example.org' ); - $order->set_billing_phone( '555-32123' ); - - // Add shipping costs - $shipping_taxes = WC_Tax::calc_shipping_tax( '10', WC_Tax::get_shipping_tax_rates() ); - $rate = new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', $shipping_taxes, 'flat_rate' ); - $item = new WC_Order_Item_Shipping(); - $item->set_props( - array( - 'method_title' => $rate->label, - 'method_id' => $rate->id, - 'total' => wc_format_decimal( $rate->cost ), - 'taxes' => $rate->taxes, - ) - ); - foreach ( $rate->get_meta_data() as $key => $value ) { - $item->add_meta_data( $key, $value, true ); - } - $order->add_item( $item ); - - // Set payment gateway - $payment_gateways = WC()->payment_gateways->payment_gateways(); - $order->set_payment_method( $payment_gateways['bacs'] ); - - // Set totals - $order->set_shipping_total( 10 ); - $order->set_discount_total( 0 ); - $order->set_discount_tax( 0 ); - $order->set_cart_tax( 0 ); - $order->set_shipping_tax( 0 ); - $order->set_total( 50 ); // 4 x $10 simple helper product - $order->save(); - - return $order; - } -} diff --git a/unit-tests/Helpers/ProductHelper.php b/unit-tests/Helpers/ProductHelper.php deleted file mode 100644 index 78d4333610e..00000000000 --- a/unit-tests/Helpers/ProductHelper.php +++ /dev/null @@ -1,310 +0,0 @@ -delete( true ); - } - } - - /** - * Create simple product. - * - * @since 2.3 - * @param bool $save Save or return object. - * @return WC_Product_Simple - */ - public static function create_simple_product( $save = true ) { - $product = new WC_Product_Simple(); - $product->set_props( - array( - 'name' => 'Dummy Product', - 'regular_price' => 10, - 'price' => 10, - 'sku' => 'DUMMY SKU', - 'manage_stock' => false, - 'tax_status' => 'taxable', - 'downloadable' => false, - 'virtual' => false, - 'stock_status' => 'instock', - 'weight' => '1.1', - ) - ); - - if ( $save ) { - $product->save(); - return \wc_get_product( $product->get_id() ); - } else { - return $product; - } - } - - /** - * Create external product. - * - * @since 3.0.0 - * @return WC_Product_External - */ - public static function create_external_product() { - $product = new WC_Product_External(); - $product->set_props( - array( - 'name' => 'Dummy External Product', - 'regular_price' => 10, - 'sku' => 'DUMMY EXTERNAL SKU', - 'product_url' => 'http://woocommerce.com', - 'button_text' => 'Buy external product', - ) - ); - $product->save(); - - return \wc_get_product( $product->get_id() ); - } - - /** - * Create grouped product. - * - * @since 3.0.0 - * @return WC_Product_Grouped - */ - public static function create_grouped_product() { - $simple_product_1 = self::create_simple_product(); - $simple_product_2 = self::create_simple_product(); - $product = new WC_Product_Grouped(); - $product->set_props( - array( - 'name' => 'Dummy Grouped Product', - 'sku' => 'DUMMY GROUPED SKU', - ) - ); - $product->set_children( array( $simple_product_1->get_id(), $simple_product_2->get_id() ) ); - $product->save(); - - return \wc_get_product( $product->get_id() ); - } - - /** - * Create a dummy variation product. - * - * @since 2.3 - * - * @return WC_Product_Variable - */ - public static function create_variation_product() { - $product = new WC_Product_Variable(); - $product->set_props( - array( - 'name' => 'Dummy Variable Product', - 'sku' => 'DUMMY VARIABLE SKU', - ) - ); - - $attribute_data = self::create_attribute( 'size', array( 'small', 'large' ) ); // Create all attribute related things. - $attributes = array(); - $attribute = new WC_Product_Attribute(); - $attribute->set_id( $attribute_data['attribute_id'] ); - $attribute->set_name( $attribute_data['attribute_taxonomy'] ); - $attribute->set_options( $attribute_data['term_ids'] ); - $attribute->set_position( 1 ); - $attribute->set_visible( true ); - $attribute->set_variation( true ); - $attributes[] = $attribute; - - $product->set_attributes( $attributes ); - $product->save(); - - $variation_1 = new WC_Product_Variation(); - $variation_1->set_props( - array( - 'parent_id' => $product->get_id(), - 'sku' => 'DUMMY SKU VARIABLE SMALL', - 'regular_price' => 10, - ) - ); - $variation_1->set_attributes( array( 'pa_size' => 'small' ) ); - $variation_1->save(); - - $variation_2 = new WC_Product_Variation(); - $variation_2->set_props( - array( - 'parent_id' => $product->get_id(), - 'sku' => 'DUMMY SKU VARIABLE LARGE', - 'regular_price' => 15, - ) - ); - $variation_2->set_attributes( array( 'pa_size' => 'large' ) ); - $variation_2->save(); - - return \wc_get_product( $product->get_id() ); - } - - /** - * Create a dummy attribute. - * - * @since 2.3 - * - * @param string $raw_name Name of attribute to create. - * @param array(string) $terms Terms to create for the attribute. - * @return array - */ - public static function create_attribute( $raw_name = 'size', $terms = array( 'small' ) ) { - global $wpdb, $wc_product_attributes; - - // Make sure caches are clean. - \delete_transient( 'wc_attribute_taxonomies' ); - if ( method_exists( '\WC_Cache_Helper', 'invalidate_cache_group' ) ) { - \WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); - } else { - \WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' ); - } - - // These are exported as labels, so convert the label to a name if possible first. - $attribute_labels = \wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name' ); - $attribute_name = \array_search( $raw_name, $attribute_labels, true ); - - if ( ! $attribute_name ) { - $attribute_name = \wc_sanitize_taxonomy_name( $raw_name ); - } - - $attribute_id = \wc_attribute_taxonomy_id_by_name( $attribute_name ); - - if ( ! $attribute_id ) { - $taxonomy_name = \wc_attribute_taxonomy_name( $attribute_name ); - - // Degister taxonomy which other tests may have created... - \unregister_taxonomy( $taxonomy_name ); - - $attribute_id = \wc_create_attribute( - array( - 'name' => $raw_name, - 'slug' => $attribute_name, - 'type' => 'select', - 'order_by' => 'menu_order', - 'has_archives' => 0, - ) - ); - - // Register as taxonomy. - \register_taxonomy( - $taxonomy_name, - apply_filters( 'woocommerce_taxonomy_objects_' . $taxonomy_name, array( 'product' ) ), - apply_filters( - 'woocommerce_taxonomy_args_' . $taxonomy_name, - array( - 'labels' => array( - 'name' => $raw_name, - ), - 'hierarchical' => false, - 'show_ui' => false, - 'query_var' => true, - 'rewrite' => false, - ) - ) - ); - - // Set product attributes global. - $wc_product_attributes = array(); - - foreach ( \wc_get_attribute_taxonomies() as $taxonomy ) { - $wc_product_attributes[ \wc_attribute_taxonomy_name( $taxonomy->attribute_name ) ] = $taxonomy; - } - } - - $attribute = \wc_get_attribute( $attribute_id ); - $return = array( - 'attribute_name' => $attribute->name, - 'attribute_taxonomy' => $attribute->slug, - 'attribute_id' => $attribute_id, - 'term_ids' => array(), - ); - - foreach ( $terms as $term ) { - $result = \term_exists( $term, $attribute->slug ); - - if ( ! $result ) { - $result = wp_insert_term( $term, $attribute->slug ); - $return['term_ids'][] = $result['term_id']; - } else { - $return['term_ids'][] = $result['term_id']; - } - } - - return $return; - } - - /** - * Delete an attribute. - * - * @param int $attribute_id ID to delete. - * - * @since 2.3 - */ - public static function delete_attribute( $attribute_id ) { - global $wpdb; - - $attribute_id = \absint( $attribute_id ); - - $wpdb->query( - $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = %d", $attribute_id ) - ); - } - - /** - * Creates a new product review on a specific product. - * - * @since 3.0 - * @param int $product_id integer Product ID that the review is for. - * @param string $review_content string Content to use for the product review. - * @return integer Product Review ID. - */ - public static function create_product_review( $product_id, $review_content = 'Review content here' ) { - $data = array( - 'comment_post_ID' => $product_id, - 'comment_author' => 'admin', - 'comment_author_email' => 'woo@woo.local', - 'comment_author_url' => '', - 'comment_date' => '2016-01-01T11:11:11', - 'comment_content' => $review_content, - 'comment_approved' => 1, - 'comment_type' => 'review', - ); - return \wp_insert_comment( $data ); - } - - /** - * A helper function for hooking into save_post during the test_product_meta_save_post test. - * @since 3.0.1 - * - * @param int $id ID to update. - */ - public static function save_post_test_update_meta_data_direct( $id ) { - \update_post_meta( $id, '_test2', 'world' ); - } -} diff --git a/unit-tests/Helpers/QueueHelper.php b/unit-tests/Helpers/QueueHelper.php deleted file mode 100644 index b0afec4c6fd..00000000000 --- a/unit-tests/Helpers/QueueHelper.php +++ /dev/null @@ -1,62 +0,0 @@ -queue()->search( - array( - 'per_page' => -1, - 'status' => 'pending', - 'claimed' => false, - ) - ); - - return $jobs; - } - - /** - * Run all pending queued actions. - * - * @return void - */ - public static function run_all_pending() { - $jobs = self::get_all_pending(); - - foreach ( $jobs as $job ) { - $job->execute(); - } - } - - /** - * Run all pending queued actions. - * - * @return void - */ - public static function process_pending() { - $jobs = self::get_all_pending(); - - $queue_runner = new \ActionScheduler_QueueRunner(); - foreach ( $jobs as $job_id => $job ) { - $queue_runner->process_action( $job_id ); - } - } -} diff --git a/unit-tests/Helpers/SettingsHelper.php b/unit-tests/Helpers/SettingsHelper.php deleted file mode 100644 index d7a8efd979d..00000000000 --- a/unit-tests/Helpers/SettingsHelper.php +++ /dev/null @@ -1,82 +0,0 @@ - 'test', - 'bad' => 'value', - 'label' => 'Test extension', - 'description' => 'My awesome test settings.', - 'option_key' => '', - ); - $groups[] = array( - 'id' => 'sub-test', - 'parent_id' => 'test', - 'label' => 'Sub test', - 'description' => '', - 'option_key' => '', - ); - $groups[] = array( - 'id' => 'coupon-data', - 'label' => 'Coupon data', - 'option_key' => '', - ); - $groups[] = array( - 'id' => 'invalid', - 'option_key' => '', - ); - return $groups; - } - - /** - * Registers some example settings. - * - * @since 3.0.0 - * @param array $settings - * @return array - */ - public static function register_test_settings( $settings ) { - $settings[] = array( - 'id' => 'woocommerce_shop_page_display', - 'label' => 'Shop page display', - 'description' => 'This controls what is shown on the product archive.', - 'default' => '', - 'type' => 'select', - 'options' => array( - '' => 'Show products', - 'subcategories' => 'Show categories & subcategories', - 'both' => 'Show both', - ), - 'option_key' => 'woocommerce_shop_page_display', - ); - return $settings; - } -} diff --git a/unit-tests/Helpers/ShippingHelper.php b/unit-tests/Helpers/ShippingHelper.php deleted file mode 100644 index 04d17e4274c..00000000000 --- a/unit-tests/Helpers/ShippingHelper.php +++ /dev/null @@ -1,50 +0,0 @@ - 'yes', - 'title' => 'Flat rate', - 'availability' => 'all', - 'countries' => '', - 'tax_status' => 'taxable', - 'cost' => '10', - ); - - update_option( 'woocommerce_flat_rate_settings', $flat_rate_settings ); - update_option( 'woocommerce_flat_rate', array() ); - WC_Cache_Helper::get_transient_version( 'shipping', true ); - WC()->shipping()->load_shipping_methods(); - } - - /** - * Delete the simple flat rate. - * - * @since 2.3 - */ - public static function delete_simple_flat_rate() { - delete_option( 'woocommerce_flat_rate_settings' ); - delete_option( 'woocommerce_flat_rate' ); - WC_Cache_Helper::get_transient_version( 'shipping', true ); - WC()->shipping()->unregister_shipping_methods(); - } -} diff --git a/unit-tests/Tests/Version2/coupons.php b/unit-tests/Tests/Version2/coupons.php deleted file mode 100644 index 8c4d6024d70..00000000000 --- a/unit-tests/Tests/Version2/coupons.php +++ /dev/null @@ -1,471 +0,0 @@ -endpoint = new WC_REST_Coupons_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/coupons', $routes ); - $this->assertArrayHasKey( '/wc/v2/coupons/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v2/coupons/batch', $routes ); - } - - /** - * Test getting coupons. - * @since 3.0.0 - */ - public function test_get_coupons() { - wp_set_current_user( $this->user ); - - $coupon_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $post_1 = get_post( $coupon_1->get_id() ); - $coupon_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons' ) ); - $coupons = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $coupons ) ); - $this->assertContains( - array( - 'id' => $coupon_1->get_id(), - 'code' => 'dummycoupon-1', - 'amount' => '1.00', - 'date_created' => wc_rest_prepare_date_response( $post_1->post_date_gmt, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $post_1->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $post_1->post_modified_gmt, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $post_1->post_modified_gmt ), - 'discount_type' => 'fixed_cart', - 'description' => 'This is a dummy coupon', - 'date_expires' => '', - 'date_expires_gmt' => '', - 'usage_count' => 0, - 'individual_use' => false, - 'product_ids' => array(), - 'excluded_product_ids' => array(), - 'usage_limit' => '', - 'usage_limit_per_user' => '', - 'limit_usage_to_x_items' => null, - 'free_shipping' => false, - 'product_categories' => array(), - 'excluded_product_categories' => array(), - 'exclude_sale_items' => false, - 'minimum_amount' => '0.00', - 'maximum_amount' => '0.00', - 'email_restrictions' => array(), - 'used_by' => array(), - 'meta_data' => array(), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/coupons/' . $coupon_1->get_id() ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/coupons' ), - ), - ), - ), - ), - $coupons - ); - } - - /** - * Test getting coupons without valid permissions. - * @since 3.0.0 - */ - public function test_get_coupons_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single coupon. - * @since 3.0.0 - */ - public function test_get_coupon() { - wp_set_current_user( $this->user ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $post = get_post( $coupon->get_id() ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $coupon->get_id(), - 'code' => 'dummycoupon-1', - 'amount' => '1.00', - 'date_created' => wc_rest_prepare_date_response( $post->post_date_gmt, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $post->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $post->post_modified_gmt, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $post->post_modified_gmt ), - 'discount_type' => 'fixed_cart', - 'description' => 'This is a dummy coupon', - 'date_expires' => null, - 'date_expires_gmt' => null, - 'usage_count' => 0, - 'individual_use' => false, - 'product_ids' => array(), - 'excluded_product_ids' => array(), - 'usage_limit' => null, - 'usage_limit_per_user' => null, - 'limit_usage_to_x_items' => null, - 'free_shipping' => false, - 'product_categories' => array(), - 'excluded_product_categories' => array(), - 'exclude_sale_items' => false, - 'minimum_amount' => '0.00', - 'maximum_amount' => '0.00', - 'email_restrictions' => array(), - 'used_by' => array(), - 'meta_data' => array(), - ), - $data - ); - } - - /** - * Test getting a single coupon with an invalid ID. - * @since 3.0.0 - */ - public function test_get_coupon_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single coupon without valid permissions. - * @since 3.0.0 - */ - public function test_get_coupon_without_permission() { - wp_set_current_user( 0 ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test creating a single coupon. - * @since 3.0.0 - */ - public function test_create_coupon() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'POST', '/wc/v2/coupons' ); - $request->set_body_params( - array( - 'code' => 'test', - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - 'description' => 'Test', - 'usage_limit' => 10, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'code' => 'test', - 'amount' => '5.00', - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'discount_type' => 'fixed_product', - 'description' => 'Test', - 'date_expires' => null, - 'date_expires_gmt' => null, - 'usage_count' => 0, - 'individual_use' => false, - 'product_ids' => array(), - 'excluded_product_ids' => array(), - 'usage_limit' => 10, - 'usage_limit_per_user' => null, - 'limit_usage_to_x_items' => null, - 'free_shipping' => false, - 'product_categories' => array(), - 'excluded_product_categories' => array(), - 'exclude_sale_items' => false, - 'minimum_amount' => '0.00', - 'maximum_amount' => '0.00', - 'email_restrictions' => array(), - 'used_by' => array(), - 'meta_data' => array(), - ), - $data - ); - } - - /** - * Test creating a single coupon with invalid fields. - * @since 3.0.0 - */ - public function test_create_coupon_invalid_fields() { - wp_set_current_user( $this->user ); - - // test no code... - $request = new WP_REST_Request( 'POST', '/wc/v2/coupons' ); - $request->set_body_params( - array( - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating a single coupon without valid permissions. - * @since 3.0.0 - */ - public function test_create_coupon_without_permission() { - wp_set_current_user( 0 ); - - // test no code... - $request = new WP_REST_Request( 'POST', '/wc/v2/coupons' ); - $request->set_body_params( - array( - 'code' => 'fail', - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single coupon. - * @since 3.0.0 - */ - public function test_update_coupon() { - wp_set_current_user( $this->user ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $post = get_post( $coupon->get_id() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/coupons/' . $coupon->get_id() ) ); - $data = $response->get_data(); - $this->assertEquals( 'This is a dummy coupon', $data['description'] ); - $this->assertEquals( 'fixed_cart', $data['discount_type'] ); - $this->assertEquals( '1.00', $data['amount'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/coupons/' . $coupon->get_id() ); - $request->set_body_params( - array( - 'amount' => '10.00', - 'description' => 'New description', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '10.00', $data['amount'] ); - $this->assertEquals( 'New description', $data['description'] ); - $this->assertEquals( 'fixed_cart', $data['discount_type'] ); - } - - /** - * Test updating a single coupon with an invalid ID. - * @since 3.0.0 - */ - public function test_update_coupon_invalid_id() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/coupons/0' ); - $request->set_body_params( - array( - 'code' => 'tester', - 'amount' => '10.00', - 'description' => 'New description', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test updating a single coupon without valid permissions. - * @since 3.0.0 - */ - public function test_update_coupon_without_permission() { - wp_set_current_user( 0 ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $post = get_post( $coupon->get_id() ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/coupons/' . $coupon->get_id() ); - $request->set_body_params( - array( - 'amount' => '10.00', - 'description' => 'New description', - ) - ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single coupon. - * @since 3.0.0 - */ - public function test_delete_coupon() { - wp_set_current_user( $this->user ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/' . $coupon->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test deleting a single coupon with an invalid ID. - * @since 3.0.0 - */ - public function test_delete_coupon_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test deleting a single coupon without valid permissions. - * @since 3.0.0 - */ - public function test_delete_coupon_without_permission() { - wp_set_current_user( 0 ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/coupons/' . $coupon->get_id() ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch operations on coupons. - * @since 3.0.0 - */ - public function test_batch_coupon() { - wp_set_current_user( $this->user ); - - $coupon_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $coupon_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); - $coupon_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-3' ); - $coupon_4 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-4' ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/coupons/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $coupon_1->get_id(), - 'amount' => '5.15', - ), - ), - 'delete' => array( - $coupon_2->get_id(), - $coupon_3->get_id(), - ), - 'create' => array( - array( - 'code' => 'new-coupon', - 'amount' => '11.00', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '5.15', $data['update'][0]['amount'] ); - $this->assertEquals( '11.00', $data['create'][0]['amount'] ); - $this->assertEquals( 'new-coupon', $data['create'][0]['code'] ); - $this->assertEquals( $coupon_2->get_id(), $data['delete'][0]['id'] ); - $this->assertEquals( $coupon_3->get_id(), $data['delete'][1]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v2/coupons' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Test coupon schema. - * @since 3.0.0 - */ - public function test_coupon_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/coupons' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 27, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'code', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_created_gmt', $properties ); - $this->assertArrayHasKey( 'date_modified', $properties ); - $this->assertArrayHasKey( 'date_modified_gmt', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'discount_type', $properties ); - $this->assertArrayHasKey( 'amount', $properties ); - $this->assertArrayHasKey( 'date_expires', $properties ); - $this->assertArrayHasKey( 'date_expires_gmt', $properties ); - $this->assertArrayHasKey( 'usage_count', $properties ); - $this->assertArrayHasKey( 'individual_use', $properties ); - $this->assertArrayHasKey( 'product_ids', $properties ); - $this->assertArrayHasKey( 'excluded_product_ids', $properties ); - $this->assertArrayHasKey( 'usage_limit', $properties ); - $this->assertArrayHasKey( 'usage_limit_per_user', $properties ); - $this->assertArrayHasKey( 'limit_usage_to_x_items', $properties ); - $this->assertArrayHasKey( 'free_shipping', $properties ); - $this->assertArrayHasKey( 'product_categories', $properties ); - $this->assertArrayHasKey( 'excluded_product_categories', $properties ); - $this->assertArrayHasKey( 'exclude_sale_items', $properties ); - $this->assertArrayHasKey( 'minimum_amount', $properties ); - $this->assertArrayHasKey( 'maximum_amount', $properties ); - $this->assertArrayHasKey( 'email_restrictions', $properties ); - $this->assertArrayHasKey( 'used_by', $properties ); - } -} diff --git a/unit-tests/Tests/Version2/customers.php b/unit-tests/Tests/Version2/customers.php deleted file mode 100644 index f9a4d5acca1..00000000000 --- a/unit-tests/Tests/Version2/customers.php +++ /dev/null @@ -1,566 +0,0 @@ -endpoint = new WC_REST_Customers_Controller(); - } - - /** - * Test route registration. - * - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - - $this->assertArrayHasKey( '/wc/v2/customers', $routes ); - $this->assertArrayHasKey( '/wc/v2/customers/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v2/customers/batch', $routes ); - } - - /** - * Test getting customers. - * - * @since 3.0.0 - */ - public function test_get_customers() { - wp_set_current_user( 1 ); - - $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); - - $request = new WP_REST_Request( 'GET', '/wc/v2/customers' ); - $request->set_query_params( - array( - 'orderby' => 'id', - ) - ); - $response = $this->server->dispatch( $request ); - $customers = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $customers ) ); - - $this->assertContains( - array( - 'id' => $customer_1->get_id(), - 'date_created' => wc_rest_prepare_date_response( $customer_1->get_date_created(), false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $customer_1->get_date_created() ), - 'date_modified' => wc_rest_prepare_date_response( $customer_1->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_1->get_date_modified() ), - 'email' => 'test@woo.local', - 'first_name' => 'Justin', - 'last_name' => '', - 'role' => 'customer', - 'username' => 'testcustomer', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'orders_count' => 0, - 'total_spent' => '0.00', - 'avatar_url' => $customer_1->get_avatar_url(), - 'meta_data' => array(), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/customers/' . $customer_1->get_id() . '' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/customers' ), - ), - ), - ), - ), - $customers - ); - } - - /** - * Test getting customers without valid permissions. - * - * @since 3.0.0 - */ - public function test_get_customers_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test creating a new customer. - * - * @since 3.0.0 - */ - public function test_create_customer() { - wp_set_current_user( 1 ); - - // Test just the basics first.. - $request = new WP_REST_Request( 'POST', '/wc/v2/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test', - 'password' => 'test123', - 'email' => 'create_customer_test@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'create_customer_test@woo.local', - 'first_name' => '', - 'last_name' => '', - 'role' => 'customer', - 'username' => 'create_customer_test', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => '', - 'postcode' => '', - 'country' => '', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => '', - 'postcode' => '', - 'country' => '', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'orders_count' => 0, - 'total_spent' => '0.00', - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - - // Test extra data - $request = new WP_REST_Request( 'POST', '/wc/v2/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test2', - 'password' => 'test123', - 'email' => 'create_customer_test2@woo.local', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - 'billing' => array( - 'country' => 'US', - 'state' => 'WA', - ), - 'shipping' => array( - 'state' => 'CA', - 'country' => 'US', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'create_customer_test2@woo.local', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - 'role' => 'customer', - 'username' => 'create_customer_test2', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => 'WA', - 'postcode' => '', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => 'CA', - 'postcode' => '', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'orders_count' => 0, - 'total_spent' => '0.00', - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - - // Test without required field - $request = new WP_REST_Request( 'POST', '/wc/v2/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test3', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating customers without valid permissions. - * - * @since 3.0.0 - */ - public function test_create_customer_without_permission() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'POST', '/wc/v2/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test_without_permission', - 'password' => 'test123', - 'email' => 'create_customer_test_without_permission@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single customer. - * - * @since 3.0.0 - */ - public function test_get_customer() { - wp_set_current_user( 1 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'get_customer_test@woo.local', - 'first_name' => 'Justin', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'last_name' => '', - 'role' => 'customer', - 'username' => 'get_customer_test', - 'orders_count' => 0, - 'total_spent' => '0.00', - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - } - - /** - * Test getting a single customer without valid permissions. - * - * @since 3.0.0 - */ - public function test_get_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single customer with an invalid ID. - * - * @since 3.0.0 - */ - public function test_get_customer_invalid_id() { - wp_set_current_user( 1 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a customer. - * - * @since 3.0.0 - */ - public function test_update_customer() { - wp_set_current_user( 1 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); - $data = $response->get_data(); - $this->assertEquals( 'update_customer_test', $data['username'] ); - $this->assertEquals( 'update_customer_test@woo.local', $data['email'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/customers/' . $customer->get_id() ); - $request->set_body_params( - array( - 'email' => 'updated_email@woo.local', - 'first_name' => 'UpdatedTest', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'updated_email@woo.local', $data['email'] ); - $this->assertEquals( 'UpdatedTest', $data['first_name'] ); - } - - /** - * Test updating a customer without valid permissions. - * - * @since 3.0.0 - */ - public function test_update_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/' . $customer->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a customer with an invalid ID. - * - * @since 3.0.0 - */ - public function test_update_customer_invalid_id() { - wp_set_current_user( 1 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/customers/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - - /** - * Test deleting a customer. - * - * @since 3.0.0 - */ - public function test_delete_customer() { - wp_set_current_user( 1 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/' . $customer->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test deleting a customer with an invalid ID. - * - * @since 3.0.0 - */ - public function test_delete_customer_invalid_id() { - wp_set_current_user( 1 ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test deleting a customer without valid permissions. - * - * @since 3.0.0 - */ - public function test_delete_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/customers/' . $customer->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test customer batch endpoint. - * - * @since 3.0.0 - */ - public function test_batch_customer() { - wp_set_current_user( 1 ); - - $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); - $customer_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); - $customer_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); - $customer_4 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/customers/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $customer_1->get_id(), - 'last_name' => 'McTest', - ), - ), - 'delete' => array( - $customer_2->get_id(), - $customer_3->get_id(), - ), - 'create' => array( - array( - 'username' => 'newuser', - 'password' => 'test123', - 'email' => 'newuser@woo.local', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'McTest', $data['update'][0]['last_name'] ); - $this->assertEquals( 'newuser', $data['create'][0]['username'] ); - $this->assertEmpty( $data['create'][0]['last_name'] ); - $this->assertEquals( $customer_2->get_id(), $data['delete'][0]['id'] ); - $this->assertEquals( $customer_3->get_id(), $data['delete'][1]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v2/customers' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Test customer schema. - * - * @since 3.0.0 - */ - public function test_customer_schema() { - wp_set_current_user( 1 ); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/customers' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 18, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_created_gmt', $properties ); - $this->assertArrayHasKey( 'date_modified', $properties ); - $this->assertArrayHasKey( 'date_modified_gmt', $properties ); - $this->assertArrayHasKey( 'email', $properties ); - $this->assertArrayHasKey( 'first_name', $properties ); - $this->assertArrayHasKey( 'last_name', $properties ); - $this->assertArrayHasKey( 'role', $properties ); - $this->assertArrayHasKey( 'username', $properties ); - $this->assertArrayHasKey( 'password', $properties ); - $this->assertArrayHasKey( 'orders_count', $properties ); - $this->assertArrayHasKey( 'total_spent', $properties ); - $this->assertArrayHasKey( 'avatar_url', $properties ); - $this->assertArrayHasKey( 'billing', $properties ); - $this->assertArrayHasKey( 'first_name', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'last_name', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'company', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'address_1', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'address_2', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'city', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'state', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'postcode', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'country', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'email', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'phone', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'shipping', $properties ); - $this->assertArrayHasKey( 'first_name', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'last_name', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'company', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'address_1', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'address_2', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'city', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'state', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'postcode', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'country', $properties['shipping']['properties'] ); - } -} diff --git a/unit-tests/Tests/Version2/orders.php b/unit-tests/Tests/Version2/orders.php deleted file mode 100644 index e80fbab5fb8..00000000000 --- a/unit-tests/Tests/Version2/orders.php +++ /dev/null @@ -1,721 +0,0 @@ -endpoint = new WC_REST_Orders_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/orders', $routes ); - $this->assertArrayHasKey( '/wc/v2/orders/batch', $routes ); - $this->assertArrayHasKey( '/wc/v2/orders/(?P[\d]+)', $routes ); - } - - /** - * Test getting all orders. - * @since 3.0.0 - */ - public function test_get_items() { - wp_set_current_user( $this->user ); - - // Create 10 orders. - for ( $i = 0; $i < 10; $i++ ) { - $this->orders[] = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders' ) ); - $orders = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 10, count( $orders ) ); - } - - /** - * Tests to make sure orders cannot be viewed without valid permissions. - * - * @since 3.0.0 - */ - public function test_get_items_without_permission() { - wp_set_current_user( 0 ); - $this->orders[] = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a single order. - * @since 3.0.0 - */ - public function test_get_item() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order->add_meta_data( 'key', 'value' ); - $order->add_meta_data( 'key2', 'value2' ); - $order->save(); - $this->orders[] = $order; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $order->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $order->get_id(), $data['id'] ); - - // Test meta data is set. - $this->assertEquals( 'key', $data['meta_data'][0]->key ); - $this->assertEquals( 'value', $data['meta_data'][0]->value ); - $this->assertEquals( 'key2', $data['meta_data'][1]->key ); - $this->assertEquals( 'value2', $data['meta_data'][1]->value ); - } - - /** - * Tests getting a single order without the correct permissions. - * @since 3.0.0 - */ - public function test_get_item_without_permission() { - wp_set_current_user( 0 ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $this->orders[] = $order; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $order->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting an order with an invalid ID. - * @since 3.0.0 - */ - public function test_get_item_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/99999999' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests getting an order with an invalid ID. - * @since 3.5.0 - */ - public function test_get_item_refund_id() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $refund = wc_create_refund( - array( - 'order_id' => $order->get_id(), - ) - ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/orders/' . $refund->get_id() ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests creating an order. - * @since 3.0.0 - */ - public function test_create_order() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); - $request->set_body_params( - array( - 'payment_method' => 'bacs', - 'payment_method_title' => 'Direct Bank Transfer', - 'set_paid' => true, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => '10.00', - 'instance_id' => '1', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $order = wc_get_order( $data['id'] ); - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); - $this->assertEquals( $order->get_payment_method_title(), $data['payment_method_title'] ); - $this->assertEquals( $order->get_billing_first_name(), $data['billing']['first_name'] ); - $this->assertEquals( $order->get_billing_last_name(), $data['billing']['last_name'] ); - $this->assertEquals( '', $data['billing']['company'] ); - $this->assertEquals( $order->get_billing_address_1(), $data['billing']['address_1'] ); - $this->assertEquals( $order->get_billing_address_2(), $data['billing']['address_2'] ); - $this->assertEquals( $order->get_billing_city(), $data['billing']['city'] ); - $this->assertEquals( $order->get_billing_state(), $data['billing']['state'] ); - $this->assertEquals( $order->get_billing_postcode(), $data['billing']['postcode'] ); - $this->assertEquals( $order->get_billing_country(), $data['billing']['country'] ); - $this->assertEquals( $order->get_billing_email(), $data['billing']['email'] ); - $this->assertEquals( $order->get_billing_phone(), $data['billing']['phone'] ); - $this->assertEquals( $order->get_shipping_first_name(), $data['shipping']['first_name'] ); - $this->assertEquals( $order->get_shipping_last_name(), $data['shipping']['last_name'] ); - $this->assertEquals( '', $data['shipping']['company'] ); - $this->assertEquals( $order->get_shipping_address_1(), $data['shipping']['address_1'] ); - $this->assertEquals( $order->get_shipping_address_2(), $data['shipping']['address_2'] ); - $this->assertEquals( $order->get_shipping_city(), $data['shipping']['city'] ); - $this->assertEquals( $order->get_shipping_state(), $data['shipping']['state'] ); - $this->assertEquals( $order->get_shipping_postcode(), $data['shipping']['postcode'] ); - $this->assertEquals( $order->get_shipping_country(), $data['shipping']['country'] ); - $this->assertEquals( 1, count( $data['line_items'] ) ); - $this->assertEquals( 1, count( $data['shipping_lines'] ) ); - $shipping = current( $order->get_items( 'shipping' ) ); - $expected = array( - 'id' => $shipping->get_id(), - 'method_title' => $shipping->get_method_title(), - 'method_id' => $shipping->get_method_id(), - 'instance_id' => $shipping->get_instance_id(), - 'total' => wc_format_decimal( $shipping->get_total(), '' ), - 'total_tax' => wc_format_decimal( $shipping->get_total_tax(), '' ), - 'taxes' => array(), - 'meta_data' => $shipping->get_meta_data(), - ); - $this->assertEquals( $expected, $data['shipping_lines'][0] ); - } - - /** - * Test the sanitization of the payment_method_title field through the API. - * - * @since 3.5.2 - */ - public function test_create_update_order_payment_method_title_sanitize() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - // Test when creating order. - $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); - $request->set_body_params( - array( - 'payment_method' => 'bacs', - 'payment_method_title' => '

Sanitize this

', - 'set_paid' => true, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => '10', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $order = wc_get_order( $data['id'] ); - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); - $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this' ); - - // Test when updating order. - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $data['id'] ); - $request->set_body_params( - array( - 'payment_method' => 'bacs', - 'payment_method_title' => '

Sanitize this too

', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $order = wc_get_order( $data['id'] ); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); - $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this too' ); - } - - /** - * Tests creating an order without required fields. - * @since 3.0.0 - */ - public function test_create_order_invalid_fields() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - // non-existent customer - $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); - $request->set_body_params( - array( - 'payment_method' => 'bacs', - 'payment_method_title' => 'Direct Bank Transfer', - 'set_paid' => true, - 'customer_id' => 99999, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => 10, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Tests create an order with an invalid product. - * - * @since 3.9.0 - */ - public function test_create_order_with_invalid_product() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/orders' ); - $request->set_body_params( - array( - 'line_items' => array( - array( - 'quantity' => 2, - ), - ), - ) - ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 'woocommerce_rest_required_product_reference', $data['code'] ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Tests updating an order. - * - * @since 3.0.0 - */ - public function test_update_order() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); - $request->set_body_params( - array( - 'payment_method' => 'test-update', - 'billing' => array( - 'first_name' => 'Fish', - 'last_name' => 'Face', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'test-update', $data['payment_method'] ); - $this->assertEquals( 'Fish', $data['billing']['first_name'] ); - $this->assertEquals( 'Face', $data['billing']['last_name'] ); - } - - /** - * Tests updating an order and removing items. - * - * @since 3.0.0 - */ - public function test_update_order_remove_items() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $fee = new WC_Order_Item_Fee(); - $fee->set_props( - array( - 'name' => 'Some Fee', - 'tax_status' => 'taxable', - 'total' => '100', - 'tax_class' => '', - ) - ); - $order->add_item( $fee ); - $order->save(); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); - $fee_data = current( $order->get_items( 'fee' ) ); - - $request->set_body_params( - array( - 'fee_lines' => array( - array( - 'id' => $fee_data->get_id(), - 'name' => null, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertTrue( empty( $data['fee_lines'] ) ); - } - - /** - * Tests updating an order after deleting a product. - * - * @since 3.9.0 - */ - public function test_update_order_after_delete_product() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); - $product->delete( true ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); - $line_items = $order->get_items( 'line_item' ); - $item = current( $line_items ); - - $request->set_body_params( - array( - 'line_items' => array( - array( - 'id' => $item->get_id(), - 'quantity' => 10, - ), - ), - ) - ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $expected = array( - 'id' => $item->get_id(), - 'name' => 'Dummy Product', - 'product_id' => 0, - 'variation_id' => 0, - 'quantity' => 10, - 'tax_class' => '', - 'subtotal' => '40.00', - 'subtotal_tax' => '0.00', - 'total' => '40.00', - 'total_tax' => '0.00', - 'taxes' => array(), - 'meta_data' => array(), - 'sku' => null, - 'price' => 4, - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $expected, $data['line_items'][0] ); - } - - /** - * Tests updating an order and adding a coupon. - * - * @since 3.3.0 - */ - public function test_update_order_add_coupons() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order_item = current( $order->get_items() ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); - $coupon->set_amount( 5 ); - $coupon->save(); - $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); - $request->set_body_params( - array( - 'coupon_lines' => array( - array( - 'code' => 'fake-coupon', - 'discount_total' => '5', - 'discount_tax' => '0', - ), - ), - 'line_items' => array( - array( - 'id' => $order_item->get_id(), - 'product_id' => $order_item->get_product_id(), - 'total' => '35.00', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $data['coupon_lines'] ); - $this->assertEquals( '45.00', $data['total'] ); - } - - /** - * Tests updating an order and removing a coupon. - * - * @since 3.3.0 - */ - public function test_update_order_remove_coupons() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order_item = current( $order->get_items() ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); - $coupon->set_amount( 5 ); - $coupon->save(); - - $order->apply_coupon( $coupon ); - $order->save(); - - // Check that the coupon is applied. - $this->assertEquals( '45.00', $order->get_total() ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); - $coupon_data = current( $order->get_items( 'coupon' ) ); - - $request->set_body_params( - array( - 'coupon_lines' => array( - array( - 'id' => $coupon_data->get_id(), - 'code' => null, - ), - ), - 'line_items' => array( - array( - 'id' => $order_item->get_id(), - 'product_id' => $order_item->get_product_id(), - 'total' => '40.00', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertTrue( empty( $data['coupon_lines'] ) ); - $this->assertEquals( '50.00', $data['total'] ); - } - - /** - * Tests updating an order without the correct permissions. - * - * @since 3.0.0 - */ - public function test_update_order_without_permission() { - wp_set_current_user( 0 ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() ); - $request->set_body_params( - array( - 'payment_method' => 'test-update', - 'billing' => array( - 'first_name' => 'Fish', - 'last_name' => 'Face', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests that updating an order with an invalid id fails. - * @since 3.0.0 - */ - public function test_update_order_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'POST', '/wc/v2/orders/999999' ); - $request->set_body_params( - array( - 'payment_method' => 'test-update', - 'billing' => array( - 'first_name' => 'Fish', - 'last_name' => 'Face', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test deleting an order. - * @since 3.0.0 - */ - public function test_delete_order() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/' . $order->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( null, get_post( $order->get_id() ) ); - } - - /** - * Test deleting an order without permission/creds. - * @since 3.0.0 - */ - public function test_delete_order_without_permission() { - wp_set_current_user( 0 ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/' . $order->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting an order with an invalid id. - * - * @since 3.0.0 - */ - public function test_delete_order_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/orders/9999999' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test batch managing product reviews. - */ - public function test_orders_batch() { - wp_set_current_user( $this->user ); - - $order1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - - $request = new WP_REST_Request( 'POST', '/wc/v2/orders/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $order1->get_id(), - 'payment_method' => 'updated', - ), - ), - 'delete' => array( - $order2->get_id(), - $order3->get_id(), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'updated', $data['update'][0]['payment_method'] ); - $this->assertEquals( $order2->get_id(), $data['delete'][0]['id'] ); - $this->assertEquals( $order3->get_id(), $data['delete'][1]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v2/orders' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 1, count( $data ) ); - } - - /** - * Test the order schema. - * @since 3.0.0 - */ - public function test_order_schema() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/orders/' . $order->get_id() ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 42, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - } -} diff --git a/unit-tests/Tests/Version2/payment-gateways.php b/unit-tests/Tests/Version2/payment-gateways.php deleted file mode 100644 index d8757c5d31d..00000000000 --- a/unit-tests/Tests/Version2/payment-gateways.php +++ /dev/null @@ -1,337 +0,0 @@ -endpoint = new WC_REST_Payment_Gateways_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/payment_gateways', $routes ); - $this->assertArrayHasKey( '/wc/v2/payment_gateways/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all payment gateways. - * - * @since 3.0.0 - */ - public function test_get_payment_gateways() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways' ) ); - $gateways = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => 'cheque', - 'title' => 'Check payments', - 'description' => 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', - 'order' => '', - 'enabled' => false, - 'method_title' => 'Check payments', - 'method_description' => 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', - 'settings' => array_diff_key( - $this->get_settings( 'WC_Gateway_Cheque' ), - array( - 'enabled' => false, - 'description' => false, - ) - ), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/payment_gateways/cheque' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/payment_gateways' ), - ), - ), - ), - ), - $gateways - ); - } - - /** - * Tests to make sure payment gateways cannot viewed without valid permissions. - * - * @since 3.0.0 - */ - public function test_get_payment_gateways_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single payment gateway. - * - * @since 3.0.0 - */ - public function test_get_payment_gateway() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways/paypal' ) ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => 'paypal', - 'title' => 'PayPal', - 'description' => "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account.", - 'order' => '', - 'enabled' => false, - 'method_title' => 'PayPal', - 'method_description' => 'PayPal Standard redirects customers to PayPal to enter their payment information.', - 'settings' => array_diff_key( - $this->get_settings( 'WC_Gateway_Paypal' ), - array( - 'enabled' => false, - 'description' => false, - ) - ), - ), - $paypal - ); - } - - /** - * Test getting a payment gateway without valid permissions. - * - * @since 3.0.0 - */ - public function test_get_payment_gateway_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways/paypal' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a payment gateway with an invalid id. - * - * @since 3.0.0 - */ - public function test_get_payment_gateway_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways/totally_fake_method' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a single payment gateway. - * - * @since 3.0.0 - */ - public function test_update_payment_gateway() { - wp_set_current_user( $this->user ); - - // Test defaults - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/payment_gateways/paypal' ) ); - $paypal = $response->get_data(); - - $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'admin@example.org', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); - - // test updating single setting - $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'email' => 'woo@woo.local', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); - - // test updating multiple settings - $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'testmode' => 'yes', - 'title' => 'PayPal - New Title', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); - - // Test other parameters, and recheck settings - $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertFalse( $paypal['enabled'] ); - $this->assertEquals( 2, $paypal['order'] ); - $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); - - // test bogus - $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'paymentaction' => 'afasfasf', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'paymentaction' => 'authorization', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - $this->assertEquals( 'authorization', $paypal['settings']['paymentaction']['value'] ); - } - - /** - * Test updating a payment gateway without valid permissions. - * - * @since 3.0.0 - */ - public function test_update_payment_gateway_without_permission() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'testmode' => 'yes', - 'title' => 'PayPal - New Title', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a payment gateway with an invalid id. - * - * @since 3.0.0 - */ - public function test_update_payment_gateway_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'POST', '/wc/v2/payment_gateways/totally_fake_method' ); - $request->set_body_params( - array( - 'enabled' => true, - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test the payment gateway schema. - * - * @since 3.0.0 - */ - public function test_payment_gateway_schema() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/payment_gateways' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 8, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'title', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'order', $properties ); - $this->assertArrayHasKey( 'enabled', $properties ); - $this->assertArrayHasKey( 'method_title', $properties ); - $this->assertArrayHasKey( 'method_description', $properties ); - $this->assertArrayHasKey( 'settings', $properties ); - } - - /** - * Loads a particular gateway's settings so we can correctly test API output. - * - * @since 3.0.0 - * @param string $gateway_class Name of WC_Payment_Gateway class. - */ - private function get_settings( $gateway_class ) { - $gateway = new $gateway_class(); - $settings = array(); - $gateway->init_form_fields(); - foreach ( $gateway->form_fields as $id => $field ) { - // Make sure we at least have a title and type - if ( empty( $field['title'] ) || empty( $field['type'] ) ) { - continue; - } - // Ignore 'title' settings/fields -- they are UI only - if ( 'title' === $field['type'] ) { - continue; - } - $data = array( - 'id' => $id, - 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => $gateway->settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - -} diff --git a/unit-tests/Tests/Version2/product-reviews.php b/unit-tests/Tests/Version2/product-reviews.php deleted file mode 100644 index 57f8804c1c9..00000000000 --- a/unit-tests/Tests/Version2/product-reviews.php +++ /dev/null @@ -1,468 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/products/reviews', $routes ); - $this->assertArrayHasKey( '/wc/v3/products/reviews/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v3/products/reviews/batch', $routes ); - } - - /** - * Test getting all product reviews. - * - * @since 3.0.0 - */ - public function test_get_product_reviews() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - // Create 10 products reviews for the product - for ( $i = 0; $i < 10; $i++ ) { - $review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); - $product_reviews = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 10, count( $product_reviews ) ); - $this->assertContains( - array( - 'id' => $review_id, - 'date_created' => $product_reviews[0]['date_created'], - 'date_created_gmt' => $product_reviews[0]['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => "

Review content here

\n", - 'rating' => 0, - 'verified' => false, - 'reviewer_avatar_urls' => $product_reviews[0]['reviewer_avatar_urls'], - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/products/reviews/' . $review_id ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/products/reviews' ), - ), - ), - 'up' => array( - array( - 'href' => rest_url( '/wc/v3/products/' . $product->get_id() ), - ), - ), - ), - ), - $product_reviews - ); - } - - /** - * Tests to make sure product reviews cannot be viewed without valid permissions. - * - * @since 3.0.0 - */ - public function test_get_product_reviews_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests to make sure an error is returned when an invalid product is loaded. - * - * @since 3.0.0 - */ - public function test_get_product_reviews_invalid_product() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/0/reviews' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests getting a single product review. - * - * @since 3.0.0 - */ - public function test_get_product_review() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $product_review_id, - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => "

Review content here

\n", - 'rating' => 0, - 'verified' => false, - 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], - ), - $data - ); - } - - /** - * Tests getting a single product review without the correct permissions. - * - * @since 3.0.0 - */ - public function test_get_product_review_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a product review with an invalid ID. - * - * @since 3.0.0 - */ - public function test_get_product_review_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests creating a product review. - * - * @since 3.0.0 - */ - public function test_create_product_review() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - 'rating' => '5', - 'product_id' => $product->get_id(), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => 'Hello world.', - 'rating' => 5, - 'verified' => false, - 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], - ), - $data - ); - } - - /** - * Tests creating a product review without required fields. - * - * @since 3.0.0 - */ - public function test_create_product_review_invalid_fields() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - // missing review - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); - $request->set_body_params( - array( - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - - // Missing reviewer. - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer_email' => 'woo@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - - // missing reviewer_email - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Tests updating a product review. - * - * @since 3.0.0 - */ - public function test_update_product_review() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); - $data = $response->get_data(); - $this->assertEquals( "

Review content here

\n", $data['review'] ); - $this->assertEquals( 'admin', $data['reviewer'] ); - $this->assertEquals( 'woo@woo.local', $data['reviewer_email'] ); - $this->assertEquals( 0, $data['rating'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); - $request->set_body_params( - array( - 'review' => 'Hello world - updated.', - 'reviewer' => 'Justin', - 'reviewer_email' => 'woo2@woo.local', - 'rating' => 3, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 'Hello world - updated.', $data['review'] ); - $this->assertEquals( 'Justin', $data['reviewer'] ); - $this->assertEquals( 'woo2@woo.local', $data['reviewer_email'] ); - $this->assertEquals( 3, $data['rating'] ); - } - - /** - * Tests updating a product review without the correct permissions. - * - * @since 3.0.0 - */ - public function test_update_product_review_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.dev', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests that updating a product review with an invalid id fails. - * - * @since 3.0.0 - */ - public function test_update_product_review_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/0' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.dev', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test deleting a product review. - * - * @since 3.0.0 - */ - public function test_delete_product_review() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test deleting a product review without permission/creds. - * - * @since 3.0.0 - */ - public function test_delete_product_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a product review with an invalid id. - * - * @since 3.0.0 - */ - public function test_delete_product_review_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test batch managing product reviews. - */ - public function test_product_reviews_batch() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - $review_1_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_2_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_3_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_4_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $review_1_id, - 'review' => 'Updated review.', - ), - ), - 'delete' => array( - $review_2_id, - $review_3_id, - ), - 'create' => array( - array( - 'review' => 'New review.', - 'reviewer' => 'Justin', - 'reviewer_email' => 'woo3@woo.local', - 'product_id' => $product->get_id(), - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'Updated review.', $data['update'][0]['review'] ); - $this->assertEquals( 'New review.', $data['create'][0]['review'] ); - $this->assertEquals( $review_2_id, $data['delete'][0]['previous']['id'] ); - $this->assertEquals( $review_3_id, $data['delete'][1]['previous']['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ); - $request->set_param( 'product', $product->get_id() ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Test the product review schema. - * - * @since 3.0.0 - */ - public function test_product_review_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/reviews' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 11, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_created_gmt', $properties ); - $this->assertArrayHasKey( 'product_id', $properties ); - $this->assertArrayHasKey( 'status', $properties ); - $this->assertArrayHasKey( 'reviewer', $properties ); - $this->assertArrayHasKey( 'reviewer_email', $properties ); - $this->assertArrayHasKey( 'review', $properties ); - $this->assertArrayHasKey( 'rating', $properties ); - $this->assertArrayHasKey( 'verified', $properties ); - - if ( get_option( 'show_avatars' ) ) { - $this->assertArrayHasKey( 'reviewer_avatar_urls', $properties ); - } - } -} diff --git a/unit-tests/Tests/Version2/product-variations.php b/unit-tests/Tests/Version2/product-variations.php deleted file mode 100644 index 22a53d4d829..00000000000 --- a/unit-tests/Tests/Version2/product-variations.php +++ /dev/null @@ -1,495 +0,0 @@ -endpoint = new WC_REST_Product_Variations_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/products/(?P[\d]+)/variations', $routes ); - $this->assertArrayHasKey( '/wc/v2/products/(?P[\d]+)/variations/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v2/products/(?P[\d]+)/variations/batch', $routes ); - } - - /** - * Test getting variations. - * - * @since 3.0.0 - */ - public function test_get_variations() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $variations ) ); - $this->assertEquals( 'DUMMY SKU VARIABLE LARGE', $variations[0]['sku'] ); - $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); - } - - /** - * Test getting variations with an orderby clause. - * - * @since 3.9.0 - */ - public function test_get_variations_with_orderby() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $request = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ); - $request->set_query_params( array( 'orderby' => 'menu_order' ) ); - $response = $this->server->dispatch( $request ); - $variations = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $variations ) ); - $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]['sku'] ); - $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); - } - - /** - * Test getting variations without permission. - * - * @since 3.0.0 - */ - public function test_get_variations_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single variation. - * - * @since 3.0.0 - */ - public function test_get_variation() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $variation_id, $variation['id'] ); - $this->assertEquals( 'size', $variation['attributes'][0]['name'] ); - } - - /** - * Test getting single variation without permission. - * - * @since 3.0.0 - */ - public function test_get_variation_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single variation. - * - * @since 3.0.0 - */ - public function test_delete_variation() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 1, count( $variations ) ); - } - - /** - * Test deleting a single variation without permission. - * - * @since 3.0.0 - */ - public function test_delete_variation_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single variation with an invalid ID. - * - * @since 3.0.0 - */ - public function test_delete_variation_with_invalid_id() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() . '/variations/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test editing a single variation. - * - * @since 3.0.0 - */ - public function test_update_variation() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $variation = $response->get_data(); - - $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variation['sku'] ); - $this->assertEquals( 10, $variation['regular_price'] ); - $this->assertEmpty( $variation['sale_price'] ); - $this->assertEquals( 'small', $variation['attributes'][0]['option'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU', - 'sale_price' => '8', - 'description' => 'O_O', - 'image' => array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertTrue( isset( $variation['description'] ), print_r( $variation, true ) ); - $this->assertContains( 'O_O', $variation['description'], print_r( $variation, true ) ); - $this->assertEquals( '8', $variation['price'], print_r( $variation, true ) ); - $this->assertEquals( '8', $variation['sale_price'], print_r( $variation, true ) ); - $this->assertEquals( '10', $variation['regular_price'], print_r( $variation, true ) ); - $this->assertEquals( 'FIXED-SKU', $variation['sku'], print_r( $variation, true ) ); - $this->assertEquals( 'medium', $variation['attributes'][0]['option'], print_r( $variation, true ) ); - $this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'], print_r( $variation, true ) ); - $this->assertContains( 'test upload image', $variation['image']['alt'], print_r( $variation, true ) ); - - wp_delete_attachment( $variation['image']['id'], true ); - } - - /** - * Test updating a single variation without permission. - * - * @since 3.0.0 - */ - public function test_update_variation_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single variation with an invalid ID. - * - * @since 3.0.0 - */ - public function test_update_variation_with_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/0' ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating a single variation. - * - * @since 3.0.0 - */ - public function test_create_variation() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 2, count( $variations ) ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations' ); - $request->set_body_params( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertContains( 'A medium size.', $variation['description'] ); - $this->assertEquals( '12', $variation['price'] ); - $this->assertEquals( '12', $variation['regular_price'] ); - $this->assertTrue( $variation['purchasable'] ); - $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $variation['sku'] ); - $this->assertEquals( 'medium', $variation['attributes'][0]['option'] ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 3, count( $variations ) ); - } - - /** - * Test creating a single variation without permission. - * - * @since 3.0.0 - */ - public function test_create_variation_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - - $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations' ); - $request->set_body_params( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch managing product variations. - */ - public function test_product_variations_batch() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/variations/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $children[0], - 'description' => 'Updated description.', - 'image' => array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - ), - ), - 'delete' => array( - $children[1], - ), - 'create' => array( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); - $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $data['create'][0]['sku'] ); - $this->assertEquals( 'medium', $data['create'][0]['attributes'][0]['option'] ); - $this->assertEquals( $children[1], $data['delete'][0]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() . '/variations' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 2, count( $data ) ); - - wp_delete_attachment( $data[1]['image']['id'], true ); - } - - /** - * Test variation schema. - * - * @since 3.0.0 - */ - public function test_variation_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/products/' . $product->get_id() . '/variations' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 37, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_modified', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'permalink', $properties ); - $this->assertArrayHasKey( 'sku', $properties ); - $this->assertArrayHasKey( 'price', $properties ); - $this->assertArrayHasKey( 'regular_price', $properties ); - $this->assertArrayHasKey( 'sale_price', $properties ); - $this->assertArrayHasKey( 'date_on_sale_from', $properties ); - $this->assertArrayHasKey( 'date_on_sale_to', $properties ); - $this->assertArrayHasKey( 'on_sale', $properties ); - $this->assertArrayHasKey( 'visible', $properties ); - $this->assertArrayHasKey( 'purchasable', $properties ); - $this->assertArrayHasKey( 'virtual', $properties ); - $this->assertArrayHasKey( 'downloadable', $properties ); - $this->assertArrayHasKey( 'downloads', $properties ); - $this->assertArrayHasKey( 'download_limit', $properties ); - $this->assertArrayHasKey( 'download_expiry', $properties ); - $this->assertArrayHasKey( 'tax_status', $properties ); - $this->assertArrayHasKey( 'tax_class', $properties ); - $this->assertArrayHasKey( 'manage_stock', $properties ); - $this->assertArrayHasKey( 'stock_quantity', $properties ); - $this->assertArrayHasKey( 'in_stock', $properties ); - $this->assertArrayHasKey( 'backorders', $properties ); - $this->assertArrayHasKey( 'backorders_allowed', $properties ); - $this->assertArrayHasKey( 'backordered', $properties ); - $this->assertArrayHasKey( 'weight', $properties ); - $this->assertArrayHasKey( 'dimensions', $properties ); - $this->assertArrayHasKey( 'shipping_class', $properties ); - $this->assertArrayHasKey( 'shipping_class_id', $properties ); - $this->assertArrayHasKey( 'image', $properties ); - $this->assertArrayHasKey( 'attributes', $properties ); - $this->assertArrayHasKey( 'menu_order', $properties ); - $this->assertArrayHasKey( 'meta_data', $properties ); - } - - /** - * Test updating a variation stock. - * - * @since 3.0.0 - */ - public function test_update_variation_manage_stock() { - wp_set_current_user( $this->user ); - - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $product->set_manage_stock( false ); - $product->save(); - - $children = $product->get_children(); - $variation_id = $children[0]; - - // Set stock to true. - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => true, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( true, $variation['manage_stock'] ); - - // Set stock to false. - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => false, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( false, $variation['manage_stock'] ); - - // Set stock to false but parent is managing stock. - $product->set_manage_stock( true ); - $product->save(); - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => false, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'parent', $variation['manage_stock'] ); - } -} diff --git a/unit-tests/Tests/Version2/products.php b/unit-tests/Tests/Version2/products.php deleted file mode 100644 index ea67735ae4e..00000000000 --- a/unit-tests/Tests/Version2/products.php +++ /dev/null @@ -1,536 +0,0 @@ -endpoint = new WC_REST_Products_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/products', $routes ); - $this->assertArrayHasKey( '/wc/v2/products/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v2/products/batch', $routes ); - } - - /** - * Test getting products. - * - * @since 3.0.0 - */ - public function test_get_products() { - wp_set_current_user( $this->user ); - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - sleep( 1 ); // So both products have different timestamps. - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 2, count( $products ) ); - $this->assertEquals( 'Dummy Product', $products[0]['name'] ); - $this->assertEquals( 'DUMMY SKU', $products[0]['sku'] ); - $this->assertEquals( 'Dummy External Product', $products[1]['name'] ); - $this->assertEquals( 'DUMMY EXTERNAL SKU', $products[1]['sku'] ); - } - - /** - * Test getting products without permission. - * - * @since 3.0.0 - */ - public function test_get_products_without_permission() { - wp_set_current_user( 0 ); - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single product. - * - * @since 3.0.0 - */ - public function test_get_product() { - wp_set_current_user( $this->user ); - $simple = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $simple->get_id() ) ); - $product = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => $simple->get_id(), - 'name' => 'Dummy External Product', - 'type' => 'simple', - 'status' => 'publish', - 'sku' => 'DUMMY EXTERNAL SKU', - 'regular_price' => 10, - ), - $product - ); - } - - /** - * Test getting single product without permission. - * - * @since 3.0.0 - */ - public function test_get_product_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single product. - * - * @since 3.0.0 - */ - public function test_delete_product() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); - $variations = $response->get_data(); - $this->assertEquals( 0, count( $variations ) ); - } - - /** - * Test deleting a single product without permission. - * - * @since 3.0.0 - */ - public function test_delete_product_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/' . $product->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single product with an invalid ID. - * - * @since 3.0.0 - */ - public function test_delete_product_with_invalid_id() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/products/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test editing a single product. Tests multiple product types. - * - * @since 3.0.0 - */ - public function test_update_product() { - wp_set_current_user( $this->user ); - - // test simple products. - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 'DUMMY SKU', $data['sku'] ); - $this->assertEquals( 10, $data['regular_price'] ); - $this->assertEmpty( $data['sale_price'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU', - 'sale_price' => '8', - 'description' => 'Testing', - 'images' => array( - array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Testing', $data['description'] ); - $this->assertEquals( '8', $data['price'] ); - $this->assertEquals( '8', $data['sale_price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertEquals( 'FIXED-SKU', $data['sku'] ); - $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); - $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); - $product->delete( true ); - wp_delete_attachment( $data['images'][0]['id'], true ); - - // test variable product (variations are tested in product-variations.php). - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); - $data = $response->get_data(); - - foreach ( array( 'small', 'large' ) as $term_name ) { - $this->assertContains( $term_name, $data['attributes'][0]['options'] ); - } - - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'attributes' => array( - array( - 'id' => 0, - 'name' => 'pa_color', - 'options' => array( - 'red', - 'yellow', - ), - 'visible' => false, - 'variation' => 1, - ), - array( - 'id' => 0, - 'name' => 'pa_size', - 'options' => array( - 'small', - ), - 'visible' => false, - 'variation' => 1, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( array( 'small' ), $data['attributes'][0]['options'] ); - $this->assertEquals( array( 'red', 'yellow' ), $data['attributes'][1]['options'] ); - $product->delete( true ); - - // test external product. - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products/' . $product->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 'Buy external product', $data['button_text'] ); - $this->assertEquals( 'http://woocommerce.com', $data['external_url'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'button_text' => 'Test API Update', - 'external_url' => 'http://automattic.com', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'Test API Update', $data['button_text'] ); - $this->assertEquals( 'http://automattic.com', $data['external_url'] ); - } - - /** - * Test updating a single product without permission. - * - * @since 3.0.0 - */ - public function test_update_product_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single product with an invalid ID. - * - * @since 3.0.0 - */ - public function test_update_product_with_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-INVALID-ID', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating a single product. - * - * @since 3.0.0 - */ - public function test_create_product() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/products/shipping_classes' ); - $request->set_body_params( - array( - 'name' => 'Test', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $shipping_class_id = $data['id']; - - // Create simple. - $request = new WP_REST_Request( 'POST', '/wc/v2/products' ); - $request->set_body_params( - array( - 'type' => 'simple', - 'name' => 'Test Simple Product', - 'sku' => 'DUMMY SKU SIMPLE API', - 'regular_price' => '10', - 'shipping_class' => 'test', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '10', $data['price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertTrue( $data['purchasable'] ); - $this->assertEquals( 'DUMMY SKU SIMPLE API', $data['sku'] ); - $this->assertEquals( 'Test Simple Product', $data['name'] ); - $this->assertEquals( 'simple', $data['type'] ); - $this->assertEquals( $shipping_class_id, $data['shipping_class_id'] ); - - // Create external. - $request = new WP_REST_Request( 'POST', '/wc/v2/products' ); - $request->set_body_params( - array( - 'type' => 'external', - 'name' => 'Test External Product', - 'sku' => 'DUMMY SKU EXTERNAL API', - 'regular_price' => '10', - 'button_text' => 'Test Button', - 'external_url' => 'https://wordpress.org', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '10', $data['price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertFalse( $data['purchasable'] ); - $this->assertEquals( 'DUMMY SKU EXTERNAL API', $data['sku'] ); - $this->assertEquals( 'Test External Product', $data['name'] ); - $this->assertEquals( 'external', $data['type'] ); - $this->assertEquals( 'Test Button', $data['button_text'] ); - $this->assertEquals( 'https://wordpress.org', $data['external_url'] ); - - // Create variable. - $request = new WP_REST_Request( 'POST', '/wc/v2/products' ); - $request->set_body_params( - array( - 'type' => 'variable', - 'name' => 'Test Variable Product', - 'sku' => 'DUMMY SKU VARIABLE API', - 'attributes' => array( - array( - 'id' => 0, - 'name' => 'pa_size', - 'options' => array( - 'small', - 'medium', - ), - 'visible' => false, - 'variation' => 1, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'DUMMY SKU VARIABLE API', $data['sku'] ); - $this->assertEquals( 'Test Variable Product', $data['name'] ); - $this->assertEquals( 'variable', $data['type'] ); - $this->assertEquals( array( 'small', 'medium' ), $data['attributes'][0]['options'] ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/products' ) ); - $products = $response->get_data(); - $this->assertEquals( 3, count( $products ) ); - } - - /** - * Test creating a single product without permission. - * - * @since 3.0.0 - */ - public function test_create_product_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/products' ); - $request->set_body_params( - array( - 'name' => 'Test Product', - 'regular_price' => '12', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch managing products. - */ - public function test_products_batch() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'POST', '/wc/v2/products/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $product->get_id(), - 'description' => 'Updated description.', - ), - ), - 'delete' => array( - $product_2->get_id(), - ), - 'create' => array( - array( - 'sku' => 'DUMMY SKU BATCH TEST 1', - 'regular_price' => '10', - 'name' => 'Test Batch Create 1', - 'type' => 'external', - 'button_text' => 'Test Button', - ), - array( - 'sku' => 'DUMMY SKU BATCH TEST 2', - 'regular_price' => '20', - 'name' => 'Test Batch Create 2', - 'type' => 'simple', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); - $this->assertEquals( 'DUMMY SKU BATCH TEST 1', $data['create'][0]['sku'] ); - $this->assertEquals( 'DUMMY SKU BATCH TEST 2', $data['create'][1]['sku'] ); - $this->assertEquals( 'Test Button', $data['create'][0]['button_text'] ); - $this->assertEquals( 'external', $data['create'][0]['type'] ); - $this->assertEquals( 'simple', $data['create'][1]['type'] ); - $this->assertEquals( $product_2->get_id(), $data['delete'][0]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Tests to make sure you can filter products post statuses by both - * the status query arg and WP_Query. - * - * @since 3.0.0 - */ - public function test_products_filter_post_status() { - wp_set_current_user( $this->user ); - for ( $i = 0; $i < 8; $i++ ) { - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - if ( 0 === $i % 2 ) { - wp_update_post( - array( - 'ID' => $product->get_id(), - 'post_status' => 'draft', - ) - ); - } - } - - // Test filtering with status=publish. - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_param( 'status', 'publish' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 4, count( $products ) ); - foreach ( $products as $product ) { - $this->assertEquals( 'publish', $product['status'] ); - } - - // Test filtering with status=draft. - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_param( 'status', 'draft' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 4, count( $products ) ); - foreach ( $products as $product ) { - $this->assertEquals( 'draft', $product['status'] ); - } - - // Test filtering with no filters - which should return 'any' (all 8). - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 8, count( $products ) ); - } - - /** - * Test product schema. - * - * @since 3.0.0 - */ - public function test_product_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/products/' . $product->get_id() ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 65, count( $properties ) ); - } -} diff --git a/unit-tests/Tests/Version2/settings.php b/unit-tests/Tests/Version2/settings.php deleted file mode 100644 index 12baa1aca4e..00000000000 --- a/unit-tests/Tests/Version2/settings.php +++ /dev/null @@ -1,892 +0,0 @@ -endpoint = new WC_REST_Setting_Options_Controller(); - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/settings', $routes ); - $this->assertArrayHasKey( '/wc/v2/settings/(?P[\w-]+)', $routes ); - $this->assertArrayHasKey( '/wc/v2/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all groups. - * - * @since 3.0.0 - */ - public function test_get_groups() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertContains( - array( - 'id' => 'test', - 'label' => 'Test extension', - 'parent_id' => '', - 'description' => 'My awesome test settings.', - 'sub_groups' => array( 'sub-test' ), - '_links' => array( - 'options' => array( - array( - 'href' => rest_url( '/wc/v2/settings/test' ), - ), - ), - ), - ), - $data - ); - - $this->assertContains( - array( - 'id' => 'sub-test', - 'label' => 'Sub test', - 'parent_id' => 'test', - 'description' => '', - 'sub_groups' => array(), - '_links' => array( - 'options' => array( - array( - 'href' => rest_url( '/wc/v2/settings/sub-test' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test /settings without valid permissions/creds. - * - * @since 3.0.0 - */ - public function test_get_groups_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test /settings without valid permissions/creds. - * - * @since 3.0.0 - * @covers WC_Rest_Settings_Controller::get_items - */ - public function test_get_groups_none_registered() { - wp_set_current_user( $this->user ); - - remove_all_filters( 'woocommerce_settings_groups' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings' ) ); - $this->assertEquals( 500, $response->get_status() ); - - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); - } - - /** - * Test groups schema. - * - * @since 3.0.0 - */ - public function test_get_group_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/settings' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 5, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'parent_id', $properties ); - $this->assertArrayHasKey( 'label', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'sub_groups', $properties ); - } - - /** - * Test settings schema. - * - * @since 3.0.0 - */ - public function test_get_setting_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/settings/test/woocommerce_shop_page_display' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 9, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'label', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'value', $properties ); - $this->assertArrayHasKey( 'default', $properties ); - $this->assertArrayHasKey( 'tip', $properties ); - $this->assertArrayHasKey( 'placeholder', $properties ); - $this->assertArrayHasKey( 'type', $properties ); - $this->assertArrayHasKey( 'options', $properties ); - } - - /** - * Test getting a single group. - * - * @since 3.0.0 - */ - public function test_get_group() { - wp_set_current_user( $this->user ); - - // test route callback receiving an empty group id - $result = $this->endpoint->get_group_settings( '' ); - $this->assertWPError( $result ); - - // test getting a group that does not exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/not-real' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // test getting the 'invalid' group - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/invalid' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // test getting a valid group with settings attached to it - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test' ) ); - $data = $response->get_data(); - $this->assertEquals( 1, count( $data ) ); - $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); - $this->assertEmpty( $data[0]['value'] ); - } - - /** - * Test getting a single group without permission. - * - * @since 3.0.0 - */ - public function test_get_group_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/coupon-data' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single setting. - * - * @since 3.0.0 - */ - public function test_update_setting() { - wp_set_current_user( $this->user ); - - // test defaults first - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - $this->assertEquals( '', $data['value'] ); - - // test updating shop display setting - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'both', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'both', $data['value'] ); - $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'subcategories', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'subcategories', $data['value'] ); - $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => '', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '', $data['value'] ); - $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); - } - - /** - * Test updating multiple settings at once. - * - * @since 3.0.0 - */ - public function test_update_settings() { - wp_set_current_user( $this->user ); - - // test defaults first - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test' ) ); - $data = $response->get_data(); - $this->assertEquals( '', $data[0]['value'] ); - - // test setting both at once - $request = new WP_REST_Request( 'POST', '/wc/v2/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'both', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'both', $data['update'][0]['value'] ); - $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - - // test updating one, but making sure the other value stays the same - $request = new WP_REST_Request( 'POST', '/wc/v2/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'subcategories', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); - $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - } - - /** - * Test getting a single setting. - * - * @since 3.0.0 - */ - public function test_get_setting() { - wp_set_current_user( $this->user ); - - // test getting an invalid setting from a group that does not exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/not-real/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - $this->assertEquals( 404, $response->get_status() ); - - // test getting an invalid setting from a group that does exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/invalid/invalid' ) ); - $data = $response->get_data(); - $this->assertEquals( 404, $response->get_status() ); - - // test getting a valid setting - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 'woocommerce_shop_page_display', $data['id'] ); - $this->assertEquals( 'Shop page display', $data['label'] ); - $this->assertEquals( '', $data['default'] ); - $this->assertEquals( 'select', $data['type'] ); - $this->assertEquals( '', $data['value'] ); - } - - /** - * Test getting a single setting without valid user permissions. - * - * @since 3.0.0 - */ - public function test_get_setting_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test/woocommerce_shop_page_display' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests the GET single setting route handler receiving an empty setting ID. - * - * @since 3.0.0 - */ - public function test_get_setting_empty_setting_id() { - $result = $this->endpoint->get_setting( 'test', '' ); - - $this->assertWPError( $result ); - } - - /** - * Tests the GET single setting route handler receiving an invalid setting ID. - * - * @since 3.0.0 - */ - public function test_get_setting_invalid_setting_id() { - $result = $this->endpoint->get_setting( 'test', 'invalid' ); - - $this->assertWPError( $result ); - } - - /** - * Tests the GET single setting route handler encountering an invalid setting type. - * - * @since 3.0.0 - */ - public function test_get_setting_invalid_setting_type() { - // $controller = $this->getMock( 'WC_Rest_Setting_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); - $controller = $this->getMockBuilder( 'WC_Rest_Setting_Options_Controller' )->setMethods( array( 'get_group_settings', 'is_setting_type_valid' ) )->getMock(); - - $controller - ->expects( $this->any() ) - ->method( 'get_group_settings' ) - ->will( $this->returnValue( \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); - - $controller - ->expects( $this->any() ) - ->method( 'is_setting_type_valid' ) - ->will( $this->returnValue( false ) ); - - $result = $controller->get_setting( 'test', 'woocommerce_shop_page_display' ); - - $this->assertWPError( $result ); - } - - /** - * Test updating a single setting without valid user permissions. - * - * @since 3.0.0 - */ - public function test_update_setting_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'subcategories', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - - /** - * Test updating multiple settings without valid user permissions. - * - * @since 3.0.0 - */ - public function test_update_settings_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'subcategories', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a bad setting ID. - * - * @since 3.0.0 - * @covers WC_Rest_Setting_Options_Controller::update_item - */ - public function test_update_setting_bad_setting_id() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/test/invalid' ); - $request->set_body_params( - array( - 'value' => 'test', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. - * - * @since 3.0.0 - */ - public function test_classic_settings() { - wp_set_current_user( $this->user ); - - // Make sure the group is properly registered - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/products' ) ); - $data = $response->get_data(); - $this->assertTrue( is_array( $data ) ); - $this->assertContains( - array( - 'id' => 'woocommerce_downloads_require_login', - 'label' => 'Access restriction', - 'description' => 'Downloads require login', - 'type' => 'checkbox', - 'default' => 'no', - 'tip' => 'This setting does not apply to guest purchases.', - 'value' => 'no', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/settings/products/woocommerce_downloads_require_login' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/settings/products' ), - ), - ), - ), - ), - $data - ); - - // test get single - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/products/woocommerce_dimension_unit' ) ); - $data = $response->get_data(); - - $this->assertEquals( 'cm', $data['default'] ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); - $request->set_body_params( - array( - 'value' => 'yd', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'yd', $data['value'] ); - $this->assertEquals( 'yd', get_option( 'woocommerce_dimension_unit' ) ); - } - - /** - * Tests our email etting registration to make sure settings added for WP-Admin are available over the API. - * - * @since 3.0.0 - */ - public function test_email_settings() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/email_new_order' ) ); - $settings = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertContains( - array( - 'id' => 'recipient', - 'label' => 'Recipient(s)', - 'description' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', - 'type' => 'text', - 'default' => '', - 'tip' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', - 'value' => '', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/settings/email_new_order/recipient' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/settings/email_new_order' ), - ), - ), - ), - ), - $settings - ); - - // test get single - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/email_new_order/subject' ) ); - $setting = $response->get_data(); - - $this->assertEquals( - array( - 'id' => 'subject', - 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', - 'type' => 'text', - 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', - 'value' => '', - ), - $setting - ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_new_order', 'subject' ) ); - $request->set_body_params( - array( - 'value' => 'This is my subject', - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEquals( - array( - 'id' => 'subject', - 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', - 'type' => 'text', - 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', - 'value' => 'This is my subject', - ), - $setting - ); - - // test updating another subject and making sure it works with a "similar" id - $request = new WP_REST_Request( 'GET', sprintf( '/wc/v2/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEmpty( $setting['value'] ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); - $request->set_body_params( - array( - 'value' => 'This is my new subject', - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEquals( 'This is my new subject', $setting['value'] ); - - // make sure the other is what we left it - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/email_new_order/subject' ) ); - $setting = $response->get_data(); - - $this->assertEquals( 'This is my subject', $setting['value'] ); - } - - /** - * Test validation of checkbox settings. - * - * @since 3.0.0 - */ - public function test_validation_checkbox() { - wp_set_current_user( $this->user ); - - // test bogus value - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'not_yes_or_no', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // test yes - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'yes', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - // test no - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'no', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test validation of radio settings. - * - * @since 3.0.0 - */ - public function test_validation_radio() { - wp_set_current_user( $this->user ); - - // not a valid option - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); - $request->set_body_params( - array( - 'value' => 'billing2', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // valid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); - $request->set_body_params( - array( - 'value' => 'billing', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test validation of multiselect. - * - * @since 3.0.0 - */ - public function test_validation_multiselect() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v2/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ) ); - $setting = $response->get_data(); - $this->assertEmpty( $setting['value'] ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ); - $request->set_body_params( - array( - 'value' => array( 'AX', 'DZ', 'MMM' ), - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( array( 'AX', 'DZ' ), $setting['value'] ); - } - - /** - * Test validation of select. - * - * @since 3.0.0 - */ - public function test_validation_select() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ) ); - $setting = $response->get_data(); - $this->assertEquals( 'kg', $setting['value'] ); - - // invalid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); - $request->set_body_params( - array( - 'value' => 'pounds', // invalid, should be lbs - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // valid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); - $request->set_body_params( - array( - 'value' => 'lbs', // invalid, should be lbs - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( 'lbs', $setting['value'] ); - } - - /** - * Test to make sure the 'base location' setting is present in the response. - * That it is returned as 'select' and not 'single_select_country', - * and that both state and country options are returned. - * - * @since 3.0.7 - */ - public function test_woocommerce_default_country() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_default_country' ) ); - $setting = $response->get_data(); - - $this->assertEquals( 'select', $setting['type'] ); - $this->assertArrayHasKey( 'GB', $setting['options'] ); - $this->assertArrayHasKey( 'US:OR', $setting['options'] ); - } - - /** - * Test to make sure the store address setting can be fetched and updated. - * - * @since 3.1.1 - */ - public function test_woocommerce_store_address() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_address' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store address 2 (line 2) setting can be fetched and updated. - * - * @since 3.1.1 - */ - public function test_woocommerce_store_address_2() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_address_2' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address_2' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address_2' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store city setting can be fetched and updated. - * - * @since 3.1.1 - */ - public function test_woocommerce_store_city() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_city' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_city' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_city' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store postcode setting can be fetched and updated. - * - * @since 3.1.1 - */ - public function test_woocommerce_store_postcode() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_postcode' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_postcode' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_postcode' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } -} diff --git a/unit-tests/Tests/Version2/shipping-methods.php b/unit-tests/Tests/Version2/shipping-methods.php deleted file mode 100644 index 65c153e8f31..00000000000 --- a/unit-tests/Tests/Version2/shipping-methods.php +++ /dev/null @@ -1,143 +0,0 @@ -endpoint = new WC_REST_Shipping_Methods_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/shipping_methods', $routes ); - $this->assertArrayHasKey( '/wc/v2/shipping_methods/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all shipping methods. - * - * @since 3.0.0 - */ - public function test_get_shipping_methods() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods' ) ); - $methods = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => 'free_shipping', - 'title' => 'Free shipping', - 'description' => 'Free shipping is a special method which can be triggered with coupons and minimum spends.', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/shipping_methods/free_shipping' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping_methods' ), - ), - ), - ), - ), - $methods - ); - } - - /** - * Tests to make sure shipping methods cannot viewed without valid permissions. - * - * @since 3.0.0 - */ - public function test_get_shipping_methods_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a single shipping method. - * - * @since 3.0.0 - */ - public function test_get_shipping_method() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods/local_pickup' ) ); - $method = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => 'local_pickup', - 'title' => 'Local pickup', - 'description' => 'Allow customers to pick up orders themselves. By default, when using local pickup store base taxes will apply regardless of customer address.', - ), - $method - ); - } - - /** - * Tests getting a single shipping method without the correct permissions. - * - * @since 3.0.0 - */ - public function test_get_shipping_method_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods/local_pickup' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a shipping method with an invalid ID. - * - * @since 3.0.0 - */ - public function test_get_shipping_method_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping_methods/fake_method' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test the shipping method schema. - * - * @since 3.0.0 - */ - public function test_shipping_method_schema() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/shipping_methods' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'title', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - } -} diff --git a/unit-tests/Tests/Version2/shipping-zones.php b/unit-tests/Tests/Version2/shipping-zones.php deleted file mode 100644 index 1d9ea5368d3..00000000000 --- a/unit-tests/Tests/Version2/shipping-zones.php +++ /dev/null @@ -1,800 +0,0 @@ -endpoint = new WC_REST_Shipping_Zones_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - $this->zones = array(); - } - - /** - * Helper method to create a Shipping Zone. - * - * @param string $name Zone name. - * @param int $order Optional. Zone sort order. - * @return WC_Shipping_Zone - */ - protected function create_shipping_zone( $name, $order = 0, $locations = array() ) { - $zone = new WC_Shipping_Zone( null ); - $zone->set_zone_name( $name ); - $zone->set_zone_order( $order ); - $zone->set_locations( $locations ); - $zone->save(); - - $this->zones[] = $zone; - - return $zone; - } - - /** - * Test route registration. - * @since 3.0.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/shipping/zones', $routes ); - $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/locations', $routes ); - $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/methods', $routes ); - $this->assertArrayHasKey( '/wc/v2/shipping/zones/(?P[\d]+)/methods/(?P[\d]+)', $routes ); - } - - /** - * Test getting all Shipping Zones. - * @since 3.0.0 - */ - public function test_get_zones() { - wp_set_current_user( $this->user ); - - // "Rest of the World" zone exists by default - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertContains( - array( - 'id' => $data[0]['id'], - 'name' => 'Locations not covered by your other zones', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $data[0]['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $data[0]['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - - // Create a zone and make sure it's in the response - $this->create_shipping_zone( 'Zone 1' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 2 ); - $this->assertContains( - array( - 'id' => $data[1]['id'], - 'name' => 'Zone 1', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $data[1]['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $data[1]['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test /shipping/zones without valid permissions/creds. - * @since 3.0.0 - */ - public function test_get_shipping_zones_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test /shipping/zones while Shipping is disabled in WooCommerce. - * @since 3.0.0 - */ - public function test_get_shipping_zones_disabled_shipping() { - wp_set_current_user( $this->user ); - - add_filter( 'wc_shipping_enabled', '__return_false' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones' ) ); - $this->assertEquals( 404, $response->get_status() ); - - remove_filter( 'wc_shipping_enabled', '__return_false' ); - } - - /** - * Test Shipping Zone schema. - * @since 3.0.0 - */ - public function test_get_shipping_zone_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/shipping/zones' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertTrue( $properties['id']['readonly'] ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'order', $properties ); - } - - /** - * Test Shipping Zone create endpoint. - * @since 3.0.0 - */ - public function test_create_shipping_zone() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones' ); - $request->set_body_params( - array( - 'name' => 'Test Zone', - 'order' => 1, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'name' => 'Test Zone', - 'order' => 1, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $data['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $data['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test Shipping Zone create endpoint. - * @since 3.0.0 - */ - public function test_create_shipping_zone_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones' ); - $request->set_body_params( - array( - 'name' => 'Test Zone', - 'order' => 1, - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test Shipping Zone update endpoint. - * @since 3.0.0 - */ - public function test_update_shipping_zone() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Test Zone' ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/shipping/zones/' . $zone->get_id() ); - $request->set_body_params( - array( - 'name' => 'Zone Test', - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $zone->get_id(), - 'name' => 'Zone Test', - 'order' => 2, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test Shipping Zone update endpoint with a bad zone ID. - * @since 3.0.0 - */ - public function test_update_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/shipping/zones/555555' ); - $request->set_body_params( - array( - 'name' => 'Zone Test', - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint. - * @since 3.0.0 - */ - public function test_delete_shipping_zone() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v2/shipping/zones/' . $zone->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint without permissions. - * @since 3.0.0 - */ - public function test_delete_shipping_zone_without_permission() { - wp_set_current_user( 0 ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v2/shipping/zones/' . $zone->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint with a bad zone ID. - * @since 3.0.0 - */ - public function test_delete_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'DELETE', '/wc/v2/shipping/zones/555555' ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single Shipping Zone. - * @since 3.0.0 - */ - public function test_get_single_shipping_zone() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Test Zone' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $zone->get_id(), - 'name' => 'Test Zone', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test getting a single Shipping Zone with a bad zone ID. - * @since 3.0.0 - */ - public function test_get_single_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting Shipping Zone Locations. - * @since 3.0.0 - */ - public function test_get_locations() { - wp_set_current_user( $this->user ); - - // Create a zone - $zone = $this->create_shipping_zone( - 'Zone 1', - 0, - array( - array( - 'code' => 'US', - 'type' => 'country', - ), - ) - ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertEquals( - array( - array( - 'code' => 'US', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test getting Shipping Zone Locations with a bad zone ID. - * @since 3.0.0 - */ - public function test_get_locations_invalid_id() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/1/locations' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test Shipping Zone Locations update endpoint. - * @since 3.0.0 - */ - public function test_update_locations() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Test Zone' ); - - $request = new WP_REST_Request( 'PUT', '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ); - $request->add_header( 'Content-Type', 'application/json' ); - $request->set_body( - json_encode( - array( - array( - 'code' => 'UK', - 'type' => 'country', - ), - array( - 'code' => 'US', // test that locations missing "type" treated as country. - ), - array( - 'code' => 'SW1A0AA', - 'type' => 'postcode', - ), - array( - 'type' => 'continent', // test that locations missing "code" aren't saved - ), - ) - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - $this->assertEquals( - array( - array( - 'code' => 'UK', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - array( - 'code' => 'US', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - array( - 'code' => 'SW1A0AA', - 'type' => 'postcode', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test updating Shipping Zone Locations with a bad zone ID. - * @since 3.0.0 - */ - public function test_update_locations_invalid_id() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'PUT', '/wc/v2/shipping/zones/1/locations' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting all Shipping Zone Methods and getting a single Shipping Zone Method. - * @since 3.0.0 - */ - public function test_get_methods() { - wp_set_current_user( $this->user ); - - // Create a shipping method and make sure it's in the response - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - - $settings = array(); - $method->init_instance_settings(); - foreach ( $method->get_instance_form_fields() as $id => $field ) { - $data = array( - 'id' => $id, - 'label' => $field['title'], - 'description' => ( empty( $field['description'] ) ? '' : $field['description'] ), - 'type' => $field['type'], - 'value' => $method->instance_settings[ $id ], - 'default' => ( empty( $field['default'] ) ? '' : $field['default'] ), - 'tip' => ( empty( $field['description'] ) ? '' : $field['description'] ), - 'placeholder' => ( empty( $field['placeholder'] ) ? '' : $field['placeholder'] ), - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods' ) ); - $data = $response->get_data(); - $expected = array( - 'id' => $instance_id, - 'instance_id' => $instance_id, - 'title' => $method->instance_settings['title'], - 'order' => $method->method_order, - 'enabled' => ( 'yes' === $method->enabled ), - 'method_id' => $method->id, - 'method_title' => $method->method_title, - 'method_description' => $method->method_description, - 'settings' => $settings, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v2/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertContains( $expected, $data ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $expected, $data ); - } - - /** - * Test getting all Shipping Zone Methods with a bad zone ID. - * @since 3.0.0 - */ - public function test_get_methods_invalid_zone_id() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/1/methods' ) ); - - $this->assertEquals( 404, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/1/methods/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single Shipping Zone Method with a bad ID. - * @since 3.0.0 - */ - public function test_get_methods_invalid_method_id() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Zone 1' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a Shipping Zone Method. - * @since 3.0.0 - */ - public function test_update_methods() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - - // Test defaults - $request = new WP_REST_Request( 'GET', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '0', $data['settings']['cost']['value'] ); - - // Update a single value - $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 5, - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '5', $data['settings']['cost']['value'] ); - - // Test multiple settings - $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 10, - 'tax_status' => 'none', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'none', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '10', $data['settings']['cost']['value'] ); - - // Test bogus - $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 10, - 'tax_status' => 'this_is_not_a_valid_option', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // Test other parameters - $this->assertTrue( $data['enabled'] ); - $this->assertEquals( 1, $data['order'] ); - - $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertFalse( $data['enabled'] ); - $this->assertEquals( 2, $data['order'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '10', $data['settings']['cost']['value'] ); - } - - /** - * Test creating a Shipping Zone Method. - * @since 3.0.0 - */ - public function test_create_method() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - $request = new WP_REST_Request( 'POST', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods' ); - $request->set_body_params( - array( - 'method_id' => 'flat_rate', - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertFalse( $data['enabled'] ); - $this->assertEquals( 2, $data['order'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '0', $data['settings']['cost']['value'] ); - } - - /** - * Test deleting a Shipping Zone Method. - * @since 3.0.0 - */ - public function test_delete_method() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - $request = new WP_REST_Request( 'DELETE', '/wc/v2/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } -} diff --git a/unit-tests/Tests/Version2/system-status.php b/unit-tests/Tests/Version2/system-status.php deleted file mode 100644 index cb359b0630b..00000000000 --- a/unit-tests/Tests/Version2/system-status.php +++ /dev/null @@ -1,355 +0,0 @@ -endpoint = new WC_REST_System_Status_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v2/system_status', $routes ); - $this->assertArrayHasKey( '/wc/v2/system_status/tools', $routes ); - $this->assertArrayHasKey( '/wc/v2/system_status/tools/(?P[\w-]+)', $routes ); - } - - /** - * Test to make sure system status cannot be accessed without valid creds - * - * @since 3.0.0 - */ - public function test_get_system_status_info_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure root properties are present. - * (environment, theme, database, etc). - * - * @since 3.0.0 - */ - public function test_get_system_status_info_returns_root_properties() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'environment', $data ); - $this->assertArrayHasKey( 'database', $data ); - $this->assertArrayHasKey( 'active_plugins', $data ); - $this->assertArrayHasKey( 'theme', $data ); - $this->assertArrayHasKey( 'settings', $data ); - $this->assertArrayHasKey( 'security', $data ); - $this->assertArrayHasKey( 'pages', $data ); - } - - /** - * Test to make sure environment response is correct. - * - * @since 3.0.0 - */ - public function test_get_system_status_info_environment() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - $data = $response->get_data(); - $environment = (array) $data['environment']; - - // Make sure all expected data is present. - $this->assertEquals( 32, count( $environment ) ); - - // Test some responses to make sure they match up. - $this->assertEquals( get_option( 'home' ), $environment['home_url'] ); - $this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] ); - $this->assertEquals( WC()->version, $environment['version'] ); - } - - /** - * Test to make sure database response is correct. - * - * @since 3.0.0 - */ - public function test_get_system_status_info_database() { - global $wpdb; - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - $data = $response->get_data(); - $database = (array) $data['database']; - - $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); - $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); - $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], print_r( $database, true ) ); - $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], print_r( $database, true ) ); - } - - /** - * Test to make sure active plugins response is correct. - * - * @since 3.0.0 - */ - public function test_get_system_status_info_active_plugins() { - wp_set_current_user( $this->user ); - - $actual_plugins = array( 'hello.php' ); - update_option( 'active_plugins', $actual_plugins ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - update_option( 'active_plugins', array() ); - - $data = $response->get_data(); - $plugins = (array) $data['active_plugins']; - - $this->assertEquals( 1, count( $plugins ) ); - $this->assertEquals( 'Hello Dolly', $plugins[0]['name'] ); - } - - /** - * Test to make sure theme response is correct. - * - * @since 3.0.0 - */ - public function test_get_system_status_info_theme() { - wp_set_current_user( $this->user ); - $active_theme = wp_get_theme(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - $data = $response->get_data(); - $theme = (array) $data['theme']; - - $this->assertEquals( 13, count( $theme ) ); - $this->assertEquals( $active_theme->Name, $theme['name'] ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar - } - - /** - * Test to make sure settings response is correct. - * - * @since 3.0.0 - */ - public function test_get_system_status_info_settings() { - wp_set_current_user( $this->user ); - - $term_response = array(); - $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); - foreach ( $terms as $term ) { - $term_response[ $term->slug ] = strtolower( $term->name ); - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - $data = $response->get_data(); - $settings = (array) $data['settings']; - - $this->assertEquals( 12, count( $settings ) ); - $this->assertEquals( ( 'yes' === get_option( 'woocommerce_api_enabled' ) ), $settings['api_enabled'] ); - $this->assertEquals( get_woocommerce_currency(), $settings['currency'] ); - $this->assertEquals( $term_response, $settings['taxonomies'] ); - } - - /** - * Test to make sure security response is correct. - * - * @since 3.0.0 - */ - public function test_get_system_status_info_security() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - $data = $response->get_data(); - $settings = (array) $data['security']; - - $this->assertEquals( 2, count( $settings ) ); - $this->assertEquals( 'https' === substr( wc_get_page_permalink( 'shop' ), 0, 5 ), $settings['secure_connection'] ); - $this->assertEquals( ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), $settings['hide_errors'] ); - } - - /** - * Test to make sure pages response is correct. - * - * @since 3.0.0 - */ - public function test_get_system_status_info_pages() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status' ) ); - $data = $response->get_data(); - $pages = $data['pages']; - $this->assertEquals( 5, count( $pages ) ); - } - - /** - * Test system status schema. - * - * @since 3.0.0 - */ - public function test_system_status_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/system_status' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 10, count( $properties ) ); - $this->assertArrayHasKey( 'environment', $properties ); - $this->assertArrayHasKey( 'database', $properties ); - $this->assertArrayHasKey( 'active_plugins', $properties ); - $this->assertArrayHasKey( 'theme', $properties ); - $this->assertArrayHasKey( 'settings', $properties ); - $this->assertArrayHasKey( 'security', $properties ); - $this->assertArrayHasKey( 'pages', $properties ); - } - - /** - * Test to make sure get_items (all tools) response is correct. - * - * @since 3.0.0 - */ - public function test_get_system_tools() { - wp_set_current_user( $this->user ); - - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status/tools' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $raw_tools ), count( $data ) ); - $this->assertContains( - array( - 'id' => 'regenerate_thumbnails', - 'name' => 'Regenerate shop thumbnails', - 'action' => 'Regenerate', - 'description' => 'This will regenerate all shop thumbnails to match your theme and/or image settings.', - '_links' => array( - 'item' => array( - array( - 'href' => rest_url( '/wc/v2/system_status/tools/regenerate_thumbnails' ), - 'embeddable' => true, - ), - ), - ), - ), - $data - ); - } - - /** - * Test to make sure system status tools cannot be accessed without valid creds - * - * @since 3.0.0 - */ - public function test_get_system_status_tools_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status/tools' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure we can load a single tool correctly. - * - * @since 3.0.0 - */ - public function test_get_system_tool() { - wp_set_current_user( $this->user ); - - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - $raw_tool = $raw_tools['recount_terms']; - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status/tools/recount_terms' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertEquals( 'Term counts', $data['name'] ); - $this->assertEquals( 'Recount terms', $data['action'] ); - $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); - } - - /** - * Test to make sure a single system status toolscannot be accessed without valid creds. - * - * @since 3.0.0 - */ - public function test_get_system_status_tool_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/system_status/tools/recount_terms' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure we can RUN a tool correctly. - * - * @since 3.0.0 - */ - public function test_execute_system_tool() { - wp_set_current_user( $this->user ); - - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - $raw_tool = $raw_tools['recount_terms']; - - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v2/system_status/tools/recount_terms' ) ); - $data = $response->get_data(); - - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertEquals( 'Term counts', $data['name'] ); - $this->assertEquals( 'Recount terms', $data['action'] ); - $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); - $this->assertTrue( $data['success'] ); - $this->assertEquals( 1, did_action( 'woocommerce_rest_insert_system_status_tool' ) ); - - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v2/system_status/tools/not_a_real_tool' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test to make sure a tool cannot be run without valid creds. - * - * @since 3.0.0 - */ - public function test_execute_system_status_tool_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v2/system_status/tools/recount_terms' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test system status schema. - * - * @since 3.0.0 - */ - public function test_system_status_tool_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v2/system_status/tools' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 6, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'action', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'success', $properties ); - $this->assertArrayHasKey( 'message', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/coupons.php b/unit-tests/Tests/Version3/coupons.php deleted file mode 100644 index bd0564de6be..00000000000 --- a/unit-tests/Tests/Version3/coupons.php +++ /dev/null @@ -1,471 +0,0 @@ -endpoint = new WC_REST_Coupons_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/coupons', $routes ); - $this->assertArrayHasKey( '/wc/v3/coupons/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v3/coupons/batch', $routes ); - } - - /** - * Test getting coupons. - * @since 3.5.0 - */ - public function test_get_coupons() { - wp_set_current_user( $this->user ); - - $coupon_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $post_1 = get_post( $coupon_1->get_id() ); - $coupon_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons' ) ); - $coupons = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $coupons ) ); - $this->assertContains( - array( - 'id' => $coupon_1->get_id(), - 'code' => 'dummycoupon-1', - 'amount' => '1.00', - 'date_created' => wc_rest_prepare_date_response( $post_1->post_date_gmt, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $post_1->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $post_1->post_modified_gmt, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $post_1->post_modified_gmt ), - 'discount_type' => 'fixed_cart', - 'description' => 'This is a dummy coupon', - 'date_expires' => '', - 'date_expires_gmt' => '', - 'usage_count' => 0, - 'individual_use' => false, - 'product_ids' => array(), - 'excluded_product_ids' => array(), - 'usage_limit' => '', - 'usage_limit_per_user' => '', - 'limit_usage_to_x_items' => null, - 'free_shipping' => false, - 'product_categories' => array(), - 'excluded_product_categories' => array(), - 'exclude_sale_items' => false, - 'minimum_amount' => '0.00', - 'maximum_amount' => '0.00', - 'email_restrictions' => array(), - 'used_by' => array(), - 'meta_data' => array(), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/coupons/' . $coupon_1->get_id() ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/coupons' ), - ), - ), - ), - ), - $coupons - ); - } - - /** - * Test getting coupons without valid permissions. - * @since 3.5.0 - */ - public function test_get_coupons_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single coupon. - * @since 3.5.0 - */ - public function test_get_coupon() { - wp_set_current_user( $this->user ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $post = get_post( $coupon->get_id() ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $coupon->get_id(), - 'code' => 'dummycoupon-1', - 'amount' => '1.00', - 'date_created' => wc_rest_prepare_date_response( $post->post_date_gmt, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $post->post_date_gmt ), - 'date_modified' => wc_rest_prepare_date_response( $post->post_modified_gmt, false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $post->post_modified_gmt ), - 'discount_type' => 'fixed_cart', - 'description' => 'This is a dummy coupon', - 'date_expires' => null, - 'date_expires_gmt' => null, - 'usage_count' => 0, - 'individual_use' => false, - 'product_ids' => array(), - 'excluded_product_ids' => array(), - 'usage_limit' => null, - 'usage_limit_per_user' => null, - 'limit_usage_to_x_items' => null, - 'free_shipping' => false, - 'product_categories' => array(), - 'excluded_product_categories' => array(), - 'exclude_sale_items' => false, - 'minimum_amount' => '0.00', - 'maximum_amount' => '0.00', - 'email_restrictions' => array(), - 'used_by' => array(), - 'meta_data' => array(), - ), - $data - ); - } - - /** - * Test getting a single coupon with an invalid ID. - * @since 3.5.0 - */ - public function test_get_coupon_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single coupon without valid permissions. - * @since 3.5.0 - */ - public function test_get_coupon_without_permission() { - wp_set_current_user( 0 ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test creating a single coupon. - * @since 3.5.0 - */ - public function test_create_coupon() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'POST', '/wc/v3/coupons' ); - $request->set_body_params( - array( - 'code' => 'test', - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - 'description' => 'Test', - 'usage_limit' => 10, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'code' => 'test', - 'amount' => '5.00', - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'discount_type' => 'fixed_product', - 'description' => 'Test', - 'date_expires' => null, - 'date_expires_gmt' => null, - 'usage_count' => 0, - 'individual_use' => false, - 'product_ids' => array(), - 'excluded_product_ids' => array(), - 'usage_limit' => 10, - 'usage_limit_per_user' => null, - 'limit_usage_to_x_items' => null, - 'free_shipping' => false, - 'product_categories' => array(), - 'excluded_product_categories' => array(), - 'exclude_sale_items' => false, - 'minimum_amount' => '0.00', - 'maximum_amount' => '0.00', - 'email_restrictions' => array(), - 'used_by' => array(), - 'meta_data' => array(), - ), - $data - ); - } - - /** - * Test creating a single coupon with invalid fields. - * @since 3.5.0 - */ - public function test_create_coupon_invalid_fields() { - wp_set_current_user( $this->user ); - - // test no code... - $request = new WP_REST_Request( 'POST', '/wc/v3/coupons' ); - $request->set_body_params( - array( - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating a single coupon without valid permissions. - * @since 3.5.0 - */ - public function test_create_coupon_without_permission() { - wp_set_current_user( 0 ); - - // test no code... - $request = new WP_REST_Request( 'POST', '/wc/v3/coupons' ); - $request->set_body_params( - array( - 'code' => 'fail', - 'amount' => '5.00', - 'discount_type' => 'fixed_product', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single coupon. - * @since 3.5.0 - */ - public function test_update_coupon() { - wp_set_current_user( $this->user ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $post = get_post( $coupon->get_id() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/coupons/' . $coupon->get_id() ) ); - $data = $response->get_data(); - $this->assertEquals( 'This is a dummy coupon', $data['description'] ); - $this->assertEquals( 'fixed_cart', $data['discount_type'] ); - $this->assertEquals( '1.00', $data['amount'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/coupons/' . $coupon->get_id() ); - $request->set_body_params( - array( - 'amount' => '10.00', - 'description' => 'New description', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '10.00', $data['amount'] ); - $this->assertEquals( 'New description', $data['description'] ); - $this->assertEquals( 'fixed_cart', $data['discount_type'] ); - } - - /** - * Test updating a single coupon with an invalid ID. - * @since 3.5.0 - */ - public function test_update_coupon_invalid_id() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/coupons/0' ); - $request->set_body_params( - array( - 'code' => 'tester', - 'amount' => '10.00', - 'description' => 'New description', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test updating a single coupon without valid permissions. - * @since 3.5.0 - */ - public function test_update_coupon_without_permission() { - wp_set_current_user( 0 ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $post = get_post( $coupon->get_id() ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/coupons/' . $coupon->get_id() ); - $request->set_body_params( - array( - 'amount' => '10.00', - 'description' => 'New description', - ) - ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single coupon. - * @since 3.5.0 - */ - public function test_delete_coupon() { - wp_set_current_user( $this->user ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/' . $coupon->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test deleting a single coupon with an invalid ID. - * @since 3.5.0 - */ - public function test_delete_coupon_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test deleting a single coupon without valid permissions. - * @since 3.5.0 - */ - public function test_delete_coupon_without_permission() { - wp_set_current_user( 0 ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/coupons/' . $coupon->get_id() ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch operations on coupons. - * @since 3.5.0 - */ - public function test_batch_coupon() { - wp_set_current_user( $this->user ); - - $coupon_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-1' ); - $coupon_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-2' ); - $coupon_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-3' ); - $coupon_4 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'dummycoupon-4' ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/coupons/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $coupon_1->get_id(), - 'amount' => '5.15', - ), - ), - 'delete' => array( - $coupon_2->get_id(), - $coupon_3->get_id(), - ), - 'create' => array( - array( - 'code' => 'new-coupon', - 'amount' => '11.00', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '5.15', $data['update'][0]['amount'] ); - $this->assertEquals( '11.00', $data['create'][0]['amount'] ); - $this->assertEquals( 'new-coupon', $data['create'][0]['code'] ); - $this->assertEquals( $coupon_2->get_id(), $data['delete'][0]['id'] ); - $this->assertEquals( $coupon_3->get_id(), $data['delete'][1]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/coupons' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Test coupon schema. - * @since 3.5.0 - */ - public function test_coupon_schema() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/coupons' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 27, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'code', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_created_gmt', $properties ); - $this->assertArrayHasKey( 'date_modified', $properties ); - $this->assertArrayHasKey( 'date_modified_gmt', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'discount_type', $properties ); - $this->assertArrayHasKey( 'amount', $properties ); - $this->assertArrayHasKey( 'date_expires', $properties ); - $this->assertArrayHasKey( 'date_expires_gmt', $properties ); - $this->assertArrayHasKey( 'usage_count', $properties ); - $this->assertArrayHasKey( 'individual_use', $properties ); - $this->assertArrayHasKey( 'product_ids', $properties ); - $this->assertArrayHasKey( 'excluded_product_ids', $properties ); - $this->assertArrayHasKey( 'usage_limit', $properties ); - $this->assertArrayHasKey( 'usage_limit_per_user', $properties ); - $this->assertArrayHasKey( 'limit_usage_to_x_items', $properties ); - $this->assertArrayHasKey( 'free_shipping', $properties ); - $this->assertArrayHasKey( 'product_categories', $properties ); - $this->assertArrayHasKey( 'excluded_product_categories', $properties ); - $this->assertArrayHasKey( 'exclude_sale_items', $properties ); - $this->assertArrayHasKey( 'minimum_amount', $properties ); - $this->assertArrayHasKey( 'maximum_amount', $properties ); - $this->assertArrayHasKey( 'email_restrictions', $properties ); - $this->assertArrayHasKey( 'used_by', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/customers.php b/unit-tests/Tests/Version3/customers.php deleted file mode 100644 index 8d4508bade4..00000000000 --- a/unit-tests/Tests/Version3/customers.php +++ /dev/null @@ -1,634 +0,0 @@ -endpoint = new WC_REST_Customers_Controller(); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - - $this->assertArrayHasKey( '/wc/v3/customers', $routes ); - $this->assertArrayHasKey( '/wc/v3/customers/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v3/customers/batch', $routes ); - } - - /** - * Test getting customers. - * - * @since 3.5.0 - */ - public function test_get_customers() { - wp_set_current_user( 1 ); - - $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer(); - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test2', 'test2', 'test2@woo.local' ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); - $request->set_query_params( - array( - 'orderby' => 'id', - ) - ); - $response = $this->server->dispatch( $request ); - $customers = $response->get_data(); - $date_created = get_date_from_gmt( date( 'Y-m-d H:i:s', strtotime( $customer_1->get_date_created() ) ) ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $customers ) ); - - $this->assertContains( - array( - 'id' => $customer_1->get_id(), - 'date_created' => wc_rest_prepare_date_response( $date_created, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $date_created ), - 'date_modified' => wc_rest_prepare_date_response( $customer_1->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_1->get_date_modified() ), - 'email' => 'test@woo.local', - 'first_name' => 'Justin', - 'last_name' => '', - 'role' => 'customer', - 'username' => 'testcustomer', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'avatar_url' => $customer_1->get_avatar_url(), - 'meta_data' => array(), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/customers/' . $customer_1->get_id() . '' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/customers' ), - ), - ), - ), - ), - $customers - ); - - update_option( 'timezone_tring', 'America/New York' ); - $customer_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'timezonetest', 'timezonetest', 'timezonetest@woo.local' ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); - $request->set_query_params( - array( - 'orderby' => 'id', - ) - ); - $response = $this->server->dispatch( $request ); - $customers = $response->get_data(); - $date_created = get_date_from_gmt( date( 'Y-m-d H:i:s', strtotime( $customer_3->get_date_created() ) ) ); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertContains( - array( - 'id' => $customer_3->get_id(), - 'date_created' => wc_rest_prepare_date_response( $date_created, false ), - 'date_created_gmt' => wc_rest_prepare_date_response( $date_created ), - 'date_modified' => wc_rest_prepare_date_response( $customer_3->get_date_modified(), false ), - 'date_modified_gmt' => wc_rest_prepare_date_response( $customer_3->get_date_modified() ), - 'email' => 'timezonetest@woo.local', - 'first_name' => 'Justin', - 'last_name' => '', - 'role' => 'customer', - 'username' => 'timezonetest', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'avatar_url' => $customer_3->get_avatar_url(), - 'meta_data' => array(), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/customers/' . $customer_3->get_id() . '' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/customers' ), - ), - ), - ), - ), - $customers - ); - - } - - /** - * Test getting customers without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_customers_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test creating a new customer. - * - * @since 3.5.0 - */ - public function test_create_customer() { - wp_set_current_user( 1 ); - - // Test just the basics first.. - $request = new WP_REST_Request( 'POST', '/wc/v3/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test', - 'password' => 'test123', - 'email' => 'create_customer_test@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'create_customer_test@woo.local', - 'first_name' => '', - 'last_name' => '', - 'role' => 'customer', - 'username' => 'create_customer_test', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => '', - 'postcode' => '', - 'country' => '', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => '', - 'postcode' => '', - 'country' => '', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - - // Test extra data. - $request = new WP_REST_Request( 'POST', '/wc/v3/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test2', - 'password' => 'test123', - 'email' => 'create_customer_test2@woo.local', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - 'billing' => array( - 'country' => 'US', - 'state' => 'WA', - ), - 'shipping' => array( - 'state' => 'CA', - 'country' => 'US', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'create_customer_test2@woo.local', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - 'role' => 'customer', - 'username' => 'create_customer_test2', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => 'WA', - 'postcode' => '', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '', - 'address_2' => '', - 'city' => '', - 'state' => 'CA', - 'postcode' => '', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - - // Test without required field. - $request = new WP_REST_Request( 'POST', '/wc/v3/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test3', - 'first_name' => 'Test', - 'last_name' => 'McTestFace', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating customers without valid permissions. - * - * @since 3.5.0 - */ - public function test_create_customer_without_permission() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'POST', '/wc/v3/customers' ); - $request->set_body_params( - array( - 'username' => 'create_customer_test_without_permission', - 'password' => 'test123', - 'email' => 'create_customer_test_without_permission@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single customer. - * - * @since 3.5.0 - */ - public function test_get_customer() { - wp_set_current_user( 1 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test', 'test123', 'get_customer_test@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'date_modified' => $data['date_modified'], - 'date_modified_gmt' => $data['date_modified_gmt'], - 'email' => 'get_customer_test@woo.local', - 'first_name' => 'Justin', - 'billing' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - 'email' => '', - 'phone' => '', - ), - 'shipping' => array( - 'first_name' => '', - 'last_name' => '', - 'company' => '', - 'address_1' => '123 South Street', - 'address_2' => 'Apt 1', - 'city' => 'Philadelphia', - 'state' => 'PA', - 'postcode' => '19123', - 'country' => 'US', - ), - 'is_paying_customer' => false, - 'meta_data' => array(), - 'last_name' => '', - 'role' => 'customer', - 'username' => 'get_customer_test', - 'avatar_url' => $data['avatar_url'], - ), - $data - ); - } - - /** - * Test getting a single customer without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'get_customer_test_without_permission', 'test123', 'get_customer_test_without_permission@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single customer with an invalid ID. - * - * @since 3.5.0 - */ - public function test_get_customer_invalid_id() { - wp_set_current_user( 1 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a customer. - * - * @since 3.5.0 - */ - public function test_update_customer() { - wp_set_current_user( 1 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test', 'test123', 'update_customer_test@woo.local' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); - $data = $response->get_data(); - $this->assertEquals( 'update_customer_test', $data['username'] ); - $this->assertEquals( 'update_customer_test@woo.local', $data['email'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/customers/' . $customer->get_id() ); - $request->set_body_params( - array( - 'email' => 'updated_email@woo.local', - 'first_name' => 'UpdatedTest', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'updated_email@woo.local', $data['email'] ); - $this->assertEquals( 'UpdatedTest', $data['first_name'] ); - } - - /** - * Test updating a customer without valid permissions. - * - * @since 3.5.0 - */ - public function test_update_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'update_customer_test_without_permission', 'test123', 'update_customer_test_without_permission@woo.local' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/' . $customer->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a customer with an invalid ID. - * - * @since 3.5.0 - */ - public function test_update_customer_invalid_id() { - wp_set_current_user( 1 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/customers/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - - /** - * Test deleting a customer. - * - * @since 3.5.0 - */ - public function test_delete_customer() { - wp_set_current_user( 1 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test', 'test123', 'delete_customer_test@woo.local' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/' . $customer->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test deleting a customer with an invalid ID. - * - * @since 3.5.0 - */ - public function test_delete_customer_invalid_id() { - wp_set_current_user( 1 ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test deleting a customer without valid permissions. - * - * @since 3.5.0 - */ - public function test_delete_customer_without_permission() { - wp_set_current_user( 0 ); - $customer = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'delete_customer_test_without_permission', 'test123', 'delete_customer_test_without_permission@woo.local' ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/customers/' . $customer->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test customer batch endpoint. - * - * @since 3.5.0 - */ - public function test_batch_customer() { - wp_set_current_user( 1 ); - - $customer_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer', 'test123', 'test_batch_customer@woo.local' ); - $customer_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer2', 'test123', 'test_batch_customer2@woo.local' ); - $customer_3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer3', 'test123', 'test_batch_customer3@woo.local' ); - $customer_4 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CustomerHelper::create_customer( 'test_batch_customer4', 'test123', 'test_batch_customer4@woo.local' ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/customers/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $customer_1->get_id(), - 'last_name' => 'McTest', - ), - ), - 'delete' => array( - $customer_2->get_id(), - $customer_3->get_id(), - ), - 'create' => array( - array( - 'username' => 'newuser', - 'password' => 'test123', - 'email' => 'newuser@woo.local', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'McTest', $data['update'][0]['last_name'] ); - $this->assertEquals( 'newuser', $data['create'][0]['username'] ); - $this->assertEmpty( $data['create'][0]['last_name'] ); - $this->assertEquals( $customer_2->get_id(), $data['delete'][0]['id'] ); - $this->assertEquals( $customer_3->get_id(), $data['delete'][1]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/customers' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Test customer schema. - * - * @since 3.5.0 - */ - public function test_customer_schema() { - wp_set_current_user( 1 ); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/customers' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 16, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_created_gmt', $properties ); - $this->assertArrayHasKey( 'date_modified', $properties ); - $this->assertArrayHasKey( 'date_modified_gmt', $properties ); - $this->assertArrayHasKey( 'email', $properties ); - $this->assertArrayHasKey( 'first_name', $properties ); - $this->assertArrayHasKey( 'last_name', $properties ); - $this->assertArrayHasKey( 'role', $properties ); - $this->assertArrayHasKey( 'username', $properties ); - $this->assertArrayHasKey( 'password', $properties ); - $this->assertArrayHasKey( 'avatar_url', $properties ); - $this->assertArrayHasKey( 'billing', $properties ); - $this->assertArrayHasKey( 'first_name', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'last_name', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'company', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'address_1', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'address_2', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'city', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'state', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'postcode', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'country', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'email', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'phone', $properties['billing']['properties'] ); - $this->assertArrayHasKey( 'shipping', $properties ); - $this->assertArrayHasKey( 'first_name', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'last_name', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'company', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'address_1', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'address_2', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'city', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'state', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'postcode', $properties['shipping']['properties'] ); - $this->assertArrayHasKey( 'country', $properties['shipping']['properties'] ); - } -} diff --git a/unit-tests/Tests/Version3/functions.php b/unit-tests/Tests/Version3/functions.php deleted file mode 100644 index 3b3b27eb5c9..00000000000 --- a/unit-tests/Tests/Version3/functions.php +++ /dev/null @@ -1,251 +0,0 @@ -http_responder = array( $this, 'mock_http_responses' ); - - $upload_dir_info = wp_upload_dir(); - $this->upload_dir_path = $upload_dir_info['path']; - $this->upload_dir_url = $upload_dir_info['url']; - $this->file_name = 'Dr1Bczxq4q.png'; - } - - /** - * Run tear down code for unit tests. - */ - public function tearDown() { - parent::tearDown(); - - // remove files created in the wc_rest_upload_image_from_url() tests. - $file_path = $this->upload_dir_path . '/' . $this->file_name; - - if ( file_exists( $file_path ) ) { - unlink( $file_path ); - } - } - - /** - * Test wc_rest_prepare_date_response(). - * - * @since 2.6.0 - */ - public function test_wc_rest_prepare_date_response() { - $this->assertEquals( '2016-06-06T06:06:06', wc_rest_prepare_date_response( '2016-06-06 06:06:06' ) ); - } - - /** - * Test wc_rest_upload_image_from_url() should return error when unable to download image. - */ - public function test_wc_rest_upload_image_from_url_should_return_error_when_unable_to_download_image() { - $expected_error_message = 'Error getting remote image http://somedomain.com/nonexistent-image.png. Error: Not found.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/nonexistent-image.png' ); - - $this->assertWPError( $result ); - $this->assertEquals( $expected_error_message, $result->get_error_message() ); - } - - /** - * Test wc_rest_upload_image_from_url() should return error when invalid image is passed. - * - * @requires PHP 5.4 - */ - public function test_wc_rest_upload_image_from_url_should_return_error_when_invalid_image_is_passed() { - // empty file. - $expected_error_message = 'Invalid image: File is empty.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-1.png' ); - - $this->assertWPError( $result ); - $this->assertStringStartsWith( $expected_error_message, $result->get_error_message() ); - - // unsupported mime type. - $expected_error_message = 'Invalid image: Sorry, this file type is not permitted for security reasons.'; - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/invalid-image-2.png' ); - - $this->assertWPError( $result ); - $this->assertEquals( $expected_error_message, $result->get_error_message() ); - } - - /** - * Test wc_rest_upload_image_from_url() should download image and return an array containing - * information about it. - * - * @requires PHP 5.4 - */ - public function test_wc_rest_upload_image_from_url_should_download_image_and_return_array() { - $expected_result = array( - 'file' => $this->upload_dir_path . '/' . $this->file_name, - 'url' => $this->upload_dir_url . '/' . $this->file_name, - 'type' => 'image/png', - ); - $result = wc_rest_upload_image_from_url( 'http://somedomain.com/' . $this->file_name ); - - $this->assertEquals( $expected_result, $result ); - } - - /** - * Test wc_rest_set_uploaded_image_as_attachment(). - * - * @since 2.6.0 - */ - public function test_wc_rest_set_uploaded_image_as_attachment() { - $this->assertInternalType( - 'int', - wc_rest_set_uploaded_image_as_attachment( - array( - 'file' => '', - 'url' => '', - ) - ) - ); - } - - /** - * Test wc_rest_validate_reports_request_arg(). - * - * @since 2.6.0 - */ - public function test_wc_rest_validate_reports_request_arg() { - $request = new WP_REST_Request( - 'GET', - '/wc/v3/foo', - array( - 'args' => array( - 'date' => array( - 'type' => 'string', - 'format' => 'date', - ), - ), - ) - ); - - // Success. - $this->assertTrue( wc_rest_validate_reports_request_arg( '2016-06-06', $request, 'date' ) ); - - // Error. - $error = wc_rest_validate_reports_request_arg( 'foo', $request, 'date' ); - $this->assertEquals( 'The date you provided is invalid.', $error->get_error_message() ); - } - - /** - * Test wc_rest_urlencode_rfc3986(). - * - * @since 2.6.0 - */ - public function test_wc_rest_urlencode_rfc3986() { - $this->assertEquals( 'https%3A%2F%2Fwoocommerce.com%2F', wc_rest_urlencode_rfc3986( 'https://woocommerce.com/' ) ); - } - - /** - * Test wc_rest_check_post_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_post_permissions() { - $this->assertFalse( wc_rest_check_post_permissions( 'shop_order' ) ); - } - - /** - * Test wc_rest_check_user_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_user_permissions() { - $this->assertFalse( wc_rest_check_user_permissions() ); - } - - /** - * Test wc_rest_check_product_term_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_product_term_permissions() { - $this->assertFalse( wc_rest_check_product_term_permissions( 'product_cat' ) ); - } - - /** - * Test wc_rest_check_manager_permissions(). - * - * @since 2.6.0 - */ - public function test_wc_rest_check_manager_permissions() { - $this->assertFalse( wc_rest_check_manager_permissions( 'reports' ) ); - } - - /** - * Helper method to define mocked HTTP responses using WP_HTTP_TestCase. - * Thanks to WP_HTTP_TestCase, it is not necessary to perform a regular request - * to an external server which would significantly slow down the tests. - * - * This function is called by WP_HTTP_TestCase::http_request_listner(). - * - * @param array $request Request arguments. - * @param string $url URL of the request. - * - * @return array|false mocked response or false to let WP perform a regular request. - */ - protected function mock_http_responses( $request, $url ) { - $mocked_response = false; - - if ( 'http://somedomain.com/nonexistent-image.png' === $url ) { - $mocked_response = array( - 'response' => array( - 'code' => 404, - 'message' => 'Not found.', - ), - ); - } elseif ( 'http://somedomain.com/invalid-image-1.png' === $url ) { - // empty image. - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } elseif ( 'http://somedomain.com/invalid-image-2.png' === $url ) { - // image with an unsupported mime type. - // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( Automattic\WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/file.txt', $request['filename'] ); - - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } elseif ( 'http://somedomain.com/' . $this->file_name === $url ) { - // we need to manually copy the file as we are mocking the request. without this an empty file is created. - copy( Automattic\WooCommerce\RestApi\UnitTests\Bootstrap::instance()->get_dir() . '/data/Dr1Bczxq4q.png', $request['filename'] ); - - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } - - return $mocked_response; - } -} diff --git a/unit-tests/Tests/Version3/orders.php b/unit-tests/Tests/Version3/orders.php deleted file mode 100644 index 6ebb7477ae0..00000000000 --- a/unit-tests/Tests/Version3/orders.php +++ /dev/null @@ -1,778 +0,0 @@ -endpoint = new WC_REST_Orders_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/orders', $routes ); - $this->assertArrayHasKey( '/wc/v3/orders/batch', $routes ); - $this->assertArrayHasKey( '/wc/v3/orders/(?P[\d]+)', $routes ); - } - - /** - * Test getting all orders. - * @since 3.5.0 - */ - public function test_get_items() { - wp_set_current_user( $this->user ); - - // Create 10 orders. - for ( $i = 0; $i < 10; $i++ ) { - $this->orders[] = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders' ) ); - $orders = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 10, count( $orders ) ); - } - - /** - * Test getting all orders sorted by modified date. - */ - public function test_get_items_ordered_by_modified() { - wp_set_current_user( $this->user ); - - $order1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); - $order2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( $this->user ); - - $order1->set_status( 'completed' ); - $order1->save(); - sleep( 1 ); - $order2->set_status( 'completed' ); - $order2->save(); - - $request = new WP_REST_Request( 'GET', '/wc/v3/orders' ); - $request->set_query_params( array( 'orderby' => 'modified', 'order' => 'asc' ) ); - $response = $this->server->dispatch( $request ); - $orders = $response->get_data(); - $this->assertEquals( $order1->get_id(), $orders[0]['id'] ); - - $request->set_query_params( array( 'orderby' => 'modified', 'order' => 'desc' ) ); - $response = $this->server->dispatch( $request ); - $orders = $response->get_data(); - $this->assertEquals( $order2->get_id(), $orders[0]['id'] ); - } - - /** - * Tests to make sure orders cannot be viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_items_without_permission() { - wp_set_current_user( 0 ); - $this->orders[] = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a single order. - * @since 3.5.0 - */ - public function test_get_item() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order->add_meta_data( 'key', 'value' ); - $order->add_meta_data( 'key2', 'value2' ); - $order->save(); - $this->orders[] = $order; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $order->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $order->get_id(), $data['id'] ); - - // Test meta data is set. - $this->assertEquals( 'key', $data['meta_data'][0]->key ); - $this->assertEquals( 'value', $data['meta_data'][0]->value ); - $this->assertEquals( 'key2', $data['meta_data'][1]->key ); - $this->assertEquals( 'value2', $data['meta_data'][1]->value ); - } - - /** - * Tests getting a single order without the correct permissions. - * @since 3.5.0 - */ - public function test_get_item_without_permission() { - wp_set_current_user( 0 ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $this->orders[] = $order; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $order->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting an order with an invalid ID. - * @since 3.5.0 - */ - public function test_get_item_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/99999999' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests getting an order with an invalid ID. - * @since 3.5.0 - */ - public function test_get_item_refund_id() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $refund = wc_create_refund( - array( - 'order_id' => $order->get_id(), - ) - ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/orders/' . $refund->get_id() ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests creating an order. - * @since 3.5.0 - */ - public function test_create_order() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); - $request->set_body_params( - array( - 'payment_method' => 'bacs', - 'payment_method_title' => 'Direct Bank Transfer', - 'set_paid' => true, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => '10.00', - 'instance_id' => '1', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $order = wc_get_order( $data['id'] ); - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); - $this->assertEquals( $order->get_payment_method_title(), $data['payment_method_title'] ); - $this->assertEquals( $order->get_billing_first_name(), $data['billing']['first_name'] ); - $this->assertEquals( $order->get_billing_last_name(), $data['billing']['last_name'] ); - $this->assertEquals( '', $data['billing']['company'] ); - $this->assertEquals( $order->get_billing_address_1(), $data['billing']['address_1'] ); - $this->assertEquals( $order->get_billing_address_2(), $data['billing']['address_2'] ); - $this->assertEquals( $order->get_billing_city(), $data['billing']['city'] ); - $this->assertEquals( $order->get_billing_state(), $data['billing']['state'] ); - $this->assertEquals( $order->get_billing_postcode(), $data['billing']['postcode'] ); - $this->assertEquals( $order->get_billing_country(), $data['billing']['country'] ); - $this->assertEquals( $order->get_billing_email(), $data['billing']['email'] ); - $this->assertEquals( $order->get_billing_phone(), $data['billing']['phone'] ); - $this->assertEquals( $order->get_shipping_first_name(), $data['shipping']['first_name'] ); - $this->assertEquals( $order->get_shipping_last_name(), $data['shipping']['last_name'] ); - $this->assertEquals( '', $data['shipping']['company'] ); - $this->assertEquals( $order->get_shipping_address_1(), $data['shipping']['address_1'] ); - $this->assertEquals( $order->get_shipping_address_2(), $data['shipping']['address_2'] ); - $this->assertEquals( $order->get_shipping_city(), $data['shipping']['city'] ); - $this->assertEquals( $order->get_shipping_state(), $data['shipping']['state'] ); - $this->assertEquals( $order->get_shipping_postcode(), $data['shipping']['postcode'] ); - $this->assertEquals( $order->get_shipping_country(), $data['shipping']['country'] ); - $this->assertEquals( 1, count( $data['line_items'] ) ); - $this->assertEquals( 1, count( $data['shipping_lines'] ) ); - $shipping = current( $order->get_items( 'shipping' ) ); - $expected = array( - 'id' => $shipping->get_id(), - 'method_title' => $shipping->get_method_title(), - 'method_id' => $shipping->get_method_id(), - 'instance_id' => $shipping->get_instance_id(), - 'total' => wc_format_decimal( $shipping->get_total(), '' ), - 'total_tax' => wc_format_decimal( $shipping->get_total_tax(), '' ), - 'taxes' => array(), - 'meta_data' => $shipping->get_meta_data(), - ); - $this->assertEquals( $expected, $data['shipping_lines'][0] ); - } - - /** - * Test the sanitization of the payment_method_title field through the API. - * - * @since 3.5.2 - */ - public function test_create_update_order_payment_method_title_sanitize() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - // Test when creating order. - $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); - $request->set_body_params( - array( - 'payment_method' => 'bacs', - 'payment_method_title' => '

Sanitize this

', - 'set_paid' => true, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => '10', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $order = wc_get_order( $data['id'] ); - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); - $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this' ); - - // Test when updating order. - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $data['id'] ); - $request->set_body_params( - array( - 'payment_method' => 'bacs', - 'payment_method_title' => '

Sanitize this too

', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $order = wc_get_order( $data['id'] ); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $order->get_payment_method(), $data['payment_method'] ); - $this->assertEquals( $order->get_payment_method_title(), 'Sanitize this too' ); - } - - /** - * Tests creating an order without required fields. - * @since 3.5.0 - */ - public function test_create_order_invalid_fields() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - // Non-existent customer. - $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); - $request->set_body_params( - array( - 'payment_method' => 'bacs', - 'payment_method_title' => 'Direct Bank Transfer', - 'set_paid' => true, - 'customer_id' => 99999, - 'billing' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - 'email' => 'john.doe@example.com', - 'phone' => '(555) 555-5555', - ), - 'shipping' => array( - 'first_name' => 'John', - 'last_name' => 'Doe', - 'address_1' => '969 Market', - 'address_2' => '', - 'city' => 'San Francisco', - 'state' => 'CA', - 'postcode' => '94103', - 'country' => 'US', - ), - 'line_items' => array( - array( - 'product_id' => $product->get_id(), - 'quantity' => 2, - ), - ), - 'shipping_lines' => array( - array( - 'method_id' => 'flat_rate', - 'method_title' => 'Flat rate', - 'total' => 10, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Tests create an order with an invalid product. - * - * @since 3.9.0 - */ - public function test_create_order_with_invalid_product() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/orders' ); - $request->set_body_params( - array( - 'line_items' => array( - array( - 'quantity' => 2, - ), - ), - ) - ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 'woocommerce_rest_required_product_reference', $data['code'] ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Tests updating an order. - * - * @since 3.5.0 - */ - public function test_update_order() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); - $request->set_body_params( - array( - 'payment_method' => 'test-update', - 'billing' => array( - 'first_name' => 'Fish', - 'last_name' => 'Face', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'test-update', $data['payment_method'] ); - $this->assertEquals( 'Fish', $data['billing']['first_name'] ); - $this->assertEquals( 'Face', $data['billing']['last_name'] ); - } - - /** - * Tests updating an order and removing items. - * - * @since 3.5.0 - */ - public function test_update_order_remove_items() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $fee = new WC_Order_Item_Fee(); - $fee->set_props( - array( - 'name' => 'Some Fee', - 'tax_status' => 'taxable', - 'total' => '100', - 'tax_class' => '', - ) - ); - $order->add_item( $fee ); - $order->save(); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); - $fee_data = current( $order->get_items( 'fee' ) ); - - $request->set_body_params( - array( - 'fee_lines' => array( - array( - 'id' => $fee_data->get_id(), - 'name' => null, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertTrue( empty( $data['fee_lines'] ) ); - } - - /** - * Tests updating an order after deleting a product. - * - * @since 3.9.0 - */ - public function test_update_order_after_delete_product() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order( 1, $product ); - $product->delete( true ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); - $line_items = $order->get_items( 'line_item' ); - $item = current( $line_items ); - - $request->set_body_params( - array( - 'line_items' => array( - array( - 'id' => $item->get_id(), - 'quantity' => 10, - ), - ), - ) - ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $expected = array( - 'id' => $item->get_id(), - 'name' => 'Dummy Product', - 'product_id' => 0, - 'variation_id' => 0, - 'quantity' => 10, - 'tax_class' => '', - 'subtotal' => '40.00', - 'subtotal_tax' => '0.00', - 'total' => '40.00', - 'total_tax' => '0.00', - 'taxes' => array(), - 'meta_data' => array(), - 'sku' => null, - 'price' => 4, - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $expected, $data['line_items'][0] ); - } - - /** - * Tests updating an order and adding a coupon. - * - * @since 3.5.0 - */ - public function test_update_order_add_coupons() { - wp_set_current_user( $this->user ); - - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order_item = current( $order->get_items() ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); - $coupon->set_amount( 5 ); - $coupon->save(); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); - $request->set_body_params( - array( - 'coupon_lines' => array( - array( - 'code' => 'fake-coupon', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $data['coupon_lines'] ); - $this->assertEquals( '45.00', $data['total'] ); - } - - /** - * Tests updating an order and removing a coupon. - * - * @since 3.5.0 - */ - public function test_update_order_remove_coupons() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order_item = current( $order->get_items() ); - $coupon = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\CouponHelper::create_coupon( 'fake-coupon' ); - $coupon->set_amount( 5 ); - $coupon->save(); - - $order->apply_coupon( $coupon ); - $order->save(); - - // Check that the coupon is applied. - $this->assertEquals( '45.00', $order->get_total() ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); - $coupon_data = current( $order->get_items( 'coupon' ) ); - - $request->set_body_params( - array( - 'coupon_lines' => array( - array( - 'id' => $coupon_data->get_id(), - 'code' => null, - ), - ), - 'line_items' => array( - array( - 'id' => $order_item->get_id(), - 'product_id' => $order_item->get_product_id(), - 'total' => '40.00', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertTrue( empty( $data['coupon_lines'] ) ); - $this->assertEquals( '50.00', $data['total'] ); - } - - /** - * Tests updating an order with an invalid coupon. - * - * @since 3.5.0 - */ - public function test_invalid_coupon() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); - - $request->set_body_params( - array( - 'coupon_lines' => array( - array( - 'code' => 'NON_EXISTING_COUPON', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - $this->assertEquals( 'woocommerce_rest_invalid_coupon', $data['code'] ); - $this->assertEquals( 'Coupon "non_existing_coupon" does not exist!', $data['message'] ); - } - - /** - * Tests updating an order without the correct permissions. - * - * @since 3.5.0 - */ - public function test_update_order_without_permission() { - wp_set_current_user( 0 ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'PUT', '/wc/v3/orders/' . $order->get_id() ); - $request->set_body_params( - array( - 'payment_method' => 'test-update', - 'billing' => array( - 'first_name' => 'Fish', - 'last_name' => 'Face', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests that updating an order with an invalid id fails. - * - * @since 3.5.0 - */ - public function test_update_order_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'POST', '/wc/v3/orders/999999' ); - $request->set_body_params( - array( - 'payment_method' => 'test-update', - 'billing' => array( - 'first_name' => 'Fish', - 'last_name' => 'Face', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test deleting an order. - * - * @since 3.5.0 - */ - public function test_delete_order() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/' . $order->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( null, get_post( $order->get_id() ) ); - } - - /** - * Test deleting an order without permission/creds. - * - * @since 3.5.0 - */ - public function test_delete_order_without_permission() { - wp_set_current_user( 0 ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/' . $order->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting an order with an invalid id. - * - * @since 3.5.0 - */ - public function test_delete_order_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/orders/9999999' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test batch managing product reviews. - * - * @since 3.5.0 - */ - public function test_orders_batch() { - wp_set_current_user( $this->user ); - - $order1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $order3 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - - $request = new WP_REST_Request( 'POST', '/wc/v3/orders/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $order1->get_id(), - 'payment_method' => 'updated', - ), - ), - 'delete' => array( - $order2->get_id(), - $order3->get_id(), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'updated', $data['update'][0]['payment_method'] ); - $this->assertEquals( $order2->get_id(), $data['delete'][0]['id'] ); - $this->assertEquals( $order3->get_id(), $data['delete'][1]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/orders' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 1, count( $data ) ); - } - - /** - * Test the order schema. - * - * @since 3.5.0 - */ - public function test_order_schema() { - wp_set_current_user( $this->user ); - $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/orders/' . $order->get_id() ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 42, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/payment-gateways.php b/unit-tests/Tests/Version3/payment-gateways.php deleted file mode 100644 index f9a43b64e5f..00000000000 --- a/unit-tests/Tests/Version3/payment-gateways.php +++ /dev/null @@ -1,345 +0,0 @@ -endpoint = new WC_REST_Payment_Gateways_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/payment_gateways', $routes ); - $this->assertArrayHasKey( '/wc/v3/payment_gateways/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all payment gateways. - * - * @since 3.5.0 - */ - public function test_get_payment_gateways() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways' ) ); - $gateways = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => 'cheque', - 'title' => 'Check payments', - 'description' => 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', - 'order' => '', - 'enabled' => false, - 'method_title' => 'Check payments', - 'method_description' => 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', - 'method_supports' => array( - 'products', - ), - 'settings' => array_diff_key( - $this->get_settings( 'WC_Gateway_Cheque' ), - array( - 'enabled' => false, - 'description' => false, - ) - ), - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/payment_gateways/cheque' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/payment_gateways' ), - ), - ), - ), - ), - $gateways - ); - } - - /** - * Tests to make sure payment gateways cannot viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_payment_gateways_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single payment gateway. - * - * @since 3.5.0 - */ - public function test_get_payment_gateway() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/paypal' ) ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => 'paypal', - 'title' => 'PayPal', - 'description' => "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account.", - 'order' => '', - 'enabled' => false, - 'method_title' => 'PayPal', - 'method_description' => 'PayPal Standard redirects customers to PayPal to enter their payment information.', - 'method_supports' => array( - 'products', - 'refunds', - ), - 'settings' => array_diff_key( - $this->get_settings( 'WC_Gateway_Paypal' ), - array( - 'enabled' => false, - 'description' => false, - ) - ), - ), - $paypal - ); - } - - /** - * Test getting a payment gateway without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_payment_gateway_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/paypal' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a payment gateway with an invalid id. - * - * @since 3.5.0 - */ - public function test_get_payment_gateway_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/totally_fake_method' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a single payment gateway. - * - * @since 3.5.0 - */ - public function test_update_payment_gateway() { - wp_set_current_user( $this->user ); - - // Test defaults - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/paypal' ) ); - $paypal = $response->get_data(); - - $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'admin@example.org', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); - - // test updating single setting - $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'email' => 'woo@woo.local', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'PayPal', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'no', $paypal['settings']['testmode']['value'] ); - - // test updating multiple settings - $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'testmode' => 'yes', - 'title' => 'PayPal - New Title', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); - - // Test other parameters, and recheck settings - $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - - $this->assertFalse( $paypal['enabled'] ); - $this->assertEquals( 2, $paypal['order'] ); - $this->assertEquals( 'PayPal - New Title', $paypal['settings']['title']['value'] ); - $this->assertEquals( 'woo@woo.local', $paypal['settings']['email']['value'] ); - $this->assertEquals( 'yes', $paypal['settings']['testmode']['value'] ); - - // test bogus - $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'paymentaction' => 'afasfasf', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'paymentaction' => 'authorization', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $paypal = $response->get_data(); - $this->assertEquals( 'authorization', $paypal['settings']['paymentaction']['value'] ); - } - - /** - * Test updating a payment gateway without valid permissions. - * - * @since 3.5.0 - */ - public function test_update_payment_gateway_without_permission() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/paypal' ); - $request->set_body_params( - array( - 'settings' => array( - 'testmode' => 'yes', - 'title' => 'PayPal - New Title', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a payment gateway with an invalid id. - * - * @since 3.5.0 - */ - public function test_update_payment_gateway_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/totally_fake_method' ); - $request->set_body_params( - array( - 'enabled' => true, - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test the payment gateway schema. - * - * @since 3.5.0 - */ - public function test_payment_gateway_schema() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/payment_gateways' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 9, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'title', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'order', $properties ); - $this->assertArrayHasKey( 'enabled', $properties ); - $this->assertArrayHasKey( 'method_title', $properties ); - $this->assertArrayHasKey( 'method_description', $properties ); - $this->assertArrayHasKey( 'method_supports', $properties ); - $this->assertArrayHasKey( 'settings', $properties ); - } - - /** - * Loads a particular gateway's settings so we can correctly test API output. - * - * @since 3.5.0 - * @param string $gateway_class Name of WC_Payment_Gateway class. - */ - private function get_settings( $gateway_class ) { - $gateway = new $gateway_class(); - $settings = array(); - $gateway->init_form_fields(); - foreach ( $gateway->form_fields as $id => $field ) { - // Make sure we at least have a title and type - if ( empty( $field['title'] ) || empty( $field['type'] ) ) { - continue; - } - // Ignore 'enabled' and 'description', to be in line with \WC_REST_Payment_Gateways_Controller::get_settings. - if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { - continue; - } - $data = array( - 'id' => $id, - 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], - 'description' => empty( $field['description'] ) ? '' : $field['description'], - 'type' => $field['type'], - 'value' => $gateway->settings[ $id ], - 'default' => empty( $field['default'] ) ? '' : $field['default'], - 'tip' => empty( $field['description'] ) ? '' : $field['description'], - 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - return $settings; - } - -} diff --git a/unit-tests/Tests/Version3/product-reviews.php b/unit-tests/Tests/Version3/product-reviews.php deleted file mode 100644 index 9a69f06a863..00000000000 --- a/unit-tests/Tests/Version3/product-reviews.php +++ /dev/null @@ -1,470 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/products/reviews', $routes ); - $this->assertArrayHasKey( '/wc/v3/products/reviews/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v3/products/reviews/batch', $routes ); - } - - /** - * Test getting all product reviews. - * - * @since 3.5.0 - */ - public function test_get_product_reviews() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - // Create 10 products reviews for the product - for ( $i = 0; $i < 10; $i++ ) { - $review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); - $product_reviews = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 10, count( $product_reviews ) ); - $this->assertContains( - array( - 'id' => $review_id, - 'date_created' => $product_reviews[0]['date_created'], - 'date_created_gmt' => $product_reviews[0]['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => "

Review content here

\n", - 'rating' => 0, - 'verified' => false, - 'reviewer_avatar_urls' => $product_reviews[0]['reviewer_avatar_urls'], - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/products/reviews/' . $review_id ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/products/reviews' ), - ), - ), - 'up' => array( - array( - 'href' => rest_url( '/wc/v3/products/' . $product->get_id() ), - ), - ), - ), - ), - $product_reviews - ); - } - - /** - * Tests to make sure product reviews cannot be viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_product_reviews_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests to make sure an error is returned when an invalid product is loaded. - * - * @since 3.5.0 - */ - public function test_get_product_reviews_invalid_product() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/0/reviews' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests getting a single product review. - * - * @since 3.5.0 - */ - public function test_get_product_review() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $product_review_id, - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => "

Review content here

\n", - 'rating' => 0, - 'verified' => false, - 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], - ), - $data - ); - } - - /** - * Tests getting a single product review without the correct permissions. - * - * @since 3.5.0 - */ - public function test_get_product_review_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a product review with an invalid ID. - * - * @since 3.5.0 - */ - public function test_get_product_review_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/0' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests creating a product review. - * - * @since 3.5.0 - */ - public function test_create_product_review() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - 'rating' => '5', - 'product_id' => $product->get_id(), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'date_created' => $data['date_created'], - 'date_created_gmt' => $data['date_created_gmt'], - 'product_id' => $product->get_id(), - 'status' => 'approved', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - 'review' => 'Hello world.', - 'rating' => 5, - 'verified' => false, - 'reviewer_avatar_urls' => $data['reviewer_avatar_urls'], - ), - $data - ); - } - - /** - * Tests creating a product review without required fields. - * - * @since 3.5.0 - */ - public function test_create_product_review_invalid_fields() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - // missing review - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); - $request->set_body_params( - array( - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - - // Missing reviewer. - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer_email' => 'woo@woo.local', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - - // missing reviewer_email - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Tests updating a product review. - * - * @since 3.5.0 - */ - public function test_update_product_review() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/reviews/' . $product_review_id ) ); - $data = $response->get_data(); - $this->assertEquals( "

Review content here

\n", $data['review'] ); - $this->assertEquals( 'admin', $data['reviewer'] ); - $this->assertEquals( 'woo@woo.local', $data['reviewer_email'] ); - $this->assertEquals( 0, $data['rating'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); - $request->set_body_params( - array( - 'review' => 'Hello world - updated.', - 'reviewer' => 'Justin', - 'reviewer_email' => 'woo2@woo.local', - 'rating' => 3, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 'Hello world - updated.', $data['review'] ); - $this->assertEquals( 'Justin', $data['reviewer'] ); - $this->assertEquals( 'woo2@woo.local', $data['reviewer_email'] ); - $this->assertEquals( 3, $data['rating'] ); - } - - /** - * Tests updating a product review without the correct permissions. - * - * @since 3.5.0 - */ - public function test_update_product_review_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/' . $product_review_id ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.dev', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests that updating a product review with an invalid id fails. - * - * @since 3.5.0 - */ - public function test_update_product_review_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/reviews/0' ); - $request->set_body_params( - array( - 'review' => 'Hello world.', - 'reviewer' => 'Admin', - 'reviewer_email' => 'woo@woo.dev', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test deleting a product review. - * - * @since 3.5.0 - */ - public function test_delete_product_review() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test deleting a product review without permission/creds. - * - * @since 3.5.0 - */ - public function test_delete_product_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/' . $product_review_id ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a product review with an invalid id. - * - * @since 3.5.0 - */ - public function test_delete_product_review_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_review_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/reviews/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test batch managing product reviews. - * - * @since 3.5.0 - */ - public function test_product_reviews_batch() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - $review_1_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_2_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_3_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - $review_4_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_product_review( $product->get_id() ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $review_1_id, - 'review' => 'Updated review.', - ), - ), - 'delete' => array( - $review_2_id, - $review_3_id, - ), - 'create' => array( - array( - 'review' => 'New review.', - 'reviewer' => 'Justin', - 'reviewer_email' => 'woo3@woo.local', - 'product_id' => $product->get_id(), - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'Updated review.', $data['update'][0]['review'] ); - $this->assertEquals( 'New review.', $data['create'][0]['review'] ); - $this->assertEquals( $review_2_id, $data['delete'][0]['previous']['id'] ); - $this->assertEquals( $review_3_id, $data['delete'][1]['previous']['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/products/reviews' ); - $request->set_param( 'product', $product->get_id() ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Test the product review schema. - * - * @since 3.5.0 - */ - public function test_product_review_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/reviews' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 11, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_created_gmt', $properties ); - $this->assertArrayHasKey( 'product_id', $properties ); - $this->assertArrayHasKey( 'status', $properties ); - $this->assertArrayHasKey( 'reviewer', $properties ); - $this->assertArrayHasKey( 'reviewer_email', $properties ); - $this->assertArrayHasKey( 'review', $properties ); - $this->assertArrayHasKey( 'rating', $properties ); - $this->assertArrayHasKey( 'verified', $properties ); - - if ( get_option( 'show_avatars' ) ) { - $this->assertArrayHasKey( 'reviewer_avatar_urls', $properties ); - } - } -} diff --git a/unit-tests/Tests/Version3/product-variations.php b/unit-tests/Tests/Version3/product-variations.php deleted file mode 100644 index 98bfda23c6b..00000000000 --- a/unit-tests/Tests/Version3/product-variations.php +++ /dev/null @@ -1,496 +0,0 @@ -endpoint = new WC_REST_Product_Variations_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/products/(?P[\d]+)/variations', $routes ); - $this->assertArrayHasKey( '/wc/v3/products/(?P[\d]+)/variations/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v3/products/(?P[\d]+)/variations/batch', $routes ); - } - - /** - * Test getting variations. - * - * @since 3.5.0 - */ - public function test_get_variations() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $variations ) ); - $this->assertEquals( 'DUMMY SKU VARIABLE LARGE', $variations[0]['sku'] ); - $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); - } - - /** - * Test getting variations with an orderby clause. - * - * @since 3.9.0 - */ - public function test_get_variations_with_orderby() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $request = new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ); - $request->set_query_params( array( 'orderby' => 'menu_order' ) ); - $response = $this->server->dispatch( $request ); - $variations = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $variations ) ); - $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]['sku'] ); - $this->assertEquals( 'size', $variations[0]['attributes'][0]['name'] ); - } - - /** - * Test getting variations without permission. - * - * @since 3.5.0 - */ - public function test_get_variations_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single variation. - * - * @since 3.5.0 - */ - public function test_get_variation() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $variation_id, $variation['id'] ); - $this->assertEquals( 'size', $variation['attributes'][0]['name'] ); - } - - /** - * Test getting single variation without permission. - * - * @since 3.5.0 - */ - public function test_get_variation_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single variation. - * - * @since 3.5.0 - */ - public function test_delete_variation() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 1, count( $variations ) ); - } - - /** - * Test deleting a single variation without permission. - * - * @since 3.5.0 - */ - public function test_delete_variation_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single variation with an invalid ID. - * - * @since 3.5.0 - */ - public function test_delete_variation_with_invalid_id() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() . '/variations/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test editing a single variation. - * - * @since 3.5.0 - */ - public function test_update_variation() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ) ); - $variation = $response->get_data(); - - $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variation['sku'] ); - $this->assertEquals( 10, $variation['regular_price'] ); - $this->assertEmpty( $variation['sale_price'] ); - $this->assertEquals( 'small', $variation['attributes'][0]['option'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'sku' => 'FIXED-\'SKU', - 'sale_price' => '8', - 'description' => 'O_O', - 'image' => array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertTrue( isset( $variation['description'] ), print_r( $variation, true ) ); - $this->assertContains( 'O_O', $variation['description'], print_r( $variation, true ) ); - $this->assertEquals( '8', $variation['price'], print_r( $variation, true ) ); - $this->assertEquals( '8', $variation['sale_price'], print_r( $variation, true ) ); - $this->assertEquals( '10', $variation['regular_price'], print_r( $variation, true ) ); - $this->assertEquals( 'FIXED-\'SKU', $variation['sku'], print_r( $variation, true ) ); - $this->assertEquals( 'medium', $variation['attributes'][0]['option'], print_r( $variation, true ) ); - $this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'], print_r( $variation, true ) ); - $this->assertContains( 'test upload image', $variation['image']['alt'], print_r( $variation, true ) ); - - wp_delete_attachment( $variation['image']['id'], true ); - } - - /** - * Test updating a single variation without permission. - * - * @since 3.5.0 - */ - public function test_update_variation_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $variation_id = $children[0]; - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single variation with an invalid ID. - * - * @since 3.5.0 - */ - public function test_update_variation_with_invalid_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/0' ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating a single variation. - * - * @since 3.5.0 - */ - public function test_create_variation() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 2, count( $variations ) ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations' ); - $request->set_body_params( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertContains( 'A medium size.', $variation['description'] ); - $this->assertEquals( '12', $variation['price'] ); - $this->assertEquals( '12', $variation['regular_price'] ); - $this->assertTrue( $variation['purchasable'] ); - $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $variation['sku'] ); - $this->assertEquals( 'medium', $variation['attributes'][0]['option'] ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ) ); - $variations = $response->get_data(); - $this->assertEquals( 3, count( $variations ) ); - } - - /** - * Test creating a single variation without permission. - * - * @since 3.5.0 - */ - public function test_create_variation_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - - $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations' ); - $request->set_body_params( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch managing product variations. - * - * @since 3.5.0 - */ - public function test_product_variations_batch() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $children = $product->get_children(); - $request = new WP_REST_Request( 'POST', '/wc/v3/products/' . $product->get_id() . '/variations/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $children[0], - 'description' => 'Updated description.', - 'image' => array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - ), - ), - 'delete' => array( - $children[1], - ), - 'create' => array( - array( - 'sku' => 'DUMMY SKU VARIABLE MEDIUM', - 'regular_price' => '12', - 'description' => 'A medium size.', - 'attributes' => array( - array( - 'name' => 'pa_size', - 'option' => 'medium', - ), - ), - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); - $this->assertEquals( 'DUMMY SKU VARIABLE MEDIUM', $data['create'][0]['sku'] ); - $this->assertEquals( 'medium', $data['create'][0]['attributes'][0]['option'] ); - $this->assertEquals( $children[1], $data['delete'][0]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() . '/variations' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 2, count( $data ) ); - - wp_delete_attachment( $data[1]['image']['id'], true ); - } - - /** - * Test variation schema. - * - * @since 3.5.0 - */ - public function test_variation_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() . '/variations' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 37, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'date_created', $properties ); - $this->assertArrayHasKey( 'date_modified', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'permalink', $properties ); - $this->assertArrayHasKey( 'sku', $properties ); - $this->assertArrayHasKey( 'price', $properties ); - $this->assertArrayHasKey( 'regular_price', $properties ); - $this->assertArrayHasKey( 'sale_price', $properties ); - $this->assertArrayHasKey( 'date_on_sale_from', $properties ); - $this->assertArrayHasKey( 'date_on_sale_to', $properties ); - $this->assertArrayHasKey( 'on_sale', $properties ); - $this->assertArrayHasKey( 'purchasable', $properties ); - $this->assertArrayHasKey( 'virtual', $properties ); - $this->assertArrayHasKey( 'downloadable', $properties ); - $this->assertArrayHasKey( 'downloads', $properties ); - $this->assertArrayHasKey( 'download_limit', $properties ); - $this->assertArrayHasKey( 'download_expiry', $properties ); - $this->assertArrayHasKey( 'tax_status', $properties ); - $this->assertArrayHasKey( 'tax_class', $properties ); - $this->assertArrayHasKey( 'manage_stock', $properties ); - $this->assertArrayHasKey( 'stock_quantity', $properties ); - $this->assertArrayHasKey( 'stock_status', $properties ); - $this->assertArrayHasKey( 'backorders', $properties ); - $this->assertArrayHasKey( 'backorders_allowed', $properties ); - $this->assertArrayHasKey( 'backordered', $properties ); - $this->assertArrayHasKey( 'weight', $properties ); - $this->assertArrayHasKey( 'dimensions', $properties ); - $this->assertArrayHasKey( 'shipping_class', $properties ); - $this->assertArrayHasKey( 'shipping_class_id', $properties ); - $this->assertArrayHasKey( 'image', $properties ); - $this->assertArrayHasKey( 'attributes', $properties ); - $this->assertArrayHasKey( 'menu_order', $properties ); - $this->assertArrayHasKey( 'meta_data', $properties ); - } - - /** - * Test updating a variation stock. - * - * @since 3.5.0 - */ - public function test_update_variation_manage_stock() { - wp_set_current_user( $this->user ); - - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $product->set_manage_stock( false ); - $product->save(); - - $children = $product->get_children(); - $variation_id = $children[0]; - - // Set stock to true. - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => true, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( true, $variation['manage_stock'] ); - - // Set stock to false. - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => false, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( false, $variation['manage_stock'] ); - - // Set stock to false but parent is managing stock. - $product->set_manage_stock( true ); - $product->save(); - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id ); - $request->set_body_params( - array( - 'manage_stock' => false, - ) - ); - - $response = $this->server->dispatch( $request ); - $variation = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'parent', $variation['manage_stock'] ); - } -} diff --git a/unit-tests/Tests/Version3/products.php b/unit-tests/Tests/Version3/products.php deleted file mode 100644 index 22351897134..00000000000 --- a/unit-tests/Tests/Version3/products.php +++ /dev/null @@ -1,861 +0,0 @@ -endpoint = new WC_REST_Products_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/products', $routes ); - $this->assertArrayHasKey( '/wc/v3/products/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v3/products/batch', $routes ); - } - - /** - * Test getting products. - * - * @since 3.5.0 - */ - public function test_get_products() { - wp_set_current_user( $this->user ); - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - sleep( 1 ); // So both products have different timestamps. - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 2, count( $products ) ); - $this->assertEquals( 'Dummy Product', $products[0]['name'] ); - $this->assertEquals( 'DUMMY SKU', $products[0]['sku'] ); - $this->assertEquals( 'Dummy External Product', $products[1]['name'] ); - $this->assertEquals( 'DUMMY EXTERNAL SKU', $products[1]['sku'] ); - } - - /** - * Test getting trashed products. - */ - public function test_get_trashed_products() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $data_store = WC_Data_Store::load( 'product' ); - $data_store->delete( $product ); - $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); - $request->set_query_params( array( 'status' => 'trash' ) ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $products ) ); - $this->assertEquals( $product->get_name(), $products[0]['name'] ); - $this->assertEquals( $product->get_id(), $products[0]['id'] ); - } - - /** - * Trashed products should not be returned by default. - */ - public function test_get_trashed_products_not_returned_by_default() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $data_store = WC_Data_Store::load( 'product' ); - $data_store->delete( $product ); - - $response = $this->server->dispatch( - new WP_REST_Request( 'GET', '/wc/v3/products' ) - ); - $products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 0, count( $products ) ); - } - - /** - * Trashed product can be fetched directly. - */ - public function test_get_trashed_products_returned_by_id() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $data_store = WC_Data_Store::load( 'product' ); - $data_store->delete( $product ); - - $response = $this->server->dispatch( - new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) - ); - - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test getting products without permission. - * - * @since 3.5.0 - */ - public function test_get_products_without_permission() { - wp_set_current_user( 0 ); - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test getting a single product. - * - * @since 3.5.0 - */ - public function test_get_product() { - wp_set_current_user( $this->user ); - $simple = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $simple->get_id() ) ); - $product = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => $simple->get_id(), - 'name' => 'Dummy External Product', - 'type' => 'simple', - 'status' => 'publish', - 'sku' => 'DUMMY EXTERNAL SKU', - 'regular_price' => 10, - ), - $product - ); - } - - /** - * Test getting single product without permission. - * - * @since 3.5.0 - */ - public function test_get_product_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single product. - * - * @since 3.5.0 - */ - public function test_delete_product() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); - $variations = $response->get_data(); - $this->assertEquals( 0, count( $variations ) ); - } - - /** - * Test deleting a single product without permission. - * - * @since 3.5.0 - */ - public function test_delete_product_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test deleting a single product with an invalid ID. - * - * @since 3.5.0 - */ - public function test_delete_product_with_invalid_id() { - wp_set_current_user( 0 ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/products/0' ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test editing a single product. Tests multiple product types. - * - * @since 3.5.0 - */ - public function test_update_product() { - wp_set_current_user( $this->user ); - - // test simple products. - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); - $data = $response->get_data(); - $date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) ); - - $this->assertEquals( 'DUMMY SKU', $data['sku'] ); - $this->assertEquals( 10, $data['regular_price'] ); - $this->assertEmpty( $data['sale_price'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU', - 'sale_price' => '8', - 'description' => 'Testing', - 'date_created' => $date_created, - 'images' => array( - array( - 'position' => 0, - 'src' => 'http://cldup.com/Dr1Bczxq4q.png', - 'alt' => 'test upload image', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Testing', $data['description'] ); - $this->assertEquals( '8', $data['price'] ); - $this->assertEquals( '8', $data['sale_price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertEquals( 'FIXED-SKU', $data['sku'] ); - $this->assertEquals( $date_created, $data['date_created'] ); - $this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] ); - $this->assertContains( 'test upload image', $data['images'][0]['alt'] ); - $product->delete( true ); - wp_delete_attachment( $data['images'][0]['id'], true ); - - // test variable product (variations are tested in product-variations.php). - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); - $data = $response->get_data(); - - foreach ( array( 'small', 'large' ) as $term_name ) { - $this->assertContains( $term_name, $data['attributes'][0]['options'] ); - } - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'attributes' => array( - array( - 'id' => 0, - 'name' => 'pa_color', - 'options' => array( - 'red', - 'yellow', - ), - 'visible' => false, - 'variation' => 1, - ), - array( - 'id' => 0, - 'name' => 'pa_size', - 'options' => array( - 'small', - ), - 'visible' => false, - 'variation' => 1, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( array( 'small' ), $data['attributes'][0]['options'] ); - - foreach ( array( 'red', 'yellow' ) as $term_name ) { - $this->assertContains( $term_name, $data['attributes'][1]['options'] ); - } - - $product->delete( true ); - - // test external product. - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 'Buy external product', $data['button_text'] ); - $this->assertEquals( 'http://woocommerce.com', $data['external_url'] ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'button_text' => 'Test API Update', - 'external_url' => 'http://automattic.com', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'Test API Update', $data['button_text'] ); - $this->assertEquals( 'http://automattic.com', $data['external_url'] ); - } - - /** - * Test updating a single product without permission. - * - * @since 3.5.0 - */ - public function test_update_product_without_permission() { - wp_set_current_user( 0 ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-NO-PERMISSION', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single product with an invalid ID. - * - * @since 3.5.0 - */ - public function test_update_product_with_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' ); - $request->set_body_params( - array( - 'sku' => 'FIXED-SKU-INVALID-ID', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - } - - /** - * Test creating a single product. - * - * @since 3.5.0 - */ - public function test_create_product() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/products/shipping_classes' ); - $request->set_body_params( - array( - 'name' => 'Test', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $shipping_class_id = $data['id']; - - // Create simple. - $request = new WP_REST_Request( 'POST', '/wc/v3/products' ); - $request->set_body_params( - array( - 'type' => 'simple', - 'name' => 'Test Simple Product', - 'sku' => 'DUMMY SKU SIMPLE API', - 'regular_price' => '10', - 'shipping_class' => 'test', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '10', $data['price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertTrue( $data['purchasable'] ); - $this->assertEquals( 'DUMMY SKU SIMPLE API', $data['sku'] ); - $this->assertEquals( 'Test Simple Product', $data['name'] ); - $this->assertEquals( 'simple', $data['type'] ); - $this->assertEquals( $shipping_class_id, $data['shipping_class_id'] ); - - // Create external. - $request = new WP_REST_Request( 'POST', '/wc/v3/products' ); - $request->set_body_params( - array( - 'type' => 'external', - 'name' => 'Test External Product', - 'sku' => 'DUMMY SKU EXTERNAL API', - 'regular_price' => '10', - 'button_text' => 'Test Button', - 'external_url' => 'https://wordpress.org', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '10', $data['price'] ); - $this->assertEquals( '10', $data['regular_price'] ); - $this->assertFalse( $data['purchasable'] ); - $this->assertEquals( 'DUMMY SKU EXTERNAL API', $data['sku'] ); - $this->assertEquals( 'Test External Product', $data['name'] ); - $this->assertEquals( 'external', $data['type'] ); - $this->assertEquals( 'Test Button', $data['button_text'] ); - $this->assertEquals( 'https://wordpress.org', $data['external_url'] ); - - // Create variable. - $request = new WP_REST_Request( 'POST', '/wc/v3/products' ); - $request->set_body_params( - array( - 'type' => 'variable', - 'name' => 'Test Variable Product', - 'sku' => 'DUMMY SKU VARIABLE API', - 'attributes' => array( - array( - 'id' => 0, - 'name' => 'pa_size', - 'options' => array( - 'small', - 'medium', - ), - 'visible' => false, - 'variation' => 1, - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'DUMMY SKU VARIABLE API', $data['sku'] ); - $this->assertEquals( 'Test Variable Product', $data['name'] ); - $this->assertEquals( 'variable', $data['type'] ); - $this->assertEquals( array( 'small', 'medium' ), $data['attributes'][0]['options'] ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) ); - $products = $response->get_data(); - $this->assertEquals( 3, count( $products ) ); - } - - /** - * Test creating a single product without permission. - * - * @since 3.5.0 - */ - public function test_create_product_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/products' ); - $request->set_body_params( - array( - 'name' => 'Test Product', - 'regular_price' => '12', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test batch managing products. - * - * @since 3.5.0 - */ - public function test_products_batch() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'POST', '/wc/v3/products/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => $product->get_id(), - 'description' => 'Updated description.', - ), - ), - 'delete' => array( - $product_2->get_id(), - ), - 'create' => array( - array( - 'sku' => 'DUMMY SKU BATCH TEST 1', - 'regular_price' => '10', - 'name' => 'Test Batch Create 1', - 'type' => 'external', - 'button_text' => 'Test Button', - ), - array( - 'sku' => 'DUMMY SKU BATCH TEST 2', - 'regular_price' => '20', - 'name' => 'Test Batch Create 2', - 'type' => 'simple', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertContains( 'Updated description.', $data['update'][0]['description'] ); - $this->assertEquals( 'DUMMY SKU BATCH TEST 1', $data['create'][0]['sku'] ); - $this->assertEquals( 'DUMMY SKU BATCH TEST 2', $data['create'][1]['sku'] ); - $this->assertEquals( 'Test Button', $data['create'][0]['button_text'] ); - $this->assertEquals( 'external', $data['create'][0]['type'] ); - $this->assertEquals( 'simple', $data['create'][1]['type'] ); - $this->assertEquals( $product_2->get_id(), $data['delete'][0]['id'] ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - } - - /** - * Tests to make sure you can filter products post statuses by both - * the status query arg and WP_Query. - * - * @since 3.5.0 - */ - public function test_products_filter_post_status() { - wp_set_current_user( $this->user ); - for ( $i = 0; $i < 8; $i++ ) { - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - if ( 0 === $i % 2 ) { - wp_update_post( - array( - 'ID' => $product->get_id(), - 'post_status' => 'draft', - ) - ); - } - } - - // Test filtering with status=publish. - $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); - $request->set_param( 'status', 'publish' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 4, count( $products ) ); - foreach ( $products as $product ) { - $this->assertEquals( 'publish', $product['status'] ); - } - - // Test filtering with status=draft. - $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); - $request->set_param( 'status', 'draft' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 4, count( $products ) ); - foreach ( $products as $product ) { - $this->assertEquals( 'draft', $product['status'] ); - } - - // Test filtering with no filters - which should return 'any' (all 8). - $request = new WP_REST_Request( 'GET', '/wc/v3/products' ); - $response = $this->server->dispatch( $request ); - $products = $response->get_data(); - - $this->assertEquals( 8, count( $products ) ); - } - - /** - * Test product schema. - * - * @since 3.5.0 - */ - public function test_product_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 65, count( $properties ) ); - } - - /** - * Test product category. - * - * @since 3.5.0 - */ - public function test_get_products_by_category() { - wp_set_current_user( $this->user ); - - // Create one product with a category. - $category = wp_insert_term( 'Some Category', 'product_cat' ); - - $product = new WC_Product_Simple(); - $product->set_category_ids( array( $category['term_id'] ) ); - $product->save(); - - // Create one product without category, i.e. Uncategorized. - $product_2 = new WC_Product_Simple(); - $product_2->save(); - - // Test product assigned to a single category. - $query_params = array( - 'category' => (string) $category['term_id'], - ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $product->get_id(), $response_product['id'] ); - $this->assertEquals( $product->get_category_ids(), wp_list_pluck( $response_product['categories'], 'id' ) ); - } - - // Test product without categories. - $request = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product_2->get_id() ); - $response = $this->server->dispatch( $request ); - $response_product = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertCount( 1, $response_product['categories'], print_r( $response_product, true ) ); - $this->assertEquals( 'uncategorized', $response_product['categories'][0]['slug'] ); - - } - - /** - * Test getting products by product type. - * - * @since 3.5.0 - */ - public function test_get_products_by_type() { - wp_set_current_user( $this->user ); - - $simple = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $external = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product(); - $grouped = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_grouped_product(); - $variable = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - - $product_ids_for_type = array( - 'simple' => array( $simple->get_id() ), - 'external' => array( $external->get_id() ), - 'grouped' => array( $grouped->get_id() ), - 'variable' => array( $variable->get_id() ), - ); - - foreach ( $grouped->get_children() as $additional_product ) { - $product_ids_for_type['simple'][] = $additional_product; - } - - foreach ( $product_ids_for_type as $product_type => $product_ids ) { - $query_params = array( - 'type' => $product_type, - ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $product_ids ), count( $response_products ) ); - foreach ( $response_products as $response_product ) { - $this->assertContains( $response_product['id'], $product_ids_for_type[ $product_type ], 'REST API: ' . $product_type . ' not found correctly' ); - } - } - } - - /** - * Test getting products by featured property. - * - * @since 3.5.0 - */ - public function test_get_featured_products() { - wp_set_current_user( $this->user ); - - // Create a featured product. - $feat_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $feat_product->set_featured( true ); - $feat_product->save(); - - // Create a non-featured product. - $nonfeat_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $nonfeat_product->save(); - - $query_params = array( - 'featured' => 'true', - ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $feat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' ); - } - - $query_params = array( - 'featured' => 'false', - ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $nonfeat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' ); - } - } - - /** - * Test getting products by shipping class property. - * - * @since 3.5.0 - */ - public function test_get_products_by_shipping_class() { - wp_set_current_user( $this->user ); - - $shipping_class_1 = wp_insert_term( 'Bulky', 'product_shipping_class' ); - - $product_1 = new WC_Product_Simple(); - $product_1->set_shipping_class_id( $shipping_class_1['term_id'] ); - $product_1->save(); - - $query_params = array( - 'shipping_class' => (string) $shipping_class_1['term_id'], - ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $product_1->get_id(), $response_product['id'] ); - } - } - - /** - * Test getting products by tag. - * - * @since 3.5.0 - */ - public function test_get_products_by_tag() { - wp_set_current_user( $this->user ); - - $test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' ); - - // Product with a tag. - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product->set_tag_ids( array( $test_tag_1['term_id'] ) ); - $product->save(); - - // Product without a tag. - $product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - $query_params = array( - 'tag' => (string) $test_tag_1['term_id'], - ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - foreach ( $response_products as $response_product ) { - $this->assertEquals( $product->get_id(), $response_product['id'] ); - } - } - - /** - * Test getting products by global attribute. - * - * @since 3.5.0 - */ - public function test_get_products_by_attribute() { - global $wpdb; - wp_set_current_user( $this->user ); - - // Variable product with 2 different variations. - $variable_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product(); - - // Terms created by variable product. - $term_large = get_term_by( 'slug', 'large', 'pa_size' ); - $term_small = get_term_by( 'slug', 'small', 'pa_size' ); - - // Simple product without attribute. - $product_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - - // Simple product with attribute size = large. - $product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $product_2->set_attributes( array( 'pa_size' => 'large' ) ); - $product_2->save(); - - // Link the product to the term. - $wpdb->insert( - $wpdb->prefix . 'term_relationships', - array( - 'object_id' => $product_2->get_id(), - 'term_taxonomy_id' => $term_large->term_id, - 'term_order' => 0, - ) - ); - - // Products with attribute size == large. - $expected_product_ids = array( - $variable_product->get_id(), - $product_2->get_id(), - ); - $query_params = array( - 'attribute' => 'pa_size', - 'attribute_term' => (string) $term_large->term_id, - ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $expected_product_ids ), count( $response_products ) ); - foreach ( $response_products as $response_product ) { - $this->assertContains( $response_product['id'], $expected_product_ids ); - } - - // Products with attribute size == small. - $expected_product_ids = array( - $variable_product->get_id(), - ); - $query_params = array( - 'attribute' => 'pa_size', - 'attribute_term' => (string) $term_small->term_id, - ); - $request = new WP_REST_Request( 'GET', '/wc/v2/products' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $response_products = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $expected_product_ids ), count( $response_products ) ); - foreach ( $response_products as $response_product ) { - $this->assertContains( $response_product['id'], $expected_product_ids ); - } - } -} diff --git a/unit-tests/Tests/Version3/reports-coupons-totals.php b/unit-tests/Tests/Version3/reports-coupons-totals.php deleted file mode 100644 index 162b8af7ef7..00000000000 --- a/unit-tests/Tests/Version3/reports-coupons-totals.php +++ /dev/null @@ -1,103 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/reports/coupons/totals', $routes ); - } - - /** - * Test getting all product reviews. - * - * @since 3.5.0 - */ - public function test_get_reports() { - global $wpdb; - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/coupons/totals' ) ); - $report = $response->get_data(); - $types = wc_get_coupon_types(); - $data = array(); - - foreach ( $types as $slug => $name ) { - $results = $wpdb->get_results( - $wpdb->prepare( - " - SELECT count(meta_id) AS total - FROM $wpdb->postmeta - WHERE meta_key = 'discount_type' - AND meta_value = %s - ", - $slug - ) - ); - - $total = isset( $results[0] ) ? (int) $results[0]->total : 0; - - $data[] = array( - 'slug' => $slug, - 'name' => $name, - 'total' => $total, - ); - } - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $types ), count( $report ) ); - $this->assertEquals( $data, $report ); - } - - /** - * Tests to make sure product reviews cannot be viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/coupons/totals' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test the product review schema. - * - * @since 3.5.0 - */ - public function test_product_review_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/coupons/totals' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'slug', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'total', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/reports-customers-totals.php b/unit-tests/Tests/Version3/reports-customers-totals.php deleted file mode 100644 index cd0e58f886f..00000000000 --- a/unit-tests/Tests/Version3/reports-customers-totals.php +++ /dev/null @@ -1,119 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/reports/customers/totals', $routes ); - } - - /** - * Test getting all product reviews. - * - * @since 3.5.0 - */ - public function test_get_reports() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/customers/totals' ) ); - $report = $response->get_data(); - $users_count = count_users(); - $total_customers = 0; - - foreach ( $users_count['avail_roles'] as $role => $total ) { - if ( in_array( $role, array( 'administrator', 'shop_manager' ), true ) ) { - continue; - } - - $total_customers += (int) $total; - } - - $customers_query = new WP_User_Query( - array( - 'role__not_in' => array( 'administrator', 'shop_manager' ), - 'number' => 0, - 'fields' => 'ID', - 'count_total' => true, - 'meta_query' => array( // WPCS: slow query ok. - array( - 'key' => 'paying_customer', - 'value' => 1, - 'compare' => '=', - ), - ), - ) - ); - - $total_paying = (int) $customers_query->get_total(); - - $data = array( - array( - 'slug' => 'paying', - 'name' => __( 'Paying customer', 'woocommerce' ), - 'total' => $total_paying, - ), - array( - 'slug' => 'non_paying', - 'name' => __( 'Non-paying customer', 'woocommerce' ), - 'total' => $total_customers - $total_paying, - ), - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $report ) ); - $this->assertEquals( $data, $report ); - } - - /** - * Tests to make sure product reviews cannot be viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/customers/totals' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test the product review schema. - * - * @since 3.5.0 - */ - public function test_product_review_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/customers/totals' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'slug', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'total', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/reports-orders-totals.php b/unit-tests/Tests/Version3/reports-orders-totals.php deleted file mode 100644 index 93a21a87634..00000000000 --- a/unit-tests/Tests/Version3/reports-orders-totals.php +++ /dev/null @@ -1,92 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/reports/orders/totals', $routes ); - } - - /** - * Test getting all product reviews. - * - * @since 3.5.0 - */ - public function test_get_reports() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/orders/totals' ) ); - $report = $response->get_data(); - $totals = wp_count_posts( 'shop_order' ); - $data = array(); - - foreach ( wc_get_order_statuses() as $slug => $name ) { - if ( ! isset( $totals->$slug ) ) { - continue; - } - - $data[] = array( - 'slug' => str_replace( 'wc-', '', $slug ), - 'name' => $name, - 'total' => (int) $totals->$slug, - ); - } - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( wc_get_order_statuses() ), count( $report ) ); - $this->assertEquals( $data, $report ); - } - - /** - * Tests to make sure product reviews cannot be viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/orders/totals' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test the product review schema. - * - * @since 3.5.0 - */ - public function test_product_review_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/orders/totals' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'slug', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'total', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/reports-products-totals.php b/unit-tests/Tests/Version3/reports-products-totals.php deleted file mode 100644 index 6243786ffad..00000000000 --- a/unit-tests/Tests/Version3/reports-products-totals.php +++ /dev/null @@ -1,99 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/reports/products/totals', $routes ); - } - - /** - * Test getting all product reviews. - * - * @since 3.5.0 - */ - public function test_get_reports() { - wp_set_current_user( $this->user ); - WC_Install::create_terms(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/products/totals' ) ); - $report = $response->get_data(); - $types = wc_get_product_types(); - $terms = get_terms( - array( - 'taxonomy' => 'product_type', - 'hide_empty' => false, - ) - ); - $data = array(); - - foreach ( $terms as $product_type ) { - if ( ! isset( $types[ $product_type->name ] ) ) { - continue; - } - - $data[] = array( - 'slug' => $product_type->name, - 'name' => $types[ $product_type->name ], - 'total' => (int) $product_type->count, - ); - } - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $types ), count( $report ) ); - $this->assertEquals( $data, $report ); - } - - /** - * Tests to make sure product reviews cannot be viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/products/totals' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test the product review schema. - * - * @since 3.5.0 - */ - public function test_product_review_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/products/totals' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'slug', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'total', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/reports-reviews-totals.php b/unit-tests/Tests/Version3/reports-reviews-totals.php deleted file mode 100644 index 3a2dc1622ff..00000000000 --- a/unit-tests/Tests/Version3/reports-reviews-totals.php +++ /dev/null @@ -1,98 +0,0 @@ -user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/reports/reviews/totals', $routes ); - } - - /** - * Test getting all product reviews. - * - * @since 3.5.0 - */ - public function test_get_reports() { - global $wpdb; - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/reviews/totals' ) ); - $report = $response->get_data(); - $data = array(); - - $query_data = array( - 'count' => true, - 'post_type' => 'product', - 'meta_key' => 'rating', // WPCS: slow query ok. - 'meta_value' => '', // WPCS: slow query ok. - ); - - for ( $i = 1; $i <= 5; $i++ ) { - $query_data['meta_value'] = $i; - - $data[] = array( - 'slug' => 'rated_' . $i . '_out_of_5', - /* translators: %s: average rating */ - 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $i ), - 'total' => (int) get_comments( $query_data ), - ); - } - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), count( $report ) ); - $this->assertEquals( $data, $report ); - } - - /** - * Tests to make sure product reviews cannot be viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_reports_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/reports/reviews/totals' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test the product review schema. - * - * @since 3.5.0 - */ - public function test_product_review_schema() { - wp_set_current_user( $this->user ); - $product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product(); - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/reviews/totals' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'slug', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'total', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/settings.php b/unit-tests/Tests/Version3/settings.php deleted file mode 100644 index 4c764de1f6c..00000000000 --- a/unit-tests/Tests/Version3/settings.php +++ /dev/null @@ -1,895 +0,0 @@ -endpoint = new WC_REST_Setting_Options_Controller(); - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/settings', $routes ); - $this->assertArrayHasKey( '/wc/v3/settings/(?P[\w-]+)', $routes ); - $this->assertArrayHasKey( '/wc/v3/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all groups. - * - * @since 3.5.0 - */ - public function test_get_groups() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertContains( - array( - 'id' => 'test', - 'label' => 'Test extension', - 'parent_id' => '', - 'description' => 'My awesome test settings.', - 'sub_groups' => array( 'sub-test' ), - '_links' => array( - 'options' => array( - array( - 'href' => rest_url( '/wc/v3/settings/test' ), - ), - ), - ), - ), - $data - ); - - $this->assertContains( - array( - 'id' => 'sub-test', - 'label' => 'Sub test', - 'parent_id' => 'test', - 'description' => '', - 'sub_groups' => array(), - '_links' => array( - 'options' => array( - array( - 'href' => rest_url( '/wc/v3/settings/sub-test' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test /settings without valid permissions/creds. - * - * @since 3.5.0 - */ - public function test_get_groups_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test /settings without valid permissions/creds. - * - * @since 3.5.0 - * @covers WC_Rest_Settings_Controller::get_items - */ - public function test_get_groups_none_registered() { - wp_set_current_user( $this->user ); - - remove_all_filters( 'woocommerce_settings_groups' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings' ) ); - $this->assertEquals( 500, $response->get_status() ); - - \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register(); - } - - /** - * Test groups schema. - * - * @since 3.5.0 - */ - public function test_get_group_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/settings' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 5, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'parent_id', $properties ); - $this->assertArrayHasKey( 'label', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'sub_groups', $properties ); - } - - /** - * Test settings schema. - * - * @since 3.5.0 - */ - public function test_get_setting_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/settings/test/woocommerce_shop_page_display' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 10, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'label', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'value', $properties ); - $this->assertArrayHasKey( 'default', $properties ); - $this->assertArrayHasKey( 'tip', $properties ); - $this->assertArrayHasKey( 'placeholder', $properties ); - $this->assertArrayHasKey( 'type', $properties ); - $this->assertArrayHasKey( 'options', $properties ); - $this->assertArrayHasKey( 'group_id', $properties ); - } - - /** - * Test getting a single group. - * - * @since 3.5.0 - */ - public function test_get_group() { - wp_set_current_user( $this->user ); - - // test route callback receiving an empty group id - $result = $this->endpoint->get_group_settings( '' ); - $this->assertWPError( $result ); - - // test getting a group that does not exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/not-real' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // test getting the 'invalid' group - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/invalid' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // test getting a valid group with settings attached to it - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test' ) ); - $data = $response->get_data(); - $this->assertEquals( 1, count( $data ) ); - $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); - $this->assertEmpty( $data[0]['value'] ); - } - - /** - * Test getting a single group without permission. - * - * @since 3.5.0 - */ - public function test_get_group_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/coupon-data' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a single setting. - * - * @since 3.5.0 - */ - public function test_update_setting() { - wp_set_current_user( $this->user ); - - // test defaults first - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - $this->assertEquals( '', $data['value'] ); - - // test updating shop display setting - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'both', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'both', $data['value'] ); - $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'subcategories', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'subcategories', $data['value'] ); - $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => '', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( '', $data['value'] ); - $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); - } - - /** - * Test updating multiple settings at once. - * - * @since 3.5.0 - */ - public function test_update_settings() { - wp_set_current_user( $this->user ); - - // test defaults first - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test' ) ); - $data = $response->get_data(); - $this->assertEquals( '', $data[0]['value'] ); - - // test setting both at once - $request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'both', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'both', $data['update'][0]['value'] ); - $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - - // test updating one, but making sure the other value stays the same - $request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'subcategories', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); - $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - } - - /** - * Test getting a single setting. - * - * @since 3.5.0 - */ - public function test_get_setting() { - wp_set_current_user( $this->user ); - - // test getting an invalid setting from a group that does not exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/not-real/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - $this->assertEquals( 404, $response->get_status() ); - - // test getting an invalid setting from a group that does exist - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/invalid/invalid' ) ); - $data = $response->get_data(); - $this->assertEquals( 404, $response->get_status() ); - - // test getting a valid setting - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test/woocommerce_shop_page_display' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 'woocommerce_shop_page_display', $data['id'] ); - $this->assertEquals( 'Shop page display', $data['label'] ); - $this->assertEquals( '', $data['default'] ); - $this->assertEquals( 'select', $data['type'] ); - $this->assertEquals( '', $data['value'] ); - } - - /** - * Test getting a single setting without valid user permissions. - * - * @since 3.5.0 - */ - public function test_get_setting_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test/woocommerce_shop_page_display' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests the GET single setting route handler receiving an empty setting ID. - * - * @since 3.5.0 - */ - public function test_get_setting_empty_setting_id() { - $result = $this->endpoint->get_setting( 'test', '' ); - - $this->assertWPError( $result ); - } - - /** - * Tests the GET single setting route handler receiving an invalid setting ID. - * - * @since 3.5.0 - */ - public function test_get_setting_invalid_setting_id() { - $result = $this->endpoint->get_setting( 'test', 'invalid' ); - - $this->assertWPError( $result ); - } - - /** - * Tests the GET single setting route handler encountering an invalid setting type. - * - * @since 3.5.0 - */ - public function test_get_setting_invalid_setting_type() { - // $controller = $this->getMock( 'WC_Rest_Setting_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); - $controller = $this->getMockBuilder( 'WC_Rest_Setting_Options_Controller' )->setMethods( array( 'get_group_settings', 'is_setting_type_valid' ) )->getMock(); - - $controller - ->expects( $this->any() ) - ->method( 'get_group_settings' ) - ->will( $this->returnValue( \Automattic\WooCommerce\RestApi\UnitTests\Helpers\SettingsHelper::register_test_settings( array() ) ) ); - - $controller - ->expects( $this->any() ) - ->method( 'is_setting_type_valid' ) - ->will( $this->returnValue( false ) ); - - $result = $controller->get_setting( 'test', 'woocommerce_shop_page_display' ); - - $this->assertWPError( $result ); - } - - /** - * Test updating a single setting without valid user permissions. - * - * @since 3.5.0 - */ - public function test_update_setting_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); - $request->set_body_params( - array( - 'value' => 'subcategories', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - - /** - * Test updating multiple settings without valid user permissions. - * - * @since 3.5.0 - */ - public function test_update_settings_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' ); - $request->set_body_params( - array( - 'update' => array( - array( - 'id' => 'woocommerce_shop_page_display', - 'value' => 'subcategories', - ), - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test updating a bad setting ID. - * - * @since 3.5.0 - * @covers WC_Rest_Setting_Options_Controller::update_item - */ - public function test_update_setting_bad_setting_id() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/test/invalid' ); - $request->set_body_params( - array( - 'value' => 'test', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. - * - * @since 3.5.0 - */ - public function test_classic_settings() { - wp_set_current_user( $this->user ); - - // Make sure the group is properly registered - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/products' ) ); - $data = $response->get_data(); - $this->assertTrue( is_array( $data ) ); - $this->assertContains( - array( - 'id' => 'woocommerce_downloads_require_login', - 'label' => 'Access restriction', - 'description' => 'Downloads require login', - 'type' => 'checkbox', - 'default' => 'no', - 'tip' => 'This setting does not apply to guest purchases.', - 'value' => 'no', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/settings/products/woocommerce_downloads_require_login' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/settings/products' ), - ), - ), - ), - ), - $data - ); - - // test get single - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/products/woocommerce_dimension_unit' ) ); - $data = $response->get_data(); - - $this->assertEquals( 'cm', $data['default'] ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); - $request->set_body_params( - array( - 'value' => 'yd', - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 'yd', $data['value'] ); - $this->assertEquals( 'yd', get_option( 'woocommerce_dimension_unit' ) ); - } - - /** - * Tests our email etting registration to make sure settings added for WP-Admin are available over the API. - * - * @since 3.5.0 - */ - public function test_email_settings() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/email_new_order' ) ); - $settings = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertContains( - array( - 'id' => 'recipient', - 'label' => 'Recipient(s)', - 'description' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', - 'type' => 'text', - 'default' => '', - 'tip' => 'Enter recipients (comma separated) for this email. Defaults to admin@example.org.', - 'value' => '', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/settings/email_new_order/recipient' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/settings/email_new_order' ), - ), - ), - ), - ), - $settings - ); - - // test get single - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/email_new_order/subject' ) ); - $setting = $response->get_data(); - - $this->assertEquals( - array( - 'id' => 'subject', - 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', - 'type' => 'text', - 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', - 'value' => '', - 'group_id' => 'email_new_order', - ), - $setting - ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_new_order', 'subject' ) ); - $request->set_body_params( - array( - 'value' => 'This is my subject', - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEquals( - array( - 'id' => 'subject', - 'label' => 'Subject', - 'description' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', - 'type' => 'text', - 'default' => '', - 'tip' => 'Available placeholders: {site_title}, {site_address}, {site_url}, {order_date}, {order_number}', - 'value' => 'This is my subject', - 'group_id' => 'email_new_order', - ), - $setting - ); - - // test updating another subject and making sure it works with a "similar" id - $request = new WP_REST_Request( 'GET', sprintf( '/wc/v3/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEmpty( $setting['value'] ); - - // test update - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); - $request->set_body_params( - array( - 'value' => 'This is my new subject', - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - - $this->assertEquals( 'This is my new subject', $setting['value'] ); - - // make sure the other is what we left it - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/email_new_order/subject' ) ); - $setting = $response->get_data(); - - $this->assertEquals( 'This is my subject', $setting['value'] ); - } - - /** - * Test validation of checkbox settings. - * - * @since 3.5.0 - */ - public function test_validation_checkbox() { - wp_set_current_user( $this->user ); - - // test bogus value - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'not_yes_or_no', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // test yes - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'yes', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - // test no - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); - $request->set_body_params( - array( - 'value' => 'no', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test validation of radio settings. - * - * @since 3.5.0 - */ - public function test_validation_radio() { - wp_set_current_user( $this->user ); - - // not a valid option - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); - $request->set_body_params( - array( - 'value' => 'billing2', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // valid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); - $request->set_body_params( - array( - 'value' => 'billing', - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test validation of multiselect. - * - * @since 3.5.0 - */ - public function test_validation_multiselect() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v3/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ) ); - $setting = $response->get_data(); - $this->assertEmpty( $setting['value'] ); - - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'general', 'woocommerce_specific_allowed_countries' ) ); - $request->set_body_params( - array( - 'value' => array( 'AX', 'DZ', 'MMM' ), - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( array( 'AX', 'DZ' ), $setting['value'] ); - } - - /** - * Test validation of select. - * - * @since 3.5.0 - */ - public function test_validation_select() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ) ); - $setting = $response->get_data(); - $this->assertEquals( 'kg', $setting['value'] ); - - // invalid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); - $request->set_body_params( - array( - 'value' => 'pounds', // invalid, should be lbs - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // valid - $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); - $request->set_body_params( - array( - 'value' => 'lbs', // invalid, should be lbs - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( 'lbs', $setting['value'] ); - } - - /** - * Test to make sure the 'base location' setting is present in the response. - * That it is returned as 'select' and not 'single_select_country', - * and that both state and country options are returned. - * - * @since 3.5.0 - */ - public function test_woocommerce_default_country() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_default_country' ) ); - $setting = $response->get_data(); - - $this->assertEquals( 'select', $setting['type'] ); - $this->assertArrayHasKey( 'GB', $setting['options'] ); - $this->assertArrayHasKey( 'US:OR', $setting['options'] ); - } - - /** - * Test to make sure the store address setting can be fetched and updated. - * - * @since 3.5.0 - */ - public function test_woocommerce_store_address() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_address' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store address 2 (line 2) setting can be fetched and updated. - * - * @since 3.5.0 - */ - public function test_woocommerce_store_address_2() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_address_2' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address_2' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address_2' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store city setting can be fetched and updated. - * - * @since 3.5.0 - */ - public function test_woocommerce_store_city() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_city' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_city' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_city' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } - - /** - * Test to make sure the store postcode setting can be fetched and updated. - * - * @since 3.5.0 - */ - public function test_woocommerce_store_postcode() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_postcode' ) ); - $setting = $response->get_data(); - $this->assertEquals( 'text', $setting['type'] ); - - // Repalce the old value with something uniquely new - $old_value = $setting['value']; - $new_value = $old_value . ' ' . rand( 1000, 9999 ); - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_postcode' ); - $request->set_body_params( - array( - 'value' => $new_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $new_value, $setting['value'] ); - - // Put the original value back - $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_postcode' ); - $request->set_body_params( - array( - 'value' => $old_value, - ) - ); - $response = $this->server->dispatch( $request ); - $setting = $response->get_data(); - $this->assertEquals( $old_value, $setting['value'] ); - } -} diff --git a/unit-tests/Tests/Version3/shipping-methods.php b/unit-tests/Tests/Version3/shipping-methods.php deleted file mode 100644 index ad139c427af..00000000000 --- a/unit-tests/Tests/Version3/shipping-methods.php +++ /dev/null @@ -1,143 +0,0 @@ -endpoint = new WC_REST_Shipping_Methods_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/shipping_methods', $routes ); - $this->assertArrayHasKey( '/wc/v3/shipping_methods/(?P[\w-]+)', $routes ); - } - - /** - * Test getting all shipping methods. - * - * @since 3.5.0 - */ - public function test_get_shipping_methods() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods' ) ); - $methods = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertContains( - array( - 'id' => 'free_shipping', - 'title' => 'Free shipping', - 'description' => 'Free shipping is a special method which can be triggered with coupons and minimum spends.', - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/shipping_methods/free_shipping' ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping_methods' ), - ), - ), - ), - ), - $methods - ); - } - - /** - * Tests to make sure shipping methods cannot viewed without valid permissions. - * - * @since 3.5.0 - */ - public function test_get_shipping_methods_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a single shipping method. - * - * @since 3.5.0 - */ - public function test_get_shipping_method() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods/local_pickup' ) ); - $method = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => 'local_pickup', - 'title' => 'Local pickup', - 'description' => 'Allow customers to pick up orders themselves. By default, when using local pickup store base taxes will apply regardless of customer address.', - ), - $method - ); - } - - /** - * Tests getting a single shipping method without the correct permissions. - * - * @since 3.5.0 - */ - public function test_get_shipping_method_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods/local_pickup' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Tests getting a shipping method with an invalid ID. - * - * @since 3.5.0 - */ - public function test_get_shipping_method_invalid_id() { - wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping_methods/fake_method' ) ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test the shipping method schema. - * - * @since 3.5.0 - */ - public function test_shipping_method_schema() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/shipping_methods' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'title', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - } -} diff --git a/unit-tests/Tests/Version3/shipping-zones.php b/unit-tests/Tests/Version3/shipping-zones.php deleted file mode 100644 index a735357b41f..00000000000 --- a/unit-tests/Tests/Version3/shipping-zones.php +++ /dev/null @@ -1,825 +0,0 @@ -endpoint = new WC_REST_Shipping_Zones_Controller(); - $this->user = $this->factory->user->create( - array( - 'role' => 'administrator', - ) - ); - $this->zones = array(); - } - - /** - * Helper method to create a Shipping Zone. - * - * @param string $name Zone name. - * @param int $order Optional. Zone sort order. - * @return WC_Shipping_Zone - */ - protected function create_shipping_zone( $name, $order = 0, $locations = array() ) { - $zone = new WC_Shipping_Zone( null ); - $zone->set_zone_name( $name ); - $zone->set_zone_order( $order ); - $zone->set_locations( $locations ); - $zone->save(); - - $this->zones[] = $zone; - - return $zone; - } - - /** - * Test route registration. - * - * @since 3.5.0 - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/shipping/zones', $routes ); - $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)', $routes ); - $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/locations', $routes ); - $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/methods', $routes ); - $this->assertArrayHasKey( '/wc/v3/shipping/zones/(?P[\d]+)/methods/(?P[\d]+)', $routes ); - } - - /** - * Test getting all Shipping Zones. - * - * @since 3.5.0 - */ - public function test_get_zones() { - wp_set_current_user( $this->user ); - - // "Rest of the World" zone exists by default - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertContains( - array( - 'id' => $data[0]['id'], - 'name' => 'Locations not covered by your other zones', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $data[0]['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $data[0]['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - - // Create a zone and make sure it's in the response - $this->create_shipping_zone( 'Zone 1' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 2 ); - $this->assertContains( - array( - 'id' => $data[1]['id'], - 'name' => 'Zone 1', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $data[1]['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $data[1]['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test /shipping/zones without valid permissions/creds. - * - * @since 3.5.0 - */ - public function test_get_shipping_zones_without_permission() { - wp_set_current_user( 0 ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test /shipping/zones while Shipping is disabled in WooCommerce. - * - * @since 3.5.0 - */ - public function test_get_shipping_zones_disabled_shipping() { - wp_set_current_user( $this->user ); - - add_filter( 'wc_shipping_enabled', '__return_false' ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones' ) ); - $this->assertEquals( 404, $response->get_status() ); - - remove_filter( 'wc_shipping_enabled', '__return_false' ); - } - - /** - * Test Shipping Zone schema. - * - * @since 3.5.0 - */ - public function test_get_shipping_zone_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/shipping/zones' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 3, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertTrue( $properties['id']['readonly'] ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'order', $properties ); - } - - /** - * Test Shipping Zone create endpoint. - * - * @since 3.5.0 - */ - public function test_create_shipping_zone() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones' ); - $request->set_body_params( - array( - 'name' => 'Test Zone', - 'order' => 1, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 201, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $data['id'], - 'name' => 'Test Zone', - 'order' => 1, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $data['id'] ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $data['id'] . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test Shipping Zone create endpoint. - * - * @since 3.5.0 - */ - public function test_create_shipping_zone_without_permission() { - wp_set_current_user( 0 ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones' ); - $request->set_body_params( - array( - 'name' => 'Test Zone', - 'order' => 1, - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test Shipping Zone update endpoint. - * - * @since 3.5.0 - */ - public function test_update_shipping_zone() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Test Zone' ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/shipping/zones/' . $zone->get_id() ); - $request->set_body_params( - array( - 'name' => 'Zone Test', - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $zone->get_id(), - 'name' => 'Zone Test', - 'order' => 2, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test Shipping Zone update endpoint with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_update_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/shipping/zones/555555' ); - $request->set_body_params( - array( - 'name' => 'Zone Test', - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint. - * - * @since 3.5.0 - */ - public function test_delete_shipping_zone() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/shipping/zones/' . $zone->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint without permissions. - * - * @since 3.5.0 - */ - public function test_delete_shipping_zone_without_permission() { - wp_set_current_user( 0 ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - - $request = new WP_REST_Request( 'DELETE', '/wc/v3/shipping/zones/' . $zone->get_id() ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test Shipping Zone delete endpoint with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_delete_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); - $request = new WP_REST_Request( 'DELETE', '/wc/v3/shipping/zones/555555' ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single Shipping Zone. - * - * @since 3.5.0 - */ - public function test_get_single_shipping_zone() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Test Zone' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( - array( - 'id' => $zone->get_id(), - 'name' => 'Test Zone', - 'order' => 0, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones' ), - ), - ), - 'describedby' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test getting a single Shipping Zone with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_get_single_shipping_zone_invalid_id() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting Shipping Zone Locations. - * - * @since 3.5.0 - */ - public function test_get_locations() { - wp_set_current_user( $this->user ); - - // Create a zone - $zone = $this->create_shipping_zone( - 'Zone 1', - 0, - array( - array( - 'code' => 'US', - 'type' => 'country', - ), - ) - ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertEquals( - array( - array( - 'code' => 'US', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test getting Shipping Zone Locations with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_get_locations_invalid_id() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/1/locations' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test Shipping Zone Locations update endpoint. - * - * @since 3.5.0 - */ - public function test_update_locations() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Test Zone' ); - - $request = new WP_REST_Request( 'PUT', '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ); - $request->add_header( 'Content-Type', 'application/json' ); - $request->set_body( - json_encode( - array( - array( - 'code' => 'UK', - 'type' => 'country', - ), - array( - 'code' => 'US', // test that locations missing "type" treated as country. - ), - array( - 'code' => 'SW1A0AA', - 'type' => 'postcode', - ), - array( - 'type' => 'continent', // test that locations missing "code" aren't saved - ), - ) - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 3, count( $data ) ); - $this->assertEquals( - array( - array( - 'code' => 'UK', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - array( - 'code' => 'US', - 'type' => 'country', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - array( - 'code' => 'SW1A0AA', - 'type' => 'postcode', - '_links' => array( - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/locations' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ), - ), - $data - ); - } - - /** - * Test updating Shipping Zone Locations with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_update_locations_invalid_id() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'PUT', '/wc/v3/shipping/zones/1/locations' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting all Shipping Zone Methods and getting a single Shipping Zone Method. - * - * @since 3.5.0 - */ - public function test_get_methods() { - wp_set_current_user( $this->user ); - - // Create a shipping method and make sure it's in the response - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - - $settings = array(); - $method->init_instance_settings(); - foreach ( $method->get_instance_form_fields() as $id => $field ) { - $data = array( - 'id' => $id, - 'label' => $field['title'], - 'description' => ( empty( $field['description'] ) ? '' : $field['description'] ), - 'type' => $field['type'], - 'value' => $method->instance_settings[ $id ], - 'default' => ( empty( $field['default'] ) ? '' : $field['default'] ), - 'tip' => ( empty( $field['description'] ) ? '' : $field['description'] ), - 'placeholder' => ( empty( $field['placeholder'] ) ? '' : $field['placeholder'] ), - ); - if ( ! empty( $field['options'] ) ) { - $data['options'] = $field['options']; - } - $settings[ $id ] = $data; - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods' ) ); - $data = $response->get_data(); - $expected = array( - 'id' => $instance_id, - 'instance_id' => $instance_id, - 'title' => $method->instance_settings['title'], - 'order' => $method->method_order, - 'enabled' => ( 'yes' === $method->enabled ), - 'method_id' => $method->id, - 'method_title' => $method->method_title, - 'method_description' => $method->method_description, - 'settings' => $settings, - '_links' => array( - 'self' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ), - ), - ), - 'collection' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods' ), - ), - ), - 'describes' => array( - array( - 'href' => rest_url( '/wc/v3/shipping/zones/' . $zone->get_id() ), - ), - ), - ), - ); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertContains( $expected, $data ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( $expected, $data ); - } - - /** - * Test getting all Shipping Zone Methods with a bad zone ID. - * - * @since 3.5.0 - */ - public function test_get_methods_invalid_zone_id() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/1/methods' ) ); - - $this->assertEquals( 404, $response->get_status() ); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/1/methods/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test getting a single Shipping Zone Method with a bad ID. - * - * @since 3.5.0 - */ - public function test_get_methods_invalid_method_id() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Zone 1' ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/1' ) ); - - $this->assertEquals( 404, $response->get_status() ); - } - - /** - * Test updating a Shipping Zone Method. - * - * @since 3.5.0 - */ - public function test_update_methods() { - wp_set_current_user( $this->user ); - - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - - // Test defaults - $request = new WP_REST_Request( 'GET', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '0', $data['settings']['cost']['value'] ); - - // Update a single value - $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 5, - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'taxable', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '5', $data['settings']['cost']['value'] ); - - // Test multiple settings - $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 10, - 'tax_status' => 'none', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'title', $data['settings'] ); - $this->assertEquals( 'Flat rate', $data['settings']['title']['value'] ); - $this->assertArrayHasKey( 'tax_status', $data['settings'] ); - $this->assertEquals( 'none', $data['settings']['tax_status']['value'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '10', $data['settings']['cost']['value'] ); - - // Test bogus - $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'settings' => array( - 'cost' => 10, - 'tax_status' => 'this_is_not_a_valid_option', - ), - ) - ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 400, $response->get_status() ); - - // Test other parameters - $this->assertTrue( $data['enabled'] ); - $this->assertEquals( 1, $data['order'] ); - - $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_body_params( - array( - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertFalse( $data['enabled'] ); - $this->assertEquals( 2, $data['order'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '10', $data['settings']['cost']['value'] ); - } - - /** - * Test creating a Shipping Zone Method. - * - * @since 3.5.0 - */ - public function test_create_method() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - $request = new WP_REST_Request( 'POST', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods' ); - $request->set_body_params( - array( - 'method_id' => 'flat_rate', - 'enabled' => false, - 'order' => 2, - ) - ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertFalse( $data['enabled'] ); - $this->assertEquals( 2, $data['order'] ); - $this->assertArrayHasKey( 'cost', $data['settings'] ); - $this->assertEquals( '0', $data['settings']['cost']['value'] ); - } - - /** - * Test deleting a Shipping Zone Method. - * - * @since 3.5.0 - */ - public function test_delete_method() { - wp_set_current_user( $this->user ); - $zone = $this->create_shipping_zone( 'Zone 1' ); - $instance_id = $zone->add_shipping_method( 'flat_rate' ); - $methods = $zone->get_shipping_methods(); - $method = $methods[ $instance_id ]; - $request = new WP_REST_Request( 'DELETE', '/wc/v3/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ); - $request->set_param( 'force', true ); - $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - } -} diff --git a/unit-tests/Tests/Version3/system-status.php b/unit-tests/Tests/Version3/system-status.php deleted file mode 100644 index cdf30aedaef..00000000000 --- a/unit-tests/Tests/Version3/system-status.php +++ /dev/null @@ -1,487 +0,0 @@ -user->create( - array( - 'role' => 'administrator', - ) - ); - } - - /** - * Setup our test server. - */ - public function setUp() { - parent::setUp(); - - wp_set_current_user( self::$user ); - - $this->endpoint = new WC_REST_System_Status_Controller(); - - // Callback used by WP_HTTP_TestCase to decide whether to perform HTTP requests or to provide a mocked response. - $this->http_responder = array( $this, 'mock_http_responses' ); - } - - /** - * Test route registration. - */ - public function test_register_routes() { - $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v3/system_status', $routes ); - $this->assertArrayHasKey( '/wc/v3/system_status/tools', $routes ); - $this->assertArrayHasKey( '/wc/v3/system_status/tools/(?P[\w-]+)', $routes ); - } - - /** - * Test to make sure system status cannot be accessed without valid creds - * - * @since 3.5.0 - */ - public function test_get_system_status_info_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure root properties are present. - * (environment, theme, database, etc). - * - * @since 3.5.0 - */ - public function test_get_system_status_info_returns_root_properties() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - $data = $response->get_data(); - - $this->assertArrayHasKey( 'environment', $data ); - $this->assertArrayHasKey( 'database', $data ); - $this->assertArrayHasKey( 'active_plugins', $data ); - $this->assertArrayHasKey( 'theme', $data ); - $this->assertArrayHasKey( 'settings', $data ); - $this->assertArrayHasKey( 'security', $data ); - $this->assertArrayHasKey( 'pages', $data ); - } - - /** - * Test to make sure environment response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_environment() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - $data = $response->get_data(); - $environment = (array) $data['environment']; - - // Make sure all expected data is present. - $this->assertEquals( 32, count( $environment ) ); - - // Test some responses to make sure they match up. - $this->assertEquals( get_option( 'home' ), $environment['home_url'] ); - $this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] ); - $this->assertEquals( WC()->version, $environment['version'] ); - } - - /** - * Test to make sure that it is possible to filter - * the environment fields returned in the response. - */ - public function test_get_system_status_info_environment_filtered_by_field() { - $expected_data = array( - 'environment' => array( - 'version' => WC()->version - ) - ); - - $request = new WP_REST_Request( 'GET', '/wc/v3/system_status' ); - $request->set_query_params( array( '_fields' => 'environment.version' ) ); - - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( $expected_data, $data ); - } - - /** - * Test to make sure database response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_database() { - global $wpdb; - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - $data = $response->get_data(); - $database = (array) $data['database']; - - $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); - $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); - $this->assertArrayHasKey( 'woocommerce', $database['database_tables'], wc_print_r( $database, true ) ); - $this->assertArrayHasKey( $wpdb->prefix . 'woocommerce_payment_tokens', $database['database_tables']['woocommerce'], wc_print_r( $database, true ) ); - } - - /** - * Test to make sure active plugins response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_active_plugins() { - $actual_plugins = array( 'hello.php' ); - update_option( 'active_plugins', $actual_plugins ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - update_option( 'active_plugins', array() ); - - $data = $response->get_data(); - $plugins = (array) $data['active_plugins']; - - $this->assertEquals( 1, count( $plugins ) ); - $this->assertEquals( 'Hello Dolly', $plugins[0]['name'] ); - } - - /** - * Test to make sure theme response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_theme() { - $active_theme = wp_get_theme(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - $data = $response->get_data(); - $theme = (array) $data['theme']; - - $this->assertEquals( 13, count( $theme ) ); - $this->assertEquals( $active_theme->Name, $theme['name'] ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar - } - - /** - * Test to make sure settings response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_settings() { - $term_response = array(); - $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); - foreach ( $terms as $term ) { - $term_response[ $term->slug ] = strtolower( $term->name ); - } - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - $data = $response->get_data(); - $settings = (array) $data['settings']; - - $this->assertEquals( 12, count( $settings ) ); - $this->assertEquals( ( 'yes' === get_option( 'woocommerce_api_enabled' ) ), $settings['api_enabled'] ); - $this->assertEquals( get_woocommerce_currency(), $settings['currency'] ); - $this->assertEquals( $term_response, $settings['taxonomies'] ); - } - - /** - * Test to make sure security response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_security() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - $data = $response->get_data(); - $settings = (array) $data['security']; - - $this->assertEquals( 2, count( $settings ) ); - $this->assertEquals( 'https' === substr( wc_get_page_permalink( 'shop' ), 0, 5 ), $settings['secure_connection'] ); - $this->assertEquals( ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), $settings['hide_errors'] ); - } - - /** - * Test to make sure pages response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_status_info_pages() { - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status' ) ); - $data = $response->get_data(); - $pages = $data['pages']; - $this->assertEquals( 5, count( $pages ) ); - } - - /** - * Test system status schema. - * - * @since 3.5.0 - */ - public function test_system_status_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/system_status' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - $this->assertEquals( 10, count( $properties ) ); - $this->assertArrayHasKey( 'environment', $properties ); - $this->assertArrayHasKey( 'database', $properties ); - $this->assertArrayHasKey( 'active_plugins', $properties ); - $this->assertArrayHasKey( 'theme', $properties ); - $this->assertArrayHasKey( 'settings', $properties ); - $this->assertArrayHasKey( 'security', $properties ); - $this->assertArrayHasKey( 'pages', $properties ); - } - - /** - * Test to make sure get_items (all tools) response is correct. - * - * @since 3.5.0 - */ - public function test_get_system_tools() { - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status/tools' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $raw_tools ), count( $data ) ); - $this->assertContains( - array( - 'id' => 'regenerate_thumbnails', - 'name' => 'Regenerate shop thumbnails', - 'action' => 'Regenerate', - 'description' => 'This will regenerate all shop thumbnails to match your theme and/or image settings.', - '_links' => array( - 'item' => array( - array( - 'href' => rest_url( '/wc/v3/system_status/tools/regenerate_thumbnails' ), - 'embeddable' => 1, - ), - ), - ), - ), - $data - ); - - $query_params = array( - '_fields' => 'id,name,nonexisting', - ); - $request = new WP_REST_Request( 'GET', '/wc/v3/system_status/tools' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $raw_tools ), count( $data ) ); - $this->assertContains( - array( - 'id' => 'regenerate_thumbnails', - 'name' => 'Regenerate shop thumbnails', - ), - $data - ); - foreach ( $data as $item ) { - // Fields that are not requested are not returned in response. - $this->assertArrayNotHasKey( 'action', $item ); - $this->assertArrayNotHasKey( 'description', $item ); - // Links are part of data in collections, so excluded if not explicitly requested. - $this->assertArrayNotHasKey( '_links', $item ); - // Non existing field is ignored. - $this->assertArrayNotHasKey( 'nonexisting', $item ); - } - - // Links are part of data, not links in collections. - $links = $response->get_links(); - $this->assertEquals( 0, count( $links ) ); - } - - /** - * Test to make sure system status tools cannot be accessed without valid creds - * - * @since 3.5.0 - */ - public function test_get_system_status_tools_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status/tools' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure we can load a single tool correctly. - * - * @since 3.5.0 - */ - public function test_get_system_tool() { - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - $raw_tool = $raw_tools['recount_terms']; - - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status/tools/recount_terms' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertEquals( 'Term counts', $data['name'] ); - $this->assertEquals( 'Recount terms', $data['action'] ); - $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); - - // Test for _fields query parameter. - $query_params = array( - '_fields' => 'id,name,nonexisting', - ); - $request = new WP_REST_Request( 'GET', '/wc/v3/system_status/tools/recount_terms' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertEquals( 'Term counts', $data['name'] ); - $this->assertArrayNotHasKey( 'action', $data ); - $this->assertArrayNotHasKey( 'description', $data ); - // Links are part of links, not data in single items. - $this->assertArrayNotHasKey( '_links', $data ); - - // Links are part of links, not data in single item response. - $links = $response->get_links(); - $this->assertEquals( 1, count( $links ) ); - } - - /** - * Test to make sure a single system status toolscannot be accessed without valid creds. - * - * @since 3.5.0 - */ - public function test_get_system_status_tool_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/system_status/tools/recount_terms' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test to make sure we can RUN a tool correctly. - * - * @since 3.5.0 - */ - public function test_execute_system_tool() { - $tools_controller = new WC_REST_System_Status_Tools_Controller(); - $raw_tools = $tools_controller->get_tools(); - $raw_tool = $raw_tools['recount_terms']; - - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v3/system_status/tools/recount_terms' ) ); - $data = $response->get_data(); - - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertEquals( 'Term counts', $data['name'] ); - $this->assertEquals( 'Recount terms', $data['action'] ); - $this->assertEquals( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', $data['description'] ); - $this->assertTrue( $data['success'] ); - $this->assertEquals( 1, did_action( 'woocommerce_rest_insert_system_status_tool' ) ); - - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v3/system_status/tools/not_a_real_tool' ) ); - $this->assertEquals( 404, $response->get_status() ); - - // Test _fields for execute system tool request. - $query_params = array( - '_fields' => 'id,success,nonexisting', - ); - $request = new WP_REST_Request( 'PUT', '/wc/v3/system_status/tools/recount_terms' ); - $request->set_query_params( $query_params ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 'recount_terms', $data['id'] ); - $this->assertTrue( $data['success'] ); - - // Fields that are not requested are not returned in response. - $this->assertArrayNotHasKey( 'action', $data ); - $this->assertArrayNotHasKey( 'name', $data ); - $this->assertArrayNotHasKey( 'description', $data ); - // Links are part of links, not data in single item response. - $this->assertArrayNotHasKey( '_links', $data ); - // Non existing field is ignored. - $this->assertArrayNotHasKey( 'nonexisting', $data ); - - // Links are part of links, not data in single item response. - $links = $response->get_links(); - $this->assertEquals( 1, count( $links ) ); - } - - /** - * Test to make sure a tool cannot be run without valid creds. - * - * @since 3.5.0 - */ - public function test_execute_system_status_tool_without_permission() { - wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'POST', '/wc/v3/system_status/tools/recount_terms' ) ); - $this->assertEquals( 401, $response->get_status() ); - } - - /** - * Test system status schema. - * - * @since 3.5.0 - */ - public function test_system_status_tool_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/system_status/tools' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $properties = $data['schema']['properties']; - - $this->assertEquals( 6, count( $properties ) ); - $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'name', $properties ); - $this->assertArrayHasKey( 'action', $properties ); - $this->assertArrayHasKey( 'description', $properties ); - $this->assertArrayHasKey( 'success', $properties ); - $this->assertArrayHasKey( 'message', $properties ); - } - - /** - * Provides a mocked response for external requests performed by WC_REST_System_Status_Controller. - * This way it is not necessary to perform a regular request to an external server which would - * significantly slow down the tests. - * - * This function is called by WP_HTTP_TestCase::http_request_listner(). - * - * @param array $request Request arguments. - * @param string $url URL of the request. - * - * @return array|false mocked response or false to let WP perform a regular request. - */ - protected function mock_http_responses( $request, $url ) { - $mocked_response = false; - - if ( in_array( $url, array( 'https://www.paypal.com/cgi-bin/webscr', 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=0' ), true ) ) { - $mocked_response = array( - 'response' => array( 'code' => 200 ), - ); - } elseif ( 'https://api.wordpress.org/themes/info/1.0/' === $url ) { - $mocked_response = array( - 'body' => 'O:8:"stdClass":12:{s:4:"name";s:7:"Default";s:4:"slug";s:7:"default";s:7:"version";s:5:"1.7.2";s:11:"preview_url";s:29:"https://wp-themes.com/default";s:6:"author";s:15:"wordpressdotorg";s:14:"screenshot_url";s:61:"//ts.w.org/wp-content/themes/default/screenshot.png?ver=1.7.2";s:6:"rating";d:100;s:11:"num_ratings";s:1:"3";s:10:"downloaded";i:296618;s:12:"last_updated";s:10:"2010-06-14";s:8:"homepage";s:37:"https://wordpress.org/themes/default/";s:13:"download_link";s:55:"https://downloads.wordpress.org/theme/default.1.7.2.zip";}', - 'response' => array( 'code' => 200 ), - ); - } - - return $mocked_response; - } -} diff --git a/unit-tests/bin/install.sh b/unit-tests/bin/install.sh deleted file mode 100755 index 8ab83ff1a13..00000000000 --- a/unit-tests/bin/install.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash - -if [ $# -lt 3 ]; then - echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" - exit 1 -fi - -DB_NAME=$1 -DB_USER=$2 -DB_PASS=$3 -DB_HOST=${4-localhost} -WP_VERSION=${5-latest} -SKIP_DB_CREATE=${6-false} - -TMPDIR=${TMPDIR-/tmp} -TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//") -WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib} -WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress/} - -# Error if WP < 5 -if [[ $WP_VERSION =~ ^([0-9]+)[0-9\.]+\-? ]]; then - if [ "5" -gt "${BASH_REMATCH[1]}" ]; then - echo "You must use WordPress 5.0 or greater." - exit 1 - fi -fi - -download() { - if [ `which curl` ]; then - curl -s "$1" > "$2"; - elif [ `which wget` ]; then - wget -nv -O "$2" "$1" - fi -} - -if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then - WP_TESTS_TAG="branches/$WP_VERSION" -elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then - if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then - # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x - WP_TESTS_TAG="tags/${WP_VERSION%??}" - else - WP_TESTS_TAG="tags/$WP_VERSION" - fi -elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - WP_TESTS_TAG="trunk" -else - # http serves a single offer, whereas https serves multiple. we only want one - download http://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json - grep '[0-9]+\.[0-9]+(\.[0-9]+)?' $TMPDIR/wp-latest.json - LATEST_VERSION=$(grep -o '"version":"[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//') - if [[ -z "$LATEST_VERSION" ]]; then - echo "Latest WordPress version could not be found" - exit 1 - fi - WP_TESTS_TAG="tags/$LATEST_VERSION" -fi - -set -ex - -install_wp() { - - if [ -d $WP_CORE_DIR ]; then - return; - fi - - mkdir -p $WP_CORE_DIR - - if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - mkdir -p $TMPDIR/wordpress-nightly - download https://wordpress.org/nightly-builds/wordpress-latest.zip $TMPDIR/wordpress-nightly/wordpress-nightly.zip - unzip -q $TMPDIR/wordpress-nightly/wordpress-nightly.zip -d $TMPDIR/wordpress-nightly/ - mv $TMPDIR/wordpress-nightly/wordpress/* $WP_CORE_DIR - else - if [ $WP_VERSION == 'latest' ]; then - local ARCHIVE_NAME='latest' - elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then - # https serves multiple offers, whereas http serves single. - download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json - if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then - # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x - LATEST_VERSION=${WP_VERSION%??} - else - # otherwise, scan the releases and get the most up to date minor version of the major release - local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'` - LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1) - fi - if [[ -z "$LATEST_VERSION" ]]; then - local ARCHIVE_NAME="wordpress-$WP_VERSION" - else - local ARCHIVE_NAME="wordpress-$LATEST_VERSION" - fi - else - local ARCHIVE_NAME="wordpress-$WP_VERSION" - fi - download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz - tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR - fi - - download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php -} - -install_test_suite() { - # portable in-place argument for both GNU sed and Mac OSX sed - if [[ $(uname -s) == 'Darwin' ]]; then - local ioption='-i .bak' - else - local ioption='-i' - fi - - # set up testing suite if it doesn't yet exist - if [ ! -d $WP_TESTS_DIR ]; then - # set up testing suite - mkdir -p $WP_TESTS_DIR - svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes - svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data - fi - - if [ ! -f wp-tests-config.php ]; then - download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php - # remove all forward slashes in the end - WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php - fi - -} - -install_db() { - - if [ ${SKIP_DB_CREATE} = "true" ]; then - return 0 - fi - - # parse DB_HOST for port or socket references - local PARTS=(${DB_HOST//\:/ }) - local DB_HOSTNAME=${PARTS[0]}; - local DB_SOCK_OR_PORT=${PARTS[1]}; - local EXTRA="" - - if ! [ -z $DB_HOSTNAME ] ; then - if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then - EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" - elif ! [ -z $DB_SOCK_OR_PORT ] ; then - EXTRA=" --socket=$DB_SOCK_OR_PORT" - elif ! [ -z $DB_HOSTNAME ] ; then - EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" - fi - fi - - # create database - mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA -} - -install_deps() { - - # Script Variables - WP_SITE_URL="http://local.wordpress.test" - BRANCH=$TRAVIS_BRANCH - REPO=$TRAVIS_REPO_SLUG - WORKING_DIR="$PWD" - - if [ "$TRAVIS_PULL_REQUEST_BRANCH" != "" ]; then - BRANCH=$TRAVIS_PULL_REQUEST_BRANCH - REPO=$TRAVIS_PULL_REQUEST_SLUG - fi - - # Set up WordPress using wp-cli - mkdir -p "$WP_CORE_DIR" - cd "$WP_CORE_DIR" - - curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar - php wp-cli.phar core config --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS --dbhost=$DB_HOST --dbprefix=wptests_ - php wp-cli.phar core install --url="$WP_SITE_URL" --title="Example" --admin_user=admin --admin_password=password --admin_email=info@example.com --path=$WP_CORE_DIR --skip-email - - # Install WooCommerce and WooCommerce Admin - cd "wp-content/plugins/" - - git clone --depth 1 https://github.com/woocommerce/woocommerce.git - - cd "woocommerce" - composer install - - cd "$WP_CORE_DIR" - php wp-cli.phar plugin activate woocommerce - - if [ "$BRANCH" != "" ]; then - # Install the correct branch of the plugin, if running from Travis CI. - php wp-cli.phar plugin install https://github.com/$REPO/archive/$BRANCH.zip --activate - fi - - # Back to original dir - cd "$WORKING_DIR" -} - -install_wp -install_test_suite -install_db -install_deps diff --git a/unit-tests/bin/phpcs.sh b/unit-tests/bin/phpcs.sh deleted file mode 100755 index 5a2c8b48a05..00000000000 --- a/unit-tests/bin/phpcs.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -if [[ ${RUN_PHPCS} == 1 ]]; then - CHANGED_FILES=`git diff --name-only --diff-filter=ACMR $TRAVIS_COMMIT_RANGE | grep \\\\.php | awk '{print}' ORS=' '` - IGNORE="" - - if [ "$CHANGED_FILES" != "" ]; then - echo "Running Code Sniffer." - ./vendor/bin/phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES - fi -fi diff --git a/unit-tests/bin/phpunit.sh b/unit-tests/bin/phpunit.sh deleted file mode 100755 index 12e95676881..00000000000 --- a/unit-tests/bin/phpunit.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -$HOME/.composer/vendor/bin/phpunit -c phpunit.xml $@ \ No newline at end of file diff --git a/unit-tests/data/Dr1Bczxq4q.png b/unit-tests/data/Dr1Bczxq4q.png deleted file mode 100644 index 4a2bb205fe40d4d8c5125399ffc585bc65595323..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10325 zcmZX31yEeg()Qx+A&{U!6Wm<_Z14a90t5*T!4_NGArKZPxRb@*-Q5Dq;!c17i@V#$ zd++_f?^gX&HK+SbcRzjlnVP9H=Rnj{yHJOz26`m=0)?lG9?&({uN$6o*d zE~%A_jGBUs46T}zy@i#nIRGFJNzlg7j2n8H*^x^~tV@fmE^Qxp&eGur)gf^@kEvC*y`z4Z>&s%79HOI@!>{BK*u+KrO*Vz5p=2)9syJ!=y zB|6}PjTQ(bP>lK>U(%3}3elsitZ4Dm)1Pu2plO6dsbgzg?xv|p?$0yxWDsJH1Y9y~ zcrkE0d-B9GOj#a-2OvgsWRV*j3%JGvG>V97#}EL1QSIVw{oM{bq3tb3mL~+zarEz~ zmvZzMsf#I?kWd`pRFMJ9Si%|QG2To4PW#fS^26~(FJ;*cB{j|Z>rnBzS8Vvb1hkp) zal8~JA9#B6i&py-p7efCog}kq-3ldc(GgYCs3xb4re67R3_K;K+rsB4Z!16XqDsNn z)7P4(%}4P`O<8&eZi0~WSuN!#ryF-Ql$#>pt?uu6!gV*RK>u$=c=?(1lp{Db zCN&JsUAmpEr@SUXx$Qc1+R5Ys{Q*4}XGu<-Li)bx5ftbpBh0#6dOy>s7;6UVooY~W z^7bOAUcBs$xN+U?L5?d&xnzhVC1y;s5fYSS(Hh2+lOjJx^YzC9R^|oH(~=yEpr>N| z;oOl27$G6aW9S>bn~d;ake9tara-~&$|7_Oa9D!L@eHG(sXdwNvp(ns@(q0p=%vRI z3lhSZ?G<+r6vOpxGpgy!a7^Ns%wL}?1^Pj0xI@X`^HFSfg_PD9lK@sa;KALQI5i~B zYtfs>?9^+oeuW=@cZeI8X~bFY(olGjGR^ii_7BFEG9kXFQ7zz$YY~^lQ!*Y1_lxKs ziAK@C1Wg;b`XoB*ms}+FOC(!cfVx%Q7m?0)^@);W%oYzm50HrUBB%yZkw`>?>x>TOu(+u!z8CydBu``4?Pka6UyGdA z5!AWT^LsP~CEEI)cw(J3IiK~Vb-B47iXm}|(`W7AshV=|Cd2Aedu!|J9Z}zV*DFOw zHQ)}VL~@mTPi|(Qcjmodne5onK?hKJp#yxb)5iYbv0c>x(h+9isA%dL*Fxy1?~%eB zw7&tUi~!2U67`)#jYyn-2&CULgrX@JG3lS+#-IqpkZ?NH)sTlfbt{Q91MG~L3sLU6 z-i+f$1@ZntZp0Sp`shG2^MS@43%!erT#E4f_i;iIXaIsvHWbYyT!@}JRFXIZNUtD| z{WI#Ah^QLyB_#gMraWmiN|BuJhp0D}F(dM1PGlYt=k)e5s&7NoKYiAu;Fo3287mZg z9o7%!9S8Ffumi*4)880%!w+TB#(5E+&zTm2+JQf~{D(|&l?iHk)42`Vh?V*$xRB~G zS^HQjbxVnCf}hS@N--!pCDwuIQM`^yI%!hwlwbw|9%rs$b#8|C5N@W*1kiJO9BC+!@na?ugrgJDTg0tC0&*r`bXIl3A)$&xjEdH{|U^)D+m74dY2F{JM1xxGOXv} z;o;*!c2jgJcEfm@aEh_XIV73*B>(wWs)kR|WD(u2^)B_U)vm#=-s?yU-MiXIiG=9^?J45X%{exy-~Rl_O?H7sr52+;ehyqcX6 zLxzo^NsR4>?!;O#N8>Bavy5hRKC#sA(@!`I5!B z@=`ogw^C+OSGed?h11Ma?6~*%WK&~w(S zx2rqA6HPVnUp8rZ*)n_i@>2heYJz;Z zumRU-YE^O7M9Z>m5>6D(s98|O_KL+y%F11<;f>B6rgzkB>y^ue0m5s6;0))S^ z`y~3T;?(a&HcbrmI3X7~f>22E7)M%*-6ht*N;wy-L;!OpF7}M=I2* zTatDgwe36jlS=uksm45}hY=&Z{FW9lF>WQtmo_tNFQgTvhgafZrSe+rHgEZb>X=+& z4n|gbeTPogZU3A*FE?#2ZCf2$ZCY_oEKklBTv@tXXqw?3dwYCtolTKSS>#!@{9th~ z^m208-7gS?O<;k}5Q6AS4a_RaZeBz7``f$v#^L{s%Lif*DE{jDJ8a@wS%i3&SkE4H*d1~Le6S=xOu(ztUU2^ny%-*LJdMk20Q1Px~ zMdXEN;X&ouT0gz4oORShbfUnUk7udqX}qakx<7TBqk<`IY+P)_Z_}pjy`uK0DkOfn znv5z853R@L6kx03WsHf7J1{*c+b@>Z-&vBtR)hpE^apOn&yqM$^@Y6Pck4w;he=U} zu5I4?VP^?jB~jXG3seiykB7&1aQuO&d>fTnT@eEjy_S4%#{T8Lg!A&zZ7@ZbVEIZ! z+LDK(;N9V#7uuEVA*aWCcePu!9pgUwGP$}ZuDgK%>VZs>=m+Ws zNr;D2N7C}$Y0>e{cKf|?YECGkJ@R$X%>HlvLV&Y z$X>-|S8rGQY~XB;y;j?_d&_plLreXy!e4Sd!aejyN|N8a3-1v3C+h{@Rbg^l-b_B_ z_a>Kl7dD7lj2z*doF+CTB`4BOBbmtwfO`!FK$o~x6pZ}-Q%rjsL!kU>I5FxYNn$&U z0ok6zs}&Hchy0$rHODr16w`!dzfb!}htq#yK2k6Rb8_D{ud47EP3D?Q~ zM9s;e*OQg&*bg*2LUs^Qz1vCtx|qe{lu? zUNZjEkrdP!jsXCq3@c3?u+B$i5mS3R4r4QW6LSuCJBMd)06@%Ld2OHD6+u4Gg zMcl>d{^cR^tp792Nk{uH7qE>uoz6!!S{ZvMb6S25J`OHA32a(gS}`Xx3lVjo?0>?a z@5Jf8fx!+UoSbfMZX9mB9QIC@oZP~~!kk<@oIE`2&mQc~9w4x>J3Gjk{@)<~4+m)O zZ0cm?0JgFR(f)&LY+~;M7N?{8C(-}5e?O+B^I0PQGd0gm{<**Xk9^i~!e8K)hCfSf z1)!9sJJPZCCwJ_U)vRqc9gRH*y0qQ+STS8;843$>)X3NmGrRf(c8$970cBi;NA9zHQRz zzU$1a_xj#Idj*at!oeeZLaJ}>U!}lgif&NL%;Ck;%>Ayvy)8C^hU*FKHYqih#_eJd?;$r*2s)<^(JW-AG=IBi;{h+AO-UEff!1r0Lwuk+dwW zSNZ>T%NIz2yL%`9Zoc?nc5ae^e{H6AHA~HwRX5`?mW+5iB<9zJ#Q?)acN*=zL#<7? zuh++wI!A9Vn?x1~`#`|A|HX1-wc%qKL)bH7A}Qd7DT|J^05%-0?zrk}z5F?+w>o4=@l9y68&Mk^;fHdRz==+ut5w1}w+ ziv~DJ`gKinvUiB<Qd1Q7Ey#EOKARlpW7D&q$jFW{xB=&MX%c_jF^g#KS$TF+8<6<=>z-w+^~(`?Xj z3I_(AO;Wh-*&@tyT)SB1E4i7=HT4p>z0*8Wi5eRIFgS`0=l7>R)v@+cW>d%#OG6xY z&FM`N{zF9mFYcCdnXBb zK~6ZLOs4&3`6*Vac#UZ8$2ZO2Ip;8U7(WR#En?M_UDiE*_B}K$>W#?E*0qRg*V6J# z({hbpd3h=lx*~Las?jv~jvKoWg^YtRvH1t0bmPP-@*>G8DrLa#B!2bOQjJWDwaz@v zO~!bXF5M=}Gq;r?wvbW0c5xuwnt0$9YGSW#^3tiLvS55O%=!FQIaOl5?U7kt$RbK^ zqe5GzpLdck&3|^CSwkoMVqL{{__AOI3(C72CE!nOCrp`75e*Zg2L4dU0iNh}$iA4fpqX>84wb zG|_(Zo!_gvaw^b=jwQD&@WYSfIZ*S`ex(!GI)|xb?L#YqYTAbv z=C^T^~z56lI3xziK!l(Xx8}-S3|XhC9^NWxj>y`DbUxLy@Tn;Cd9- zEWTw9*MTPpJ>N(5G48WQ-V>B*8#^r8n=R2Z_W$Tti)M)p1_7W_i`n5Zp+@iw!U z*GlZxJmRYEnRyeYM}3J#Xo2MKRSp~;UBZk{ekOVfFi7oBaZ$EA6 z^reX_g)9OKrd1)J`CT0;@P}>>w#B#=quM>A2b^|4A@*h{=v$;4|6o48C1x z&f7PvnNFIDd)%?&Yel!m(E^^EXY9qy?Lml$<{Udl+MZN4 zG5Ueuj&I=!l}-91X^96P#6KT>xAb!6bfpz8CoT*;plw3zHA#>OO6yVsx{Y%GjTK898;RO3PQ-b&D}B2$&KQ|(K+tiF2_PriQO?;gK7M)J)vWK~&ZFBX^hXdlP$9hU){st>L*S+dL=++^|35 z^||AR0W!L1!?t!!_m78jySNjt8xCIC5gCa2AMRu_)pH;Z@UDtu)qsUOU=cf*?QF`W zbFWI+|5G#j_}W5F5O8;rv}))mft{J6P0rVYYwhM_sloP{`K7o8+}nK(G7nkW095!a z2{F)cV0*KTAATn;h-^fKAG-OxGV<-CLo@B)2iV^toq9%ut!y;t@p!V$`C<;aa;Rzx zd5lxp8Q9WTBGw9&#b}oMt8fnj9{(JQhpwz&c6xjSYub4)lxu>^XCAnuz(pN_deN#r z@TA97L{lL1pSquEPjyO;gk@h)b)h|(tYAVPD!7YxZ{o=dg=cj-qfH*&o>>+oWSmZ( zc;&hgwz8M;Nj=WRE+nv^jE2+)uMN^Jtz`qlwDi|Ayqx)vHHc93r#B?uU0agtQskOj zs7GA(&EP;KA?(43vs^R1?>VeNgB>-{hGfKt)qJHY>&*iX!nO})+rrHKdOmVPrh1o6 zyrn&F<6It9Y44e zg6yBv$l}xk^h9~2^u)u*6ZH>-(Ls8q9^k2~*eEehUJz2v(bvTJLWDTqmv!VMTlQ0_ zJf_;IjFG&DNg>C6UmdVX%1r2IX2ryfNBj4E+;?l_jiVxzQF1>nqNnTYxp894I;46T&OkhEpWcj96j!V^ z|NaSJi2Gc11qW)#Js5C+?rX{ zw6_-6uJ2Ic%*I|X;pTI`Dfm!TrrsiIpc`_Ybq#Qv@vf9X%XTIzq9=8w4^RW~{hZ7|B$%S%gP(AU;+dHg&4AsutSUw92lSrAD3kBI3=sbd? zmAlup{H|I95r>+Pbust|pjrGKvE7Mlz8`UpuAIa_7;RsmG`60cID(;%Jl_mAghJa1 zW@&FFmR2nImCjvTx;rv_7a3N#90(uqvL$)`iorde%4m9owk5prwExVEy&in8MPIvR z?q|3Z@p|qHX=qjqd459URZj;Vm85kkCFTD2ZJg5cs&|i*)r+LgNu1gV?Z6Y)AuqUh z5CXk2y;AqXo~mA!HM{U+>gTJI%gyLheT?I7-jp;W`c*3w+~Wae2;xTWHXb2(ZwS%g zBsgsAq4kVbNSp)832K}7NGTr9%iE6DCgDh&vYQ8@98b|8$e=JHH*roM1{N$REAgl! zXLe-Tp=Od3*x_RD1pzxD^lT_H(*K+X^8ImQr zEXCmd)`Z`T`sFKONF!nS(eRg+rv%J#lEb;<&(k1k|rVa?_wZJqa_D&h;mF#l*m z-MO#gRzq~n*sX*Pq$djuZO@pAA51*V^0D|LYILYe*2oy=iW0Fc=F^WHa|x-O2Wa9A zPu==9_9Ty+x5AC05KU0#MRn_H*4f1;Bmm&)i2)M$007`u|MQA{V6fx4CxUNt`$!-< z(spLE1xD?z%pO&mU~nb&E0~u3#DED8i`&wFyvXYCYnRXt>V&D%B#vyJ_WgQne8E@+ zmU`(VIhn3mV-=rb>78JAkyVoJ81&>f(ean-w!MS%#JS1)hYTXkoaWE^rp&p-@QBo4 z?*UBqs4vv!RO%dZFlmvEpG5O~_#T91^@45~c?x){?q$w%FklBZg8s2{XaypNfD3bl zjPyb@{3*}_6$M7e-?CkCL#jCO+X2>!Xm6fd5!r3LCXUMKS=XY4$A9paK8c)MM>^Pf-G z-l1P*efiaMI^B=6f%85L9nIq?sF~(zrWbE1KuotN>yERGm&oEjul{)WF!*T~fHd1@ zx7r>L6FT4-$&Z)7BO00h@hA{Lq}YKeic_rn{yukmn7KufCMimAlN%2NnrEPaWS8ol*8sNc+IV(P4h}HcIdOZi(?G^~;ZbLgvn6YH@|hIn2@w4)Vk#$=EAcNtYzB^pR(ly3qTr2XpN;9XH_mDX;!x}PF5ajO&UX3hqZ zpVtG&+1LdyiTHZ|pVNp;lp^sMuQBzs`*&aaX6vsoGXz~zOmiz{0_r=cSs;G|zwVs1 zXV#luB|I*JY`EA0So0qk+BkK z_u4xs-A=B|1|2+T`aU7)bkXYYU`7HcsIwa}Qc8f-In{EE{!#!#5EHqO7RouW#?RwP z5MXl~Y7_Zx;XadWmu+BAI2KOQ`7p&-9VW6}z(HSCbB+_A+6d|}YpqB;8fp}ij}%V5 zdefX!qqV)|_HHe-J)MgQ^5>g^?+8P=MV+rMbQS=~Ufl_Iiiw0XIpA~fa%@+x_%8}G0CmAN2rvjzCUj?<|p5#N5&kb zA-sPL8jU;-}UiDm-NvGGBH* zp{&Oz2?2&lYI7FVUL-#Df0i@Zofk)&qU>%KdbHM!EC2uf% zX`IG8OP=ORe)(-pE8mPj;Zvehh01{0NORf!sl^J^`Ah$Wq`hf+BI1E9hnY@f>@V9v z7h#IS{gB@TgjW75qXh&}lvrGYDSLna7iUQmwr8iYQO^Ox9FiP@F@$`+wumH&J*zu0 z(EF{>A^ii-Oq{Ys-eYi_?1w`0r(1mukEC4)L}i_*TtXnFakG(R%DnaKSaM*phLMm;OQ_qzTDW0ZbCj;=lygNHM!rzbIW? z;FJLaFbb)bh#U<<{PMDbM&}4UcW}ky9_9B)w#v8bxx_478!H14;!D8wapNuYF6L^* zEg3M%H=6`A6ZAq9TJ@hX<2uAt2V(i6fWJ=oj!-2-YB_}O#7TZuz@Zd)0YK4UaJae< zLHlmZy5_EQ$|lNXhHo~krhDqmE5>M7w!I&v(MqdFNu058AC#%T^o6LBB*G|Ph^ew! z-^aY^l3~)!HS7=bEGxaZUHF=Dc$fG&oO3seX(6a*K;6R@A=zB)qo{~GXXSu#>op*)G}J76)5&2u;&GFo(unKYdiy9P=KUUBCcYUo=N&b1iNz>B?$e z`R<4s-p~PIUB?l1vf%G~e&)3>vM#)rta~Vo@THMDBQo zAK*D9XG}6scD03wN`F+xY-SpDlxJ>1Ea-0Ws6rlGiJT=Jd0P5v8D;0IecjB*HW>6S)CQ2AB`Rq-#Uch1LDi z_^hgQUUBn&c|j8dB-%X^k*04s8U^_6Pquyni{m_ zekDNzNrr~_Rd*6El|j3J7`DFW?gY-{4P@o4SiCu2eG=X$5+3YhKuyCcXdl4*1u`#!vS4B<73cAW`$5s}&$^9Fv$I(6#*+Ib}o(X9#Az}hDi zxDUPl)OJF4@d;AllC!|9`a`=%Fye9nJ@6+2^&131dxW?p%owZ{sts*Y7QNjeLUv=k zZN+?5Ve#p<{}{=RSke~}LEYt(mJ^=i)X}`LU(z}(d+P!v$@MM=dSR9RL=2ybIEQ$g zIU*iHzp9N!0(U!$v`{^MF z6=jqq2ldUnT9+WgS%`4*bX~ch=g5hZs=WhV&5Zu&C8%6+~q* z7S<(7;zQ#SuQOvQ{K#Q2&^<7w+mV8}*J110bju~g?qHwkg!IPfFEfZjzWOP;;?v&{rao0Wn$Ie-;Ip|sROylv<5A|k~{z87b{E*c;t zr4%eyeqBa#p}qnOr{=OgZ7TP2j`5x-nIZ{+UK8UJwTBudt|Cj7k+6WRmRr*%24g41 zhM3Mqc!WvP>X~jQ(%<>ShpFQ@Q~t06MkAD)6;CZGXmbdE9}Dhvn8@`Lu3!ZbZ<8y? z@IUGu7ec$w!jj~YRFI5~2RB6ev4 zrqv{>e<|ZmIhZBiIo=EyrXT=45T*BrGUvFiGX!M2f7(dk0Sexq{Lqr>v3z!C&MM#jm%MB%eC!=C+LbBg9`#0w={e%}aFoIh$?fqTPKYP8e z#mpmCx0X{YQ1_)T+BZH%>SJseQ5JKt6zig|NHW85aFCdxfgw!i8TK#@E2s Tmze$k{5ewipaLwHHVXV7`I0Rd diff --git a/unit-tests/data/file.txt b/unit-tests/data/file.txt deleted file mode 100644 index 078595600bd..00000000000 --- a/unit-tests/data/file.txt +++ /dev/null @@ -1 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi porta purus dolor, malesuada consequat sem blandit eu. Pellentesque tempor elementum maximus. Phasellus efficitur turpis ante, ac egestas nisl efficitur sit amet. Vestibulum tortor erat, efficitur id nulla eget, malesuada lobortis augue. Ut eleifend ante at pharetra gravida. Quisque suscipit efficitur mauris, quis bibendum massa efficitur id. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vel luctus nisl, ac bibendum nulla. Sed faucibus nibh consectetur urna hendrerit sagittis. Sed bibendum felis in tortor elementum, a porttitor lacus volutpat. Etiam facilisis congue lacinia. Quisque vitae ultricies mauris, non ornare orci. diff --git a/woocommerce-rest-api.php b/woocommerce-rest-api.php deleted file mode 100644 index 075a160c555..00000000000 --- a/woocommerce-rest-api.php +++ /dev/null @@ -1,68 +0,0 @@ - -
-

- composer install', - '' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '' - ); - ?> -

-
- Date: Wed, 22 Jul 2020 10:33:46 -0400 Subject: [PATCH 318/440] update woo blocks to 3.0.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b104fb4686e..aa1205bcb1e 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "pelago/emogrifier": "^3.1", "woocommerce/action-scheduler": "3.1.6", "woocommerce/woocommerce-admin": "1.3.1", - "woocommerce/woocommerce-blocks": "2.7.1", + "woocommerce/woocommerce-blocks": "3.0.0", "woocommerce/woocommerce-rest-api": "1.0.10" }, "require-dev": { From 0897ed68fcc2be789f31ed478bf8de21dfa823f0 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 24 Jul 2020 13:30:21 +0000 Subject: [PATCH 319/440] Update dependency automattic/jetpack-autoloader to v2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index aa1205bcb1e..4c07fc24c60 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "minimum-stability": "dev", "require": { "php": ">=7.0", - "automattic/jetpack-autoloader": "^1.7.0", + "automattic/jetpack-autoloader": "^2.0.2", "automattic/jetpack-constants": "^1.1", "composer/installers": "1.7.0", "league/container": "^3.3", From 3e6c4dd14a5a443391b32de2481932efd585cc12 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Fri, 24 Jul 2020 11:18:56 -0700 Subject: [PATCH 320/440] Updated WooCommerce Admin to 1.4.0-beta.1 The official PR for 1.4.0-beta.2 will be arriving next week and so I've included the first beta here in order to complete the autoloader update. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4c07fc24c60..769f0202e1a 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "maxmind-db/reader": "1.6.0", "pelago/emogrifier": "^3.1", "woocommerce/action-scheduler": "3.1.6", - "woocommerce/woocommerce-admin": "1.3.1", + "woocommerce/woocommerce-admin": "1.4.0-beta.1", "woocommerce/woocommerce-blocks": "3.0.0", "woocommerce/woocommerce-rest-api": "1.0.10" }, From 77eee6d92d7ef6f3978d9871774ef4eb35195d8d Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Fri, 24 Jul 2020 10:59:04 -0700 Subject: [PATCH 321/440] Updated the REST API to 1.0.11 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 769f0202e1a..5f28d3e43d0 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "woocommerce/action-scheduler": "3.1.6", "woocommerce/woocommerce-admin": "1.4.0-beta.1", "woocommerce/woocommerce-blocks": "3.0.0", - "woocommerce/woocommerce-rest-api": "1.0.10" + "woocommerce/woocommerce-rest-api": "1.0.11" }, "require-dev": { "phpunit/phpunit": "7.5.20", From c36ea25eb960d8d202fa1d4bd900ae7449940b67 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Fri, 24 Jul 2020 11:26:47 -0700 Subject: [PATCH 322/440] Updated composer lock file Now that we've got all of the packages updated successfully we can do this! --- composer.lock | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/composer.lock b/composer.lock index 9eb8e969711..437dbdce245 100644 --- a/composer.lock +++ b/composer.lock @@ -4,24 +4,24 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c0a0cf15845787f05ec6bc30f06084c4", + "content-hash": "8c1f82c00b53093f703e7cecd4e9895c", "packages": [ { "name": "automattic/jetpack-autoloader", - "version": "v1.7.0", + "version": "v2.0.2", "source": { "type": "git", "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "7c6736eeee0f9fc49fa691fe3e958725efb27ca0" + "reference": "4502da4b2443fc1b61389cacc94c34876aca2b3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/7c6736eeee0f9fc49fa691fe3e958725efb27ca0", - "reference": "7c6736eeee0f9fc49fa691fe3e958725efb27ca0", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/4502da4b2443fc1b61389cacc94c34876aca2b3d", + "reference": "4502da4b2443fc1b61389cacc94c34876aca2b3d", "shasum": "" }, "require": { - "composer-plugin-api": "^1.1" + "composer-plugin-api": "^1.1 || ^2.0" }, "require-dev": { "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5" @@ -40,7 +40,7 @@ "GPL-2.0-or-later" ], "description": "Creates a custom autoloader for a plugin or theme.", - "time": "2020-04-23T02:28:37+00:00" + "time": "2020-07-09T13:18:38+00:00" }, { "name": "automattic/jetpack-constants", @@ -554,20 +554,20 @@ }, { "name": "woocommerce/woocommerce-admin", - "version": "v1.3.1", + "version": "v1.4.0-beta.1", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-admin.git", - "reference": "337036202a29078aed827f8e5dec566a9c57929a" + "reference": "9fb6f4167020e1b45c57040b782797a7055a0e95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/337036202a29078aed827f8e5dec566a9c57929a", - "reference": "337036202a29078aed827f8e5dec566a9c57929a", + "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/9fb6f4167020e1b45c57040b782797a7055a0e95", + "reference": "9fb6f4167020e1b45c57040b782797a7055a0e95", "shasum": "" }, "require": { - "automattic/jetpack-autoloader": "^1.6.0", + "automattic/jetpack-autoloader": "^2.0.0", "composer/installers": "1.7.0", "php": ">=5.6|>=7.0" }, @@ -597,24 +597,24 @@ ], "description": "A modern, javascript-driven WooCommerce Admin experience.", "homepage": "https://github.com/woocommerce/woocommerce-admin", - "time": "2020-07-20T22:33:15+00:00" + "time": "2020-07-22T01:44:35+00:00" }, { "name": "woocommerce/woocommerce-blocks", - "version": "v2.7.1", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git", - "reference": "0025c5cda83892c6f566fffd05197006f230d16c" + "reference": "cc00da60f21a7219e7e5ef5599996c68fee7b2be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/0025c5cda83892c6f566fffd05197006f230d16c", - "reference": "0025c5cda83892c6f566fffd05197006f230d16c", + "url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/cc00da60f21a7219e7e5ef5599996c68fee7b2be", + "reference": "cc00da60f21a7219e7e5ef5599996c68fee7b2be", "shasum": "" }, "require": { - "automattic/jetpack-autoloader": "^1.6.0", + "automattic/jetpack-autoloader": "^2.0.0", "composer/installers": "1.7.0" }, "require-dev": { @@ -644,24 +644,24 @@ "gutenberg", "woocommerce" ], - "time": "2020-06-16T13:34:29+00:00" + "time": "2020-07-22T13:34:19+00:00" }, { "name": "woocommerce/woocommerce-rest-api", - "version": "1.0.10", + "version": "1.0.11", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-rest-api.git", - "reference": "fdcb116b4f5b699b942c01b46fd863c7da8b4b7c" + "reference": "304bb95cb4b95f182f09d56153d5ac254d5fe60a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-rest-api/zipball/fdcb116b4f5b699b942c01b46fd863c7da8b4b7c", - "reference": "fdcb116b4f5b699b942c01b46fd863c7da8b4b7c", + "url": "https://api.github.com/repos/woocommerce/woocommerce-rest-api/zipball/304bb95cb4b95f182f09d56153d5ac254d5fe60a", + "reference": "304bb95cb4b95f182f09d56153d5ac254d5fe60a", "shasum": "" }, "require": { - "automattic/jetpack-autoloader": "^1.2.0" + "automattic/jetpack-autoloader": "^2.0.0" }, "require-dev": { "phpunit/phpunit": "6.5.14", @@ -684,7 +684,7 @@ ], "description": "The WooCommerce core REST API.", "homepage": "https://github.com/woocommerce/woocommerce-rest-api", - "time": "2020-06-16T09:51:51+00:00" + "time": "2020-07-24T13:38:16+00:00" } ], "packages-dev": [ From 5afab2b03d809f46b508f87c09aff7f339b607b2 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Fri, 24 Jul 2020 12:42:51 -0700 Subject: [PATCH 323/440] Removed the temporary PSR-4 autoloader This was added to get around a limitation in the Jetpack Autoloader 1.x branch. Since dependencies could not be used before `plugins_loaded` without throwing a notice we needed a custom autoloader to run before it in order to prevent the notice from showing. --- src/Autoloader.php | 60 ---------------------------------------------- 1 file changed, 60 deletions(-) diff --git a/src/Autoloader.php b/src/Autoloader.php index 0da9ea83d86..f2da75ee72b 100644 --- a/src/Autoloader.php +++ b/src/Autoloader.php @@ -21,33 +21,6 @@ class Autoloader { */ private function __construct() {} - /** - * These namespaces are autoloaded by our temporary PSR-4 autoloader. This enables us to bypass the limitations - * imposed by the 1.x branch of the Jetpack Autoloader until the 2.x branch is in-use. - * - * Note: Due to the way we load the files you must place more specific namespaces first or they won't be used! - * - * @var string[] - */ - private static $autoloaded_namespaces = array( - 'Psr\\Container\\' => __DIR__ . '/../vendor/psr/container/src/', - 'League\\Container\\' => __DIR__ . '/../vendor/league/container/src/', - 'Automattic\\WooCommerce\\Tests\\' => __DIR__ . '/../tests/php/src/', - 'Automattic\\WooCommerce\\Testing\\Tools' => __DIR__ . '/../tests/Tools/', - 'Automattic\\WooCommerce\\' => __DIR__ . '/', - ); - - /** - * These namespaces are excluded from being autoloaded by our temporary PSR-4 autoloader. - * - * @var string[] - */ - private static $excluded_namespaces = array( - 'Automattic\\WooCommerce\\Admin\\', - 'Automattic\\WooCommerce\\Blocks\\', - 'Automattic\\WooCommerce\\RestApi\\', - ); - /** * Require the autoloader and return the result. * @@ -63,8 +36,6 @@ class Autoloader { return false; } - self::register_psr4_autoloader(); - $autoloader_result = require $autoloader; if ( ! $autoloader_result ) { return false; @@ -73,37 +44,6 @@ class Autoloader { return $autoloader_result; } - /** - * Define a PSR-4 autoloader to load any desired classes before the Jetpack Autoloader to avoid triggering its - * error messages. - * - * TODO: Remove after the JetPack Autoloader dependency has been updated to v2. - */ - protected static function register_psr4_autoloader() { - spl_autoload_register( - function ( $class ) { - foreach ( self::$excluded_namespaces as $namespace ) { - if ( substr( $class, 0, strlen( $namespace ) ) === $namespace ) { - return; - } - } - - foreach ( self::$autoloaded_namespaces as $namespace => $directory ) { - $len = strlen( $namespace ); - if ( substr( $class, 0, $len ) === $namespace ) { - $filename = $directory . str_replace( '\\', '/', substr( $class, $len ) ) . '.php'; - if ( file_exists( $filename ) ) { - require $filename; - } - return; - } - } - }, - true, - true - ); - } - /** * If the autoloader is missing, add an admin notice. */ From 08575b16617a171bdd968b18eda5efc67666d405 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Fri, 24 Jul 2020 13:15:13 -0700 Subject: [PATCH 324/440] Added JETPACK_AUTOLOAD_DEV flag to autoloader Since Composer assigns dev versions to locally checked out repositories (most of the time) we need to set this flag. If we don't tell the autoloader we want to use dev versions then it will always prioritize the package classes over the plugin classes. --- src/Autoloader.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Autoloader.php b/src/Autoloader.php index f2da75ee72b..b67eafa4f76 100644 --- a/src/Autoloader.php +++ b/src/Autoloader.php @@ -36,6 +36,20 @@ class Autoloader { return false; } + /** + * In order to support local development for feature plugins the autoloader must support dev versions. + * + * - If the checked out branch cannot supply Composer with version information then it + * assigns it a dev version string for the Jetpack Autoloader to use. + * - By default the Jetpack Autoloader will ignore these dev versions in favor of tagged versions. + * + * Due to this interaction, feature plugin files from the included packages will always be loaded instead + * of the versions in the feature plugin when checked out from a repository as a dev version. By setting + * this constant we change the behavior of the autoloader so that dev versions are prioritized over the + * tagged versions included in WooCommerce Core. + */ + define( 'JETPACK_AUTOLOAD_DEV', true ); + $autoloader_result = require $autoloader; if ( ! $autoloader_result ) { return false; From 4123d048e0594fedf2663efbfff5ef93e9830847 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Mon, 27 Jul 2020 07:08:54 -0700 Subject: [PATCH 325/440] Fixed the number of industries in the onboarding E2E test --- tests/e2e/utils/components.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/utils/components.js b/tests/e2e/utils/components.js index 37b0e99e080..490d6b5f716 100644 --- a/tests/e2e/utils/components.js +++ b/tests/e2e/utils/components.js @@ -88,10 +88,10 @@ const completeOnboardingWizard = async () => { // Query for the industries checkboxes const industryCheckboxes = await page.$$( '.components-checkbox-control__input' ); - expect( industryCheckboxes ).toHaveLength( 8 ); + expect( industryCheckboxes ).toHaveLength( 10 ); // Select all industries including "Other" - for ( let i = 0; i < 8; i++ ) { + for ( let i = 0; i < 10; i++ ) { await industryCheckboxes[i].click(); } From cc118c0c1017bdf1b29562f8f1c9a8459fb5e641 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Mon, 27 Jul 2020 16:49:32 +0200 Subject: [PATCH 326/440] Fixed the number of product types in the onboarding E2E test --- tests/e2e/utils/components.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/utils/components.js b/tests/e2e/utils/components.js index 490d6b5f716..d7f22be041f 100644 --- a/tests/e2e/utils/components.js +++ b/tests/e2e/utils/components.js @@ -113,7 +113,7 @@ const completeOnboardingWizard = async () => { // Query for the product types checkboxes const productTypesCheckboxes = await page.$$( '.components-checkbox-control__input' ); - expect( productTypesCheckboxes ).toHaveLength( 6 ); + expect( productTypesCheckboxes ).toHaveLength( 8 ); // Select Physical and Downloadable products for ( let i = 0; i < 2; i++ ) { From d073b9d1e3ffe75100bc7c48d039680088194fee Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 16:42:00 -0300 Subject: [PATCH 327/440] Always run wp_filter_kses() on coupon codes. By default it only get sanitized when editing the coupon with an user that doesn't have unfiltered_html capability. --- includes/class-wc-post-data.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/class-wc-post-data.php b/includes/class-wc-post-data.php index cffabae2f38..6c0b7e31505 100644 --- a/includes/class-wc-post-data.php +++ b/includes/class-wc-post-data.php @@ -255,6 +255,9 @@ class WC_Post_Data { } } elseif ( 'product' === $data['post_type'] && 'auto-draft' === $data['post_status'] ) { $data['post_title'] = 'AUTO-DRAFT'; + } elseif ( 'shop_coupon' === $data['post_type'] ) { + // Coupons should never allow unfiltered HTML. + $data['post_title'] = wp_filter_kses( $data['post_title'] ); } return $data; From 42321924f0d08e65e685ff3e1a1c151a142d948d Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 16:44:47 -0300 Subject: [PATCH 328/440] Update the coupon code sanitization This makes match with WP sanitization for post_title. WP sanitize post_title using kses_init_filters() when the current user can't use unfiltered HTML. --- includes/wc-formatting-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/wc-formatting-functions.php b/includes/wc-formatting-functions.php index fc1064a2ebf..8a189d9cf5f 100644 --- a/includes/wc-formatting-functions.php +++ b/includes/wc-formatting-functions.php @@ -375,7 +375,7 @@ function wc_format_coupon_code( $value ) { * @return string */ function wc_sanitize_coupon_code( $value ) { - return sanitize_post_field( 'post_title', $value, 0, 'db' ); + return wp_filter_kses( sanitize_post_field( 'post_title', $value, 0, 'db' ) ); } /** From 6ee47b0356f72b35c94ad72d108810c0db2f5de3 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 16:48:15 -0300 Subject: [PATCH 329/440] Prevent breakage if coupons code get updated while there's some cart sessions --- includes/class-wc-cart.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index 3b086137acd..6069029583a 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -1691,7 +1691,7 @@ class WC_Cart extends WC_Legacy_Cart { */ public function remove_coupon( $coupon_code ) { $coupon_code = wc_format_coupon_code( $coupon_code ); - $position = array_search( $coupon_code, $this->get_applied_coupons(), true ); + $position = array_search( $coupon_code, array_map( 'wc_format_coupon_code', $this->get_applied_coupons() ), true ); if ( false !== $position ) { unset( $this->applied_coupons[ $position ] ); From d8edcb45511a5d3569dd243442a970619f95aa19 Mon Sep 17 00:00:00 2001 From: Ron Rennick Date: Mon, 27 Jul 2020 16:48:39 -0300 Subject: [PATCH 330/440] update from review feedback --- includes/admin/class-wc-admin-post-types.php | 2 +- includes/admin/views/html-admin-settings.php | 2 +- includes/class-wc-order-item-meta.php | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/includes/admin/class-wc-admin-post-types.php b/includes/admin/class-wc-admin-post-types.php index 00e891c1c2c..8746ab5d134 100644 --- a/includes/admin/class-wc-admin-post-types.php +++ b/includes/admin/class-wc-admin-post-types.php @@ -895,7 +895,7 @@ class WC_Admin_Post_Types { * @deprecated 3.3.0 and moved to post-data class. */ public function process_product_file_download_paths( $product_id, $variation_id, $downloadable_files ) { - wc_deprecated_function( 'WC_Admin_Post_Types::process_product_file_download_paths', '3.3', 'WC_Post_Data::process_product_file_download_paths' ); + wc_deprecated_function( 'WC_Admin_Post_Types::process_product_file_download_paths', '3.3', '' ); WC_Post_Data::process_product_file_download_paths( $product_id, $variation_id, $downloadable_files ); } diff --git a/includes/admin/views/html-admin-settings.php b/includes/admin/views/html-admin-settings.php index 823726b1444..ff854fe5718 100644 --- a/includes/admin/views/html-admin-settings.php +++ b/includes/admin/views/html-admin-settings.php @@ -38,7 +38,7 @@ if ( ! $tab_exists ) { self::show_messages(); do_action( 'woocommerce_settings_' . $current_tab ); - do_action( 'woocommerce_settings_tabs_' . $current_tab ); // @deprecated 3.4.0 hook. @todo remove in 4.6.0. + do_action( 'woocommerce_settings_tabs_' . $current_tab ); // @deprecated 3.4.0 hook. ?>

diff --git a/includes/class-wc-order-item-meta.php b/includes/class-wc-order-item-meta.php index a00fb5d9e6d..2d2f72f03f9 100644 --- a/includes/class-wc-order-item-meta.php +++ b/includes/class-wc-order-item-meta.php @@ -163,13 +163,11 @@ class WC_Order_Item_Meta { * Return an array of formatted item meta in format e.g. * Handles @deprecated args. * - * @deprecated 4.4.0 * @param string $hideprefix Hide prefix. * * @return array */ public function get_formatted_legacy( $hideprefix = '_' ) { - wc_deprecated_function( 'WC_Order_Item_Product::get_formatted_legacy', '4.4.0', '' ); if ( ! is_ajax() ) { wc_deprecated_argument( 'WC_Order_Item_Meta::get_formatted', '2.4', 'Item Meta Data is being called with legacy arguments' ); } From be106af910b9d8043c99521772ff09c0ee4f7b9a Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 16:50:23 -0300 Subject: [PATCH 331/440] Added upgrade routine to sanitize all coupon codes --- includes/class-wc-install.php | 4 ++++ includes/wc-update-functions.php | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index e6b2d9e1379..baabd8807c5 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -149,6 +149,10 @@ class WC_Install { 'wc_update_400_reset_action_scheduler_migration_status', 'wc_update_400_db_version', ), + '4.5.0' => array( + 'wc_update_450_sanitize_coupons_code', + 'wc_update_450_db_version', + ), ); /** diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index ac02393eade..84d08bc5295 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2110,3 +2110,35 @@ function wc_update_400_reset_action_scheduler_migration_status() { function wc_update_400_db_version() { WC_Install::update_db_version( '4.0.0' ); } + +/** + * Update DB version to 4.5.0. + */ +function wc_update_450_db_version() { + WC_Install::update_db_version( '4.5.0' ); +} + +/** + * Sanitize all coupons code. + */ +function wc_update_450_sanitize_coupons_code() { + global $wpdb; + + $coupons = $wpdb->get_results( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_type = 'shop_coupon';" ); + + if ( $coupons ) { + foreach ( $coupons as $data ) { + $code = trim( wp_filter_kses( $data->post_title ) ); + + if ( ! empty( $code ) ) { + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->posts} SET post_title = %s WHERE ID = %d", + $code, + $data->ID + ) + ); + } + } + } +} From 3f784fd17f5c45e7716a5a8f1aa92be9886c4ee2 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 27 Jul 2020 20:20:12 +0000 Subject: [PATCH 332/440] Update dependency eslint-plugin-jest to v23.19.0 --- package-lock.json | 48 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7c7e3544f6..fa0fad07d0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7663,9 +7663,9 @@ } }, "@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", "dev": true }, "@types/mime-types": { @@ -7764,21 +7764,21 @@ "dev": true }, "@typescript-eslint/experimental-utils": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.26.0.tgz", - "integrity": "sha512-RELVoH5EYd+JlGprEyojUv9HeKcZqF7nZUGSblyAw1FwOGNnmQIU8kxJ69fttQvEwCsX5D6ECJT8GTozxrDKVQ==", + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.26.0", + "@typescript-eslint/typescript-estree": "2.34.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" }, "dependencies": { "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -7787,9 +7787,9 @@ } }, "@typescript-eslint/typescript-estree": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.26.0.tgz", - "integrity": "sha512-3x4SyZCLB4zsKsjuhxDLeVJN6W29VwBnYpCsZ7vIdPel9ZqLfIZJgJXO47MNUkurGpQuIBALdPQKtsSnWpE1Yg==", + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", "dev": true, "requires": { "debug": "^4.1.1", @@ -7797,7 +7797,7 @@ "glob": "^7.1.6", "is-glob": "^4.0.1", "lodash": "^4.17.15", - "semver": "^6.3.0", + "semver": "^7.3.2", "tsutils": "^3.17.1" }, "dependencies": { @@ -7825,9 +7825,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "ms": { @@ -7837,9 +7837,9 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true } } @@ -8025,7 +8025,7 @@ "dev": true, "requires": { "@wordpress/e2e-test-utils": "^4.6.0", - "@wordpress/jest-preset-default": "^5.4.0", + "@wordpress/jest-preset-default": "^6.2.0", "app-root-path": "^3.0.0", "jest": "^25.1.0", "jest-puppeteer": "^4.4.0", @@ -14328,9 +14328,9 @@ } }, "eslint-plugin-jest": { - "version": "23.8.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz", - "integrity": "sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg==", + "version": "23.19.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.19.0.tgz", + "integrity": "sha512-l5PLflALqnODl8Yy0H5hDs18aKJS1KTf66VZGXRpIhmbLbPLaTuMB2P+65fBpkdseSpnTVcIlBYvTvJSBi/itg==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "^2.5.0" diff --git a/package.json b/package.json index fbfb1e4cc13..ee6f28d1548 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "deasync": "0.1.20", "eslint": "6.8.0", "eslint-config-wpcalypso": "5.0.0", - "eslint-plugin-jest": "23.8.2", + "eslint-plugin-jest": "23.19.0", "github-contributors-list": "https://github.com/woocommerce/github-contributors-list/tarball/master", "grunt": "1.1.0", "grunt-contrib-clean": "2.0.0", From ddc1f87f8d5b3d419f7e3a84519a8366c944800b Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Mon, 27 Jul 2020 13:30:39 -0700 Subject: [PATCH 333/440] Update README.md Changed `npm install` suggestion to better suggest saving the dependencies as devDependencies --- tests/e2e/factories/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/factories/README.md b/tests/e2e/factories/README.md index 664feb91a9d..fd1498a8cd4 100644 --- a/tests/e2e/factories/README.md +++ b/tests/e2e/factories/README.md @@ -5,7 +5,7 @@ A simple interface for generating models of different types. ## Installation ``bash -npm install @woocommerce/model-factories --save +npm install @woocommerce/model-factories --save-dev `` ## Usage From e94196cea86a51e1a3311a27e0aaa926b4fbbf64 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 17:33:15 -0300 Subject: [PATCH 334/440] Sanitize coupon code in coupon ID by code functions --- includes/data-stores/class-wc-coupon-data-store-cpt.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/data-stores/class-wc-coupon-data-store-cpt.php b/includes/data-stores/class-wc-coupon-data-store-cpt.php index dab16bfc1b9..68f0c1671f5 100644 --- a/includes/data-stores/class-wc-coupon-data-store-cpt.php +++ b/includes/data-stores/class-wc-coupon-data-store-cpt.php @@ -721,7 +721,7 @@ class WC_Coupon_Data_Store_CPT extends WC_Data_Store_WP implements WC_Coupon_Dat return $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_date DESC", - $code + wc_sanitize_coupon_code( $code ) ) ); } From 4048d19a399bcacd57738bbabf8d29032190fb8c Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 17:44:04 -0300 Subject: [PATCH 335/440] Added unit tests for coupon code sanitization --- .../framework/class-wc-unit-test-case.php | 4 +-- .../php/includes/class-wc-post-data-test.php | 35 +++++++++++++++++++ .../includes/wc-formatting-functions-test.php | 20 +++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 tests/php/includes/class-wc-post-data-test.php create mode 100644 tests/php/includes/wc-formatting-functions-test.php diff --git a/tests/legacy/framework/class-wc-unit-test-case.php b/tests/legacy/framework/class-wc-unit-test-case.php index d13e4d1fdbc..74289f2b413 100644 --- a/tests/legacy/framework/class-wc-unit-test-case.php +++ b/tests/legacy/framework/class-wc-unit-test-case.php @@ -171,9 +171,9 @@ class WC_Unit_Test_Case extends WP_HTTP_TestCase { */ public function login_as_administrator() { return $this->login_as_role( 'administrator' ); - } + } - /** + /** * Get an instance of a class that has been registered in the dependency injection container. * To get an instance of a legacy class (such as the ones in the 'íncludes' directory) use * 'get_legacy_instance_of' instead. diff --git a/tests/php/includes/class-wc-post-data-test.php b/tests/php/includes/class-wc-post-data-test.php new file mode 100644 index 00000000000..3d3f7914325 --- /dev/null +++ b/tests/php/includes/class-wc-post-data-test.php @@ -0,0 +1,35 @@ +login_as_role( 'shop_manager' ); + $coupon = WC_Helper_Coupon::create_coupon( 'a&a' ); + $post_data = get_post( $coupon->get_id() ); + $this->assertEquals( 'a&a', $post_data->post_title ); + $coupon->delete( true ); + + $this->login_as_administrator(); + $coupon = WC_Helper_Coupon::create_coupon( 'b&b' ); + $post_data = get_post( $coupon->get_id() ); + $this->assertEquals( 'b&b', $post_data->post_title ); + $coupon->delete( true ); + + wp_set_current_user( 0 ); + $coupon = WC_Helper_Coupon::create_coupon( 'c&c' ); + $post_data = get_post( $coupon->get_id() ); + $this->assertEquals( 'c&c', $post_data->post_title ); + $coupon->delete( true ); + } +} diff --git a/tests/php/includes/wc-formatting-functions-test.php b/tests/php/includes/wc-formatting-functions-test.php new file mode 100644 index 00000000000..93dfda3b314 --- /dev/null +++ b/tests/php/includes/wc-formatting-functions-test.php @@ -0,0 +1,20 @@ +assertEquals( 'DUMMYCOUPON', wc_sanitize_coupon_code( 'DUMMYCOUPON' ) ); + $this->assertEquals( 'a&a', wc_sanitize_coupon_code( 'a&a' ) ); + } +} From edf1932ee980badde122a8870e796f40d0268a7d Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Mon, 27 Jul 2020 14:38:43 -0700 Subject: [PATCH 336/440] Adjusted the OBW test for changes in WC-Admin 1.4.0 --- tests/e2e/utils/components.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/e2e/utils/components.js b/tests/e2e/utils/components.js index d7f22be041f..0e6e721c4b0 100644 --- a/tests/e2e/utils/components.js +++ b/tests/e2e/utils/components.js @@ -139,22 +139,17 @@ const completeOnboardingWizard = async () => { // Fill the number of products you plan to sell await selectControls[0].click(); - await page.waitForSelector( '.woocommerce-select-control__listbox' ); + await page.waitForSelector( '.woocommerce-select-control__control' ); await expect( page ).toClick( '.woocommerce-select-control__option', { text: config.get( 'onboardingwizard.numberofproducts' ) } ); // Fill currently selling elsewhere await selectControls[1].click(); - await page.waitForSelector( '.woocommerce-select-control__listbox' ); + await page.waitForSelector( '.woocommerce-select-control__control' ); await expect( page ).toClick( '.woocommerce-select-control__option', { text: config.get( 'onboardingwizard.sellingelsewhere' ) } ); - // Query for the plugin upload toggles - const pluginToggles = await page.$$( '.components-form-toggle__input' ); - expect( pluginToggles ).toHaveLength( 3 ); - - // Disable Market on Facebook, Mailchimp and Google Shopping download - for ( let i = 0; i < 3; i++ ) { - await pluginToggles[i].click(); - } + // Disable business extension downloads + const pluginToggle = await page.$( '.woocommerce-business-extensions .components-checkbox-control__input-container' ); + pluginToggle.click(); // Wait for "Continue" button to become active await page.waitForSelector( 'button.is-primary:not(:disabled)' ); From 1868cd8aaa100ff8b3050b16965ee2ce6d90f2e2 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Mon, 27 Jul 2020 15:18:27 -0700 Subject: [PATCH 337/440] Adjusting the shipping task order in the E2E test for setup tasks --- tests/e2e/specs/activate-and-setup/setup-wizard.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/specs/activate-and-setup/setup-wizard.test.js b/tests/e2e/specs/activate-and-setup/setup-wizard.test.js index 1a543f7ec1c..cf1f88531e7 100644 --- a/tests/e2e/specs/activate-and-setup/setup-wizard.test.js +++ b/tests/e2e/specs/activate-and-setup/setup-wizard.test.js @@ -60,7 +60,7 @@ describe( 'Store owner can go through setup Task List', () => { await Promise.all( [ // Click on "Set up shipping" task to move to the next step - taskListItems[3].click(), + taskListItems[4].click(), // Wait for shipping setup section to load page.waitForNavigation( { waitUntil: 'networkidle0' } ), From 4f90307e2ebda287b32a9eb4830430bd2d341801 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 20:18:33 -0300 Subject: [PATCH 338/440] Fixed "Paid By Customer" data when the orders contains refunds --- includes/admin/meta-boxes/views/html-order-items.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/includes/admin/meta-boxes/views/html-order-items.php b/includes/admin/meta-boxes/views/html-order-items.php index 2981b467db4..554eca52ef9 100644 --- a/includes/admin/meta-boxes/views/html-order-items.php +++ b/includes/admin/meta-boxes/views/html-order-items.php @@ -216,7 +216,14 @@ if ( wc_tax_enabled() ) { : - get_total(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?> + get_total(); + if ( $order->get_total_refunded() ) { + $total_paid_by_customer -= $order->get_total_refunded(); + } + + echo wc_price( $total_paid_by_customer, array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> From 134ab5c184c2aac18658fe895da36cc64779d6cd Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 20:21:41 -0300 Subject: [PATCH 339/440] Fixed coding standards --- .../meta-boxes/views/html-order-items.php | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/includes/admin/meta-boxes/views/html-order-items.php b/includes/admin/meta-boxes/views/html-order-items.php index 554eca52ef9..d35c4d966c4 100644 --- a/includes/admin/meta-boxes/views/html-order-items.php +++ b/includes/admin/meta-boxes/views/html-order-items.php @@ -147,7 +147,7 @@ if ( wc_tax_enabled() ) { - get_subtotal(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?> + get_subtotal(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> get_total_discount() ) : ?> @@ -155,7 +155,7 @@ if ( wc_tax_enabled() ) { - - get_total_discount(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?> + get_total_discount(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> @@ -164,7 +164,7 @@ if ( wc_tax_enabled() ) { - get_total_fees(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?> + get_total_fees(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> @@ -176,7 +176,7 @@ if ( wc_tax_enabled() ) { - get_shipping_total(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?> + get_shipping_total(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> @@ -189,7 +189,7 @@ if ( wc_tax_enabled() ) { label ); ?>: - amount, array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?> + amount, array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> @@ -201,7 +201,7 @@ if ( wc_tax_enabled() ) { : - get_total(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?> + get_total(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> @@ -209,7 +209,7 @@ if ( wc_tax_enabled() ) {

- get_status(), array( 'processing', 'completed', 'refunded' ) ) && ! empty( $order->get_date_paid() ) ) : ?> + get_status(), array( 'processing', 'completed', 'refunded' ), true ) && ! empty( $order->get_date_paid() ) ) : ?> @@ -237,7 +237,7 @@ if ( wc_tax_enabled() ) { - + get_id() ); ?> @@ -246,7 +246,7 @@ if ( wc_tax_enabled() ) { @@ -308,11 +308,11 @@ if ( wc_tax_enabled() ) { - + - + - +
: -get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>-get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
: - get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?> + get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
:-get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>-get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
:get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
@@ -393,7 +393,7 @@ if ( wc_tax_enabled() ) { ?>
@@ -433,18 +433,17 @@ if ( wc_tax_enabled() ) { get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates ORDER BY tax_rate_name LIMIT 100" ); - + $rates = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates ORDER BY tax_rate_name LIMIT 100" ); foreach ( $rates as $rate ) { echo ' - - ' . ( isset( $classes_options[ $rate->tax_rate_class ] ) ? $classes_options[ $rate->tax_rate_class ] : '-' ) . ' - ' . WC_Tax::get_rate_code( $rate ) . ' - ' . WC_Tax::get_rate_percent( $rate ) . ' + + ' . ( isset( $classes_options[ $rate->tax_rate_class ] ) ? esc_html( $classes_options[ $rate->tax_rate_class ] ) : '-' ) . ' + ' . esc_html( WC_Tax::get_rate_code( $rate ) ) . ' + ' . esc_html( WC_Tax::get_rate_percent( $rate ) ) . ' - '; // WPCS: XSS ok. + '; } ?> From 08620cf8466054263d6975fb749c6b454d9dee34 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 21:49:33 -0300 Subject: [PATCH 340/440] Make "woocommerce_shipping_cost_requires_address" strict --- includes/class-wc-cart.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index 3b086137acd..eb546b925ee 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -1396,10 +1396,8 @@ class WC_Cart extends WC_Legacy_Cart { } if ( 'yes' === get_option( 'woocommerce_shipping_cost_requires_address' ) ) { - if ( ! $this->get_customer()->has_calculated_shipping() ) { - if ( ! $this->get_customer()->get_shipping_country() || ( ! $this->get_customer()->get_shipping_state() && ! $this->get_customer()->get_shipping_postcode() ) ) { - return false; - } + if ( ! $this->get_customer()->get_shipping_country() || ! $this->get_customer()->get_shipping_state() || ! $this->get_customer()->get_shipping_postcode() ) { + return false; } } From 0f091406df23bf7e7ba97e35b29e7b5f3a7961fa Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 21:52:33 -0300 Subject: [PATCH 341/440] Test WC_Cart::show_shipping() --- tests/php/includes/class-wc-cart-test.php | 59 +++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tests/php/includes/class-wc-cart-test.php diff --git a/tests/php/includes/class-wc-cart-test.php b/tests/php/includes/class-wc-cart-test.php new file mode 100644 index 00000000000..081b6aa3c54 --- /dev/null +++ b/tests/php/includes/class-wc-cart-test.php @@ -0,0 +1,59 @@ +cart->empty_cart(); + WC()->customer->set_is_vat_exempt( false ); + WC()->session->set( 'wc_notices', null ); + } + + /** + * Test show shipping. + */ + public function test_show_shipping() { + // Test with an empty cart. + $this->assertFalse( WC()->cart->show_shipping() ); + + // Add a product to the cart. + $product = WC_Helper_Product::create_simple_product(); + WC()->cart->add_to_cart( $product->get_id(), 1 ); + + // Test with "woocommerce_ship_to_countries" disabled. + $default_ship_to_countries = get_option( 'woocommerce_ship_to_countries', '' ); + update_option( 'woocommerce_ship_to_countries', 'disabled' ); + $this->assertFalse( WC()->cart->show_shipping() ); + + // Test with default "woocommerce_ship_to_countries" and "woocommerce_shipping_cost_requires_address". + update_option( 'woocommerce_ship_to_countries', $default_ship_to_countries ); + $this->assertTrue( WC()->cart->show_shipping() ); + + // Test with "woocommerce_shipping_cost_requires_address" enabled. + $default_shipping_cost_requires_address = get_option( 'woocommerce_shipping_cost_requires_address', 'no' ); + update_option( 'woocommerce_shipping_cost_requires_address', 'yes' ); + $this->assertFalse( WC()->cart->show_shipping() ); + + // Set address for shipping calculation required for "woocommerce_shipping_cost_requires_address". + WC()->cart->get_customer()->set_shipping_country( 'US' ); + WC()->cart->get_customer()->set_shipping_state( 'NY' ); + WC()->cart->get_customer()->set_shipping_postcode( '12345' ); + $this->assertTrue( WC()->cart->show_shipping() ); + + // Reset. + update_option( 'woocommerce_shipping_cost_requires_address', $default_shipping_cost_requires_address ); + $product->delete( true ); + } +} From de383971eb5b91fa433ecb6df54f7bb3cfbafe30 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 27 Jul 2020 22:07:46 -0300 Subject: [PATCH 342/440] Reset all after test --- tests/php/includes/class-wc-cart-test.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/php/includes/class-wc-cart-test.php b/tests/php/includes/class-wc-cart-test.php index 081b6aa3c54..466de397fa6 100644 --- a/tests/php/includes/class-wc-cart-test.php +++ b/tests/php/includes/class-wc-cart-test.php @@ -55,5 +55,8 @@ class WC_Cart_Test extends \WC_Unit_Test_Case { // Reset. update_option( 'woocommerce_shipping_cost_requires_address', $default_shipping_cost_requires_address ); $product->delete( true ); + WC()->cart->get_customer()->set_shipping_country( 'GB' ); + WC()->cart->get_customer()->set_shipping_state( '' ); + WC()->cart->get_customer()->set_shipping_postcode( '' ); } } From c27283dffe2383b6e1607dc10062001e15307caf Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 21 Apr 2020 15:52:40 +0200 Subject: [PATCH 343/440] Fix code sniffer errors in some files. Fixed files: includes/abstracts/abstract-wc-product.php includes/class-wc-query.php includes/wc-template-functions.php includes/widgets/class-wc-widget-layered-nav.php templates/loop/result-count.php tests/unit-tests/util/class-wc-tests-wc-query.php --- includes/abstracts/abstract-wc-product.php | 5 ++ includes/class-wc-query.php | 60 ++++++++----- includes/wc-template-functions.php | 84 +++++++++++++------ .../widgets/class-wc-widget-layered-nav.php | 8 +- templates/loop/result-count.php | 2 + .../util/class-wc-tests-wc-query.php | 9 ++ 6 files changed, 116 insertions(+), 52 deletions(-) diff --git a/includes/abstracts/abstract-wc-product.php b/includes/abstracts/abstract-wc-product.php index d7c04330b04..e8edd7aa055 100644 --- a/includes/abstracts/abstract-wc-product.php +++ b/includes/abstracts/abstract-wc-product.php @@ -1990,8 +1990,13 @@ class WC_Product extends WC_Abstract_Legacy_Product { public function get_price_suffix( $price = '', $qty = 1 ) { $html = ''; +<<<<<<< HEAD $suffix = get_option( 'woocommerce_price_display_suffix' ); if ( $suffix && wc_tax_enabled() && 'taxable' === $this->get_tax_status() ) { +======= + // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure, WordPress.CodeAnalysis.AssignmentInCondition.Found + if ( ( $suffix = get_option( 'woocommerce_price_display_suffix' ) ) && wc_tax_enabled() && 'taxable' === $this->get_tax_status() ) { +>>>>>>> cd077dfb6... Fix code sniffer errors in some files. if ( '' === $price ) { $price = $this->get_price(); } diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index bd026f46b26..e7ac1eeab77 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -32,7 +32,7 @@ class WC_Query { * * @var array */ - private static $_chosen_attributes; + private static $chosen_attributes; /** * Constructor for the query class. Hooks in methods. @@ -54,7 +54,8 @@ class WC_Query { * Get any errors from querystring. */ public function get_errors() { - $error = ! empty( $_GET['wc_error'] ) ? sanitize_text_field( wp_unslash( $_GET['wc_error'] ) ) : ''; // WPCS: input var ok, CSRF ok. + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $error = ! empty( $_GET['wc_error'] ) ? sanitize_text_field( wp_unslash( $_GET['wc_error'] ) ) : ''; if ( $error && ! wc_has_notice( $error, 'error' ) ) { wc_add_notice( $error, 'error' ); @@ -217,14 +218,16 @@ class WC_Query { public function parse_request() { global $wp; + // phpcs:disable WordPress.Security.NonceVerification.Recommended // Map query vars to their keys, or get them if endpoints are not supported. foreach ( $this->get_query_vars() as $key => $var ) { - if ( isset( $_GET[ $var ] ) ) { // WPCS: input var ok, CSRF ok. - $wp->query_vars[ $key ] = sanitize_text_field( wp_unslash( $_GET[ $var ] ) ); // WPCS: input var ok, CSRF ok. + if ( isset( $_GET[ $var ] ) ) { + $wp->query_vars[ $key ] = sanitize_text_field( wp_unslash( $_GET[ $var ] ) ); } elseif ( isset( $wp->query_vars[ $var ] ) ) { $wp->query_vars[ $key ] = $wp->query_vars[ $var ]; } } + // phpcs:enable WordPress.Security.NonceVerification.Recommended } /** @@ -447,7 +450,8 @@ class WC_Query { public function get_catalog_ordering_args( $orderby = '', $order = '' ) { // Get ordering from query string unless defined. if ( ! $orderby ) { - $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( (string) wp_unslash( $_GET['orderby'] ) ) : wc_clean( get_query_var( 'orderby' ) ); // WPCS: sanitization ok, input var ok, CSRF ok. + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( (string) wp_unslash( $_GET['orderby'] ) ) : wc_clean( get_query_var( 'orderby' ) ); if ( ! $orderby_value ) { if ( is_search() ) { @@ -522,12 +526,15 @@ class WC_Query { public function price_filter_post_clauses( $args, $wp_query ) { global $wpdb; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( ! $wp_query->is_main_query() || ( ! isset( $_GET['max_price'] ) && ! isset( $_GET['min_price'] ) ) ) { return $args; } - $current_min_price = isset( $_GET['min_price'] ) ? floatval( wp_unslash( $_GET['min_price'] ) ) : 0; // WPCS: input var ok, CSRF ok. - $current_max_price = isset( $_GET['max_price'] ) ? floatval( wp_unslash( $_GET['max_price'] ) ) : PHP_INT_MAX; // WPCS: input var ok, CSRF ok. + // phpcs:disable WordPress.Security.NonceVerification.Recommended + $current_min_price = isset( $_GET['min_price'] ) ? floatval( wp_unslash( $_GET['min_price'] ) ) : 0; + $current_max_price = isset( $_GET['max_price'] ) ? floatval( wp_unslash( $_GET['max_price'] ) ) : PHP_INT_MAX; + // phpcs:enable WordPress.Security.NonceVerification.Recommended /** * Adjust if the store taxes are not displayed how they are stored. @@ -666,9 +673,11 @@ class WC_Query { $product_visibility_not_in[] = $product_visibility_terms['outofstock']; } + // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash // Filter by rating. - if ( isset( $_GET['rating_filter'] ) ) { // WPCS: input var ok, CSRF ok. - $rating_filter = array_filter( array_map( 'absint', explode( ',', $_GET['rating_filter'] ) ) ); // WPCS: input var ok, CSRF ok, Sanitization ok. + if ( isset( $_GET['rating_filter'] ) ) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $rating_filter = array_filter( array_map( 'absint', explode( ',', $_GET['rating_filter'] ) ) ); $rating_terms = array(); for ( $i = 1; $i <= 5; $i ++ ) { if ( in_array( $i, $rating_filter, true ) && isset( $product_visibility_terms[ 'rated-' . $i ] ) ) { @@ -685,6 +694,7 @@ class WC_Query { ); } } + // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash if ( ! empty( $product_visibility_not_in ) ) { $tax_query[] = array( @@ -753,8 +763,9 @@ class WC_Query { $term = substr( $term, 1 ); } - $like = '%' . $wpdb->esc_like( $term ) . '%'; - $sql[] = $wpdb->prepare( "(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_excerpt $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like, $like ); // unprepared SQL ok. + $like = '%' . $wpdb->esc_like( $term ) . '%'; + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $sql[] = $wpdb->prepare( "(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_excerpt $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like, $like ); } if ( ! empty( $sql ) && ! is_user_logged_in() ) { @@ -770,11 +781,12 @@ class WC_Query { * @return array */ public static function get_layered_nav_chosen_attributes() { - if ( ! is_array( self::$_chosen_attributes ) ) { - self::$_chosen_attributes = array(); + // phpcs:disable WordPress.Security.NonceVerification.Recommended + if ( ! is_array( self::$chosen_attributes ) ) { + self::$chosen_attributes = array(); - if ( ! empty( $_GET ) ) { // WPCS: input var ok, CSRF ok. - foreach ( $_GET as $key => $value ) { // WPCS: input var ok, CSRF ok. + if ( ! empty( $_GET ) ) { + foreach ( $_GET as $key => $value ) { if ( 0 === strpos( $key, 'filter_' ) ) { $attribute = wc_sanitize_taxonomy_name( str_replace( 'filter_', '', $key ) ); $taxonomy = wc_attribute_taxonomy_name( $attribute ); @@ -784,14 +796,15 @@ class WC_Query { continue; } - $query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ), true ) ? wc_clean( wp_unslash( $_GET[ 'query_type_' . $attribute ] ) ) : ''; // WPCS: sanitization ok, input var ok, CSRF ok. - self::$_chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding. - self::$_chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' ); + $query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ), true ) ? wc_clean( wp_unslash( $_GET[ 'query_type_' . $attribute ] ) ) : ''; + self::$chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding. + self::$chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' ); } } } } - return self::$_chosen_attributes; + return self::$chosen_attributes; + // phpcs:disable WordPress.Security.NonceVerification.Recommended } /** @@ -804,7 +817,6 @@ class WC_Query { return remove_query_arg( 'add-to-cart', $url ); } - // @codingStandardsIgnoreStart /** * Return a meta query for filtering by rating. * @@ -819,7 +831,7 @@ class WC_Query { * Returns a meta query to handle product visibility. * * @deprecated 3.0.0 Replaced with taxonomy. - * @param string $compare (default: 'IN') + * @param string $compare (default: 'IN'). * @return array */ public function visibility_meta_query( $compare = 'IN' ) { @@ -830,7 +842,7 @@ class WC_Query { * Returns a meta query to handle product stock status. * * @deprecated 3.0.0 Replaced with taxonomy. - * @param string $status (default: 'instock') + * @param string $status (default: 'instock'). * @return array */ public function stock_status_meta_query( $status = 'instock' ) { @@ -869,6 +881,8 @@ class WC_Query { /** * Search post excerpt. * + * @param string $where Where clause. + * * @deprecated 3.2.0 - Not needed anymore since WordPress 4.5. */ public function search_post_excerpt( $where = '' ) { @@ -878,10 +892,10 @@ class WC_Query { /** * Remove the posts_where filter. + * * @deprecated 3.2.0 - Nothing to remove anymore because search_post_excerpt() is deprecated. */ public function remove_posts_where() { wc_deprecated_function( 'WC_Query::remove_posts_where', '3.2.0', 'Nothing to remove anymore because search_post_excerpt() is deprecated.' ); } - // @codingStandardsIgnoreEnd } diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 0ebcfb39d32..760b27fa53c 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -8,6 +8,8 @@ * @version 2.5.0 */ +// phpcs:disable Generic.Commenting.Todo.TaskFound + use Automattic\Jetpack\Constants; defined( 'ABSPATH' ) || exit; @@ -18,11 +20,13 @@ defined( 'ABSPATH' ) || exit; function wc_template_redirect() { global $wp_query, $wp; + // phpcs:disable WordPress.Security.NonceVerification.Recommended // When default permalinks are enabled, redirect shop page to post type archive url. - if ( ! empty( $_GET['page_id'] ) && '' === get_option( 'permalink_structure' ) && wc_get_page_id( 'shop' ) === absint( $_GET['page_id'] ) && get_post_type_archive_link( 'product' ) ) { // WPCS: input var ok, CSRF ok. + if ( ! empty( $_GET['page_id'] ) && '' === get_option( 'permalink_structure' ) && wc_get_page_id( 'shop' ) === absint( $_GET['page_id'] ) && get_post_type_archive_link( 'product' ) ) { wp_safe_redirect( get_post_type_archive_link( 'product' ) ); exit; } + // phpcs:enable WordPress.Security.NonceVerification.Recommended // When on the checkout with an empty cart, redirect to cart page. if ( is_page( wc_get_page_id( 'checkout' ) ) && wc_get_page_id( 'checkout' ) !== wc_get_page_id( 'cart' ) && WC()->cart->is_empty() && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) && ! is_customize_preview() && apply_filters( 'woocommerce_checkout_redirect_empty_cart', true ) ) { @@ -33,7 +37,7 @@ function wc_template_redirect() { } // Logout. - if ( isset( $wp->query_vars['customer-logout'] ) && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'customer-logout' ) ) { // WPCS: input var ok, CSRF ok. + if ( isset( $wp->query_vars['customer-logout'] ) && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'customer-logout' ) ) { wp_safe_redirect( str_replace( '&', '&', wp_logout_url( wc_get_page_permalink( 'myaccount' ) ) ) ); exit; } @@ -96,9 +100,11 @@ add_action( 'template_redirect', 'wc_send_frame_options_header' ); * @since 2.5.3 */ function wc_prevent_endpoint_indexing() { - if ( is_wc_endpoint_url() || isset( $_GET['download_file'] ) ) { // WPCS: input var ok, CSRF ok. - @header( 'X-Robots-Tag: noindex' ); // @codingStandardsIgnoreLine + // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.PHP.NoSilencedErrors.Discouraged + if ( is_wc_endpoint_url() || isset( $_GET['download_file'] ) ) { + @header( 'X-Robots-Tag: noindex' ); } + // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.PHP.NoSilencedErrors.Discouraged } add_action( 'template_redirect', 'wc_prevent_endpoint_indexing' ); @@ -704,7 +710,9 @@ function wc_product_class( $class = '', $product_id = null ) { */ function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '', $return = false ) { if ( is_null( $values ) ) { - $values = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended + // phpcs:disable WordPress.Security.NonceVerification.Recommended + $values = $_GET; + // phpcs:enable WordPress.Security.NonceVerification.Recommended } elseif ( is_string( $values ) ) { $url_parts = wp_parse_url( $values ); $values = array(); @@ -1022,7 +1030,8 @@ if ( ! function_exists( 'woocommerce_demo_store' ) ) { $notice_id = md5( $notice ); - echo apply_filters( 'woocommerce_demo_store', '
', $notice ); // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo apply_filters( 'woocommerce_demo_store', '', $notice ); } } @@ -1062,7 +1071,8 @@ if ( ! function_exists( 'woocommerce_page_title' ) ) { $page_title = apply_filters( 'woocommerce_page_title', $page_title ); if ( $echo ) { - echo $page_title; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $page_title; } else { return $page_title; } @@ -1087,7 +1097,8 @@ if ( ! function_exists( 'woocommerce_product_loop_start' ) ) { $loop_start = apply_filters( 'woocommerce_product_loop_start', ob_get_clean() ); if ( $echo ) { - echo $loop_start; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $loop_start; } else { return $loop_start; } @@ -1110,7 +1121,8 @@ if ( ! function_exists( 'woocommerce_product_loop_end' ) ) { $loop_end = apply_filters( 'woocommerce_product_loop_end', ob_get_clean() ); if ( $echo ) { - echo $loop_end; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $loop_end; } else { return $loop_end; } @@ -1139,7 +1151,8 @@ if ( ! function_exists( 'woocommerce_template_loop_category_title' ) ) { echo esc_html( $category->name ); if ( $category->count > 0 ) { - echo apply_filters( 'woocommerce_subcategory_count_html', ' (' . esc_html( $category->count ) . ')', $category ); // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo apply_filters( 'woocommerce_subcategory_count_html', ' (' . esc_html( $category->count ) . ')', $category ); } ?> @@ -1199,7 +1212,8 @@ if ( ! function_exists( 'woocommerce_taxonomy_archive_description' ) ) { $term = get_queried_object(); if ( $term && ! empty( $term->description ) ) { - echo '
' . wc_format_content( $term->description ) . '
'; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
' . wc_format_content( $term->description ) . '
'; } } } @@ -1220,7 +1234,8 @@ if ( ! function_exists( 'woocommerce_product_archive_description' ) ) { if ( $shop_page ) { $description = wc_format_content( $shop_page->post_content ); if ( $description ) { - echo '
' . $description . '
'; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
' . $description . '
'; } } } @@ -1276,7 +1291,8 @@ if ( ! function_exists( 'woocommerce_template_loop_product_thumbnail' ) ) { * Get the product thumbnail for the loop. */ function woocommerce_template_loop_product_thumbnail() { - echo woocommerce_get_product_thumbnail(); // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo woocommerce_get_product_thumbnail(); } } if ( ! function_exists( 'woocommerce_template_loop_price' ) ) { @@ -1368,7 +1384,9 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) { ); $default_orderby = wc_get_loop_prop( 'is_search' ) ? 'relevance' : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby', '' ) ); - $orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : $default_orderby; // WPCS: sanitization ok, input var ok, CSRF ok. + // phpcs:disable WordPress.Security.NonceVerification.Recommended + $orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : $default_orderby; + // phpcs:enable WordPress.Security.NonceVerification.Recommended if ( wc_get_loop_prop( 'is_search' ) ) { $catalog_orderby_options = array_merge( array( 'relevance' => __( 'Relevance', 'woocommerce' ) ), $catalog_orderby_options ); @@ -1700,7 +1718,8 @@ if ( ! function_exists( 'woocommerce_quantity_input' ) ) { wc_get_template( 'global/quantity-input.php', $args ); if ( $echo ) { - echo ob_get_clean(); // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo ob_get_clean(); } else { return ob_get_clean(); } @@ -1780,7 +1799,8 @@ if ( ! function_exists( 'woocommerce_sort_product_tabs' ) ) { // Make sure the $tabs parameter is an array. if ( ! is_array( $tabs ) ) { - trigger_error( 'Function woocommerce_sort_product_tabs() expects an array as the first parameter. Defaulting to empty array.' ); // @codingStandardsIgnoreLine + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error + trigger_error( 'Function woocommerce_sort_product_tabs() expects an array as the first parameter. Defaulting to empty array.' ); $tabs = array(); } @@ -1817,7 +1837,8 @@ if ( ! function_exists( 'woocommerce_comments' ) ) { * @param int $depth Depth. */ function woocommerce_comments( $comment, $args, $depth ) { - $GLOBALS['comment'] = $comment; // WPCS: override ok. + // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + $GLOBALS['comment'] = $comment; wc_get_template( 'single-product/review.php', array( @@ -2443,7 +2464,8 @@ if ( ! function_exists( 'woocommerce_output_product_categories' ) ) { return false; } - echo $args['before']; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $args['before']; foreach ( $product_categories as $category ) { wc_get_template( @@ -2454,7 +2476,8 @@ if ( ! function_exists( 'woocommerce_output_product_categories' ) ) { ); } - echo $args['after']; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $args['after']; return true; } @@ -2839,7 +2862,8 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) { if ( $args['return'] ) { return $field; } else { - echo $field; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $field; } } } @@ -2882,7 +2906,8 @@ if ( ! function_exists( 'get_product_search_form' ) ) { return $form; } - echo $form; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $form; } } @@ -2951,8 +2976,10 @@ if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) { // Get selected value. if ( false === $args['selected'] && $args['attribute'] && $args['product'] instanceof WC_Product ) { - $selected_key = 'attribute_' . sanitize_title( $args['attribute'] ); - $args['selected'] = isset( $_REQUEST[ $selected_key ] ) ? wc_clean( wp_unslash( $_REQUEST[ $selected_key ] ) ) : $args['product']->get_variation_default_attribute( $args['attribute'] ); // WPCS: input var ok, CSRF ok, sanitization ok. + $selected_key = 'attribute_' . sanitize_title( $args['attribute'] ); + // phpcs:disable WordPress.Security.NonceVerification.Recommended + $args['selected'] = isset( $_REQUEST[ $selected_key ] ) ? wc_clean( wp_unslash( $_REQUEST[ $selected_key ] ) ) : $args['product']->get_variation_default_attribute( $args['attribute'] ); + // phpcs:enable WordPress.Security.NonceVerification.Recommended } $options = $args['options']; @@ -2999,7 +3026,8 @@ if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) { $html .= ''; - echo apply_filters( 'woocommerce_dropdown_variation_attribute_options_html', $html, $args ); // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo apply_filters( 'woocommerce_dropdown_variation_attribute_options_html', $html, $args ); } } @@ -3236,7 +3264,8 @@ if ( ! function_exists( 'wc_display_item_meta' ) ) { $html = apply_filters( 'woocommerce_display_item_meta', $html, $item, $args ); if ( $args['echo'] ) { - echo $html; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $html; } else { return $html; } @@ -3290,7 +3319,8 @@ if ( ! function_exists( 'wc_display_item_downloads' ) ) { $html = apply_filters( 'woocommerce_display_item_downloads', $html, $item, $args ); if ( $args['echo'] ) { - echo $html; // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $html; } else { return $html; } @@ -3698,3 +3728,5 @@ function wc_get_pay_buttons() { } echo ''; } + +// phpcs:enable Generic.Commenting.Todo.TaskFound diff --git a/includes/widgets/class-wc-widget-layered-nav.php b/includes/widgets/class-wc-widget-layered-nav.php index 40d89194f36..e69f9372497 100644 --- a/includes/widgets/class-wc-widget-layered-nav.php +++ b/includes/widgets/class-wc-widget-layered-nav.php @@ -442,8 +442,9 @@ class WC_Widget_Layered_Nav extends WC_Widget { continue; } - $filter_name = 'filter_' . wc_attribute_taxonomy_slug( $taxonomy ); - $current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ $filter_name ] ) ) ) : array(); // WPCS: input var ok, CSRF ok. + $filter_name = 'filter_' . wc_attribute_taxonomy_slug( $taxonomy ); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ $filter_name ] ) ) ) : array(); $current_filter = array_map( 'sanitize_title', $current_filter ); if ( ! in_array( $term->slug, $current_filter, true ) ) { @@ -487,7 +488,8 @@ class WC_Widget_Layered_Nav extends WC_Widget { $term_html .= ' ' . apply_filters( 'woocommerce_layered_nav_count', '(' . absint( $count ) . ')', $count, $term ); echo '
  • '; - echo apply_filters( 'woocommerce_layered_nav_term_html', $term_html, $term, $link, $count ); // WPCS: XSS ok. + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.EscapeOutput.OutputNotEscaped + echo apply_filters( 'woocommerce_layered_nav_term_html', $term_html, $term, $link, $count ); echo '
  • '; } diff --git a/templates/loop/result-count.php b/templates/loop/result-count.php index 25897e7e952..5a8c400f269 100644 --- a/templates/loop/result-count.php +++ b/templates/loop/result-count.php @@ -23,6 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) { ?>

    diff --git a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php index 9e87239e84d..da9b8e751c2 100644 --- a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php +++ b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php @@ -28,6 +28,7 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { $this->assertTrue( wc_has_notice( 'test', 'error' ) ); // Clean up. + // phpcs:disable WordPress.Security.NonceVerification.Recommended unset( $_GET['wc_error'] ); wc_clear_notices(); @@ -182,6 +183,7 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { * @group core-only */ public function test_get_catalog_ordering_args() { + // phpcs:disable WordPress.DB.SlowDBQuery $data = array( array( 'orderby' => 'menu_order', @@ -297,6 +299,7 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { ), ), ); + // phpcs:enable WordPress.DB.SlowDBQuery foreach ( $data as $test ) { $result = WC()->query->get_catalog_ordering_args( $test['orderby'], $test['order'] ); @@ -310,11 +313,13 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { public function test_get_catalog_ordering_args_GET() { $_GET['orderby'] = 'price-desc'; + // phpcs:disable WordPress.DB.SlowDBQuery $expected = array( 'orderby' => 'price', 'order' => 'DESC', 'meta_key' => '', ); + // phpcs:enable WordPress.DB.SlowDBQuery $this->assertEquals( $expected, WC()->query->get_catalog_ordering_args() ); @@ -341,9 +346,11 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { 'include_children' => true, ); + // phpcs:disable WordPress.DB.SlowDBQuery $query_args = array( 'tax_query' => array( $tax_query ), ); + // phpcs:enable WordPress.DB.SlowDBQuery WC()->query->product_query( new WP_Query( $query_args ) ); $tax_queries = WC_Query::get_main_tax_query(); @@ -360,9 +367,11 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { 'compare' => '=', ); + // phpcs:disable WordPress.DB.SlowDBQuery $query_args = array( 'meta_query' => array( $meta_query ), ); + // phpcs:enable WordPress.DB.SlowDBQuery WC()->query->product_query( new WP_Query( $query_args ) ); $meta_queries = WC_Query::get_main_meta_query(); From ff7884bdb6b428299c4a1bb4fd73558e240b2818 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Wed, 22 Apr 2020 14:42:56 +0200 Subject: [PATCH 344/440] Fix total products count display when there's one single result. Fix from "Showing all 1 results" to "Showing the single result". --- templates/loop/result-count.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/loop/result-count.php b/templates/loop/result-count.php index 5a8c400f269..1f1798261a3 100644 --- a/templates/loop/result-count.php +++ b/templates/loop/result-count.php @@ -24,7 +24,7 @@ if ( ! defined( 'ABSPATH' ) ) {

    Date: Thu, 23 Apr 2020 15:07:09 +0200 Subject: [PATCH 345/440] Fix visibility of variable products with layered nav filtering. The layered nav filtering doesn't work well with variable products when some variations have stock and other don't. When a term is selected in the widget, a variable product having no stock for the variation corresponding to that term but having stock for other variations will be displayed, but it shouldn't. This commit fixes that by introducing two changes: - A new override of "is_visible" for WC_Product_Variable that looks at the supplied filters, compares them against the corresponding available variations and calculates the visibility based on the query type (OR or AND). - A hook on the "found_posts" filter in WC_Query, that adjusts the posts count based on the found products visibility when there are filters available; this is needed to sync the "displaying X posts" messages and the paging when variable products are hidden due to stock status. Additionally, the visibility calculated in "found_posts" is cached as loop variables so that it isn't calculated again when actually displaying the products. --- includes/abstracts/abstract-wc-product.php | 12 +- includes/class-wc-product-variable.php | 62 ++++++++ includes/class-wc-query.php | 54 +++++++ includes/wc-template-functions.php | 23 ++- templates/content-product.php | 2 +- .../helpers/class-wc-helper-product.php | 20 ++- .../unit-tests/product/product-variable.php | 140 +++++++++++++++++- .../util/class-wc-tests-wc-query.php | 72 +++++++++ 8 files changed, 376 insertions(+), 9 deletions(-) diff --git a/includes/abstracts/abstract-wc-product.php b/includes/abstracts/abstract-wc-product.php index e8edd7aa055..4cf70ec1c8f 100644 --- a/includes/abstracts/abstract-wc-product.php +++ b/includes/abstracts/abstract-wc-product.php @@ -1501,6 +1501,16 @@ class WC_Product extends WC_Abstract_Legacy_Product { * @return bool */ public function is_visible() { + $visible = $this->is_visible_core(); + return apply_filters( 'woocommerce_product_is_visible', $visible, $this->get_id() ); + } + + /** + * Returns whether or not the product is visible in the catalog (doesn't trigger filters). + * + * @return bool + */ + protected function is_visible_core() { $visible = 'visible' === $this->get_catalog_visibility() || ( is_search() && 'search' === $this->get_catalog_visibility() ) || ( ! is_search() && 'catalog' === $this->get_catalog_visibility() ); if ( 'trash' === $this->get_status() ) { @@ -1521,7 +1531,7 @@ class WC_Product extends WC_Abstract_Legacy_Product { $visible = false; } - return apply_filters( 'woocommerce_product_is_visible', $visible, $this->get_id() ); + return $visible; } /** diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index ad26e1c3220..5d3b33f6157 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -572,6 +572,68 @@ class WC_Product_Variable extends WC_Product { return true; } + /** + * Returns whether or not the product is visible in the catalog (doesn't trigger filters). + * + * @return bool + */ + protected function is_visible_core() { + if ( ! $this->parent_is_visible_core() ) { + return false; + } + + $query_filters = $this->get_layered_nav_chosen_attributes(); + if ( empty( $query_filters ) ) { + return true; + } + + /** + * If there are attribute filters in the request, a variable product will be visible + * only if at least one of the corresponding variations is visible (for OR filtering) + * or if all of them are (for AND filtering). + * + * Note that for "Any..." variations the attribute value will be empty, these must be + * always included in the result and hence the '' === $value check. + */ + + $filter_attribute = array_keys( $query_filters )[0]; + $temp = array_values( $query_filters )[0]; + $filter_values = $temp['terms']; + $filter_type = $temp['query_type']; + + $attributes = array(); + foreach ( $this->get_available_variations() as $variation ) { + foreach ( $variation['attributes'] as $attribute => $value ) { + $attribute = substr( $attribute, strlen( 'attribute_' ) ); + if ( $attribute === $filter_attribute && ( '' === $value || in_array( $value, $filter_values, true ) ) && ! in_array( $value, $attributes, true ) ) { + array_push( $attributes, $value ); + } + } + } + + return ( 'or' === $filter_type && count( $attributes ) > 0 ) || ( count( $attributes ) === count( $filter_values ) ); + } + + /** + * What does is_visible_core in the parent class say? + * This method exists to ease unit testing. + * + * @return bool + */ + protected function parent_is_visible_core() { + return parent::is_visible_core(); + } + + /** + * Get an array of attributes and terms selected with the layered nav widget. + * This method exists to ease unit testing. + * + * @return array + */ + protected function get_layered_nav_chosen_attributes() { + return WC()->query::get_layered_nav_chosen_attributes(); + } + /* |-------------------------------------------------------------------------- | Sync with child variations. diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index e7ac1eeab77..98338422ce8 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -45,6 +45,7 @@ class WC_Query { add_action( 'parse_request', array( $this, 'parse_request' ), 0 ); add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); add_filter( 'the_posts', array( $this, 'remove_product_query_filters' ) ); + add_filter( 'found_posts', array( $this, 'adjust_posts_count' ) ); add_filter( 'get_pagenum_link', array( $this, 'remove_add_to_cart_pagination' ), 10, 1 ); } $this->init_query_vars(); @@ -366,6 +367,59 @@ class WC_Query { return $posts; } + /** + * When the request is filtering by attributes via layered nav plugin we need to adjust the total posts count + * to account for variable products having stock in some variations but not in others. + * We do that by just checking if each product is visible. + * + * We also cache the post visibility so that it isn't checked again when displaying the posts list. + * + * @param int $count Original posts count, as supplied by the found_posts filter. + * + * @return int Adjusted posts count. + */ + public function adjust_posts_count( $count ) { + if ( empty( $this->get_layered_nav_chosen_attributes_inst() ) ) { + return $count; + } + + $post_ids = $this->get_current_post_ids(); + $count = 0; + foreach ( $post_ids as $id ) { + $product = wc_get_product( $id ); + if ( ! is_object( $product ) ) { + continue; + } + if ( $product->is_visible() ) { + wc_set_loop_product_visibility( $id, true ); + $count++; + } else { + wc_set_loop_product_visibility( $id, false ); + } + } + + wc_set_loop_prop( 'total', $count ); + return $count; + } + + /** + * Instance version of get_layered_nav_chosen_attributes, needed for unit tests. + * + * @return array + */ + protected function get_layered_nav_chosen_attributes_inst() { + return self::get_layered_nav_chosen_attributes(); + } + + /** + * Get the ids of the posts found in the current WP loop. + * + * @return array Array of post ids. + */ + protected function get_current_post_ids() { + return $GLOBALS['wp_query']->posts; + } + /** * WP SEO meta description. * diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 760b27fa53c..6c7e4e7a25c 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -238,6 +238,27 @@ function wc_set_loop_prop( $prop, $value = '' ) { $GLOBALS['woocommerce_loop'][ $prop ] = $value; } +/** + * Set the current visbility for a product in the woocommerce_loop global. + * + * @param int $product_id Product it to cache visbiility for. + * @param bool $value The poduct visibility value to cache. + */ +function wc_set_loop_product_visibility( $product_id, $value ) { + wc_set_loop_prop( "product_visibility_$product_id", $value ); +} + +/** + * Gets the cached current visibility for a product from the woocommerce_loop global. + * + * @param int $product_id Product id to get the cached visibility for. + * + * @return bool|null The cached product visibility, or null if on visibility has been cached for that product. + */ +function wc_get_loop_product_visibility( $product_id ) { + return wc_get_loop_prop( "product_visibility_$product_id", null ); +} + /** * Should the WooCommerce loop be displayed? * @@ -247,7 +268,7 @@ function wc_set_loop_prop( $prop, $value = '' ) { * @return bool */ function woocommerce_product_loop() { - return have_posts() || 'products' !== woocommerce_get_loop_display_mode(); + return wc_get_loop_prop( 'total' ) > 0 || 'products' !== woocommerce_get_loop_display_mode(); } /** diff --git a/templates/content-product.php b/templates/content-product.php index f69bc53b95e..3d5f0d5347a 100644 --- a/templates/content-product.php +++ b/templates/content-product.php @@ -20,7 +20,7 @@ defined( 'ABSPATH' ) || exit; global $product; // Ensure visibility. -if ( empty( $product ) || ! $product->is_visible() ) { +if ( empty( $product ) || false === wc_get_loop_product_visibility( $product->get_id() ) || ! $product->is_visible() ) { return; } ?> diff --git a/tests/legacy/framework/helpers/class-wc-helper-product.php b/tests/legacy/framework/helpers/class-wc-helper-product.php index 96a595f711c..b76b27e13a9 100644 --- a/tests/legacy/framework/helpers/class-wc-helper-product.php +++ b/tests/legacy/framework/helpers/class-wc-helper-product.php @@ -103,14 +103,19 @@ class WC_Helper_Product { } /** - * Create a dummy variation product. + * Create a dummy variation product or configure an existing product object with dummy data. + * * * @since 2.3 - * + * @param WC_Product_Variable|null $product Product object to configure, or null to create a new one. * @return WC_Product_Variable */ - public static function create_variation_product() { - $product = new WC_Product_Variable(); + public static function create_variation_product( $product = null ) { + $is_new_product = is_null( $product ); + if ( $is_new_product ) { + $product = new WC_Product_Variable(); + } + $product->set_props( array( 'name' => 'Dummy Variable Product', @@ -209,7 +214,12 @@ class WC_Helper_Product { ); $variation_4->save(); - return wc_get_product( $product->get_id() ); + if ( $is_new_product ) { + return wc_get_product( $product->get_id() ); + } + + $product->set_children( array( $variation_1->get_id(), $variation_2->get_id(), $variation_3->get_id(), $variation_4->get_id() ) ); + return $product; } /** diff --git a/tests/legacy/unit-tests/product/product-variable.php b/tests/legacy/unit-tests/product/product-variable.php index 044f147375b..48d0feeba10 100644 --- a/tests/legacy/unit-tests/product/product-variable.php +++ b/tests/legacy/unit-tests/product/product-variable.php @@ -159,7 +159,7 @@ class WC_Tests_Product_Variable extends WC_Unit_Test_Case { * @param string $expected_stock_status The expected stock status of the product after being saved. */ public function test_stock_status_on_save_when_managing_stock( $stock_quantity, $notify_no_stock_amount, $accepts_backorders, $expected_stock_status ) { - list($product, $child1, $child2) = $this->get_variable_product_with_children(); + list( $product, $child1, $child2 ) = $this->get_variable_product_with_children(); update_option( 'woocommerce_notify_no_stock_amount', $notify_no_stock_amount ); @@ -176,4 +176,142 @@ class WC_Tests_Product_Variable extends WC_Unit_Test_Case { $this->assertEquals( $expected_stock_status, $product->get_stock_status() ); } + + /** + * Setup for a test for is_visible. + * + * @param array $terms Terms for the "size" attribute that will be supplied as layered nav filtering. + * @param string $query_type Logical operation for the nav filtering, "or" or "and". + * @param bool $hide_out_of_stock_products Should the woocommerce_hide_out_of_stock_items option be set?. + * @param bool $is_visible_from_parent Return value of is_visible from base class. + * + * @return WC_Product_Variable A properly configured instance of WC_Product_Variable to test. + */ + private function prepare_visibility_test( $terms, $query_type, $hide_out_of_stock_products = true, $is_visible_from_parent = true ) { + if ( empty( $terms ) ) { + $layered_nav_chosen_attributes = array(); + } else { + $layered_nav_chosen_attributes = array( + 'pa_size' => array( + 'terms' => $terms, + 'query_type' => $query_type, + ), + ); + } + + if ( $hide_out_of_stock_products ) { + update_option( 'woocommerce_hide_out_of_stock_items', 'yes' ); + } + + $sut = $this + ->getMockBuilder( WC_Product_Variable::class ) + ->setMethods( array( 'parent_is_visible_core', 'get_layered_nav_chosen_attributes' ) ) + ->getMock(); + + $sut = WC_Helper_Product::create_variation_product( $sut ); + $sut->save(); + + $sut->method( 'parent_is_visible_core' )->willReturn( $is_visible_from_parent ); + $sut->method( 'get_layered_nav_chosen_attributes' )->willReturn( $layered_nav_chosen_attributes ); + + return $sut; + } + + /** + * Configure the stock status for the "size" attribute-based variations of a product. + * + * @param WC_Product_Variable $product Product with the variations to configure. + * @param array $size_names Terms whose variations will have stock, all others won't have. + */ + private function set_size_variations_with_stock( $product, $size_names ) { + $variation_ids = $product->get_children(); + foreach ( $variation_ids as $id ) { + $variation = wc_get_product( $id ); + $size = $variation->get_attribute( 'pa_size' ); + $variation->set_stock_status( in_array( $size, $size_names, true ) ? 'instock' : 'outofstock' ); + $variation->save(); + } + } + + /** + * @testdox The product should be invisible when the parent 'is_visible' method returns false. + */ + public function test_is_invisible_when_parent_is_visible_returns_false() { + $sut = $this->prepare_visibility_test( array(), '', false, false ); + + $this->assertFalse( $sut->is_visible() ); + } + + /** + * @testdox The product should be visible when no nav filtering is supplied if at least one variation has stock. + * + * Note that if no variations have stock the base is_visible will already return false. + */ + public function test_is_visible_when_no_filtering_supplied_and_at_least_one_variation_has_stock() { + $sut = $this->prepare_visibility_test( array(), '' ); + + $this->set_size_variations_with_stock( $sut, array( 'small' ) ); + + $this->assertTrue( $sut->is_visible() ); + } + + /** + * @testdox Test product visibility when the variation requested in nav filtering has no stock, result depends on woocommerce_hide_out_of_stock_items option. + * + * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. + * @param string $query_type "or" or "and". + * @param bool $expected_visibility Expected value of is_visible for the tested product. + * + * @testWith [true, "or", false] + * [false, "or", true] + * [true, "and", false] + * [false, "and", true] + */ + public function test_visibility_when_supplied_filter_has_no_stock( $hide_out_of_stock, $query_type, $expected_visibility ) { + $sut = $this->prepare_visibility_test( array( 'large' ), $query_type, $hide_out_of_stock ); + + $this->set_size_variations_with_stock( $sut, array( 'small' ) ); + + $this->assertEquals( $expected_visibility, $sut->is_visible() ); + } + + /** + * @testdox Test product visibility when only one of the variations requested in nav filtering has stock, result depends on woocommerce_hide_out_of_stock_items option and query type. + * + * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. + * @param string $query_type "or" or "and". + * @param bool $expected_visibility Expected value of is_visible for the tested product. + * + * @testWith [true, "or", true] + * [false, "or", true] + * [true, "and", false] + * [false, "and", true] + */ + public function test_visibility_when_multiple_filters_supplied_and_only_one_has_stock( $hide_out_of_stock, $query_type, $expected_visibility ) { + $sut = $this->prepare_visibility_test( array( 'small', 'large' ), $query_type, $hide_out_of_stock ); + + $this->set_size_variations_with_stock( $sut, array( 'small' ) ); + + $this->assertEquals( $expected_visibility, $sut->is_visible() ); + } + + /** + * @testdox Product should always be visible when all of the variations requested in nav filtering have stock. + * + * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. + * @param string $query_type "or" or "and". + * @param bool $expected_visibility Expected value of is_visible for the tested product. + * + * @testWith [true, "or", true] + * [false, "or", true] + * [true, "and", true] + * [false, "and", true] + */ + public function test_visibility_when_multiple_filters_supplied_and_all_of_them_have_stock( $hide_out_of_stock, $query_type, $expected_visibility ) { + $sut = $this->prepare_visibility_test( array( 'small', 'large' ), $query_type, $hide_out_of_stock ); + + $this->set_size_variations_with_stock( $sut, array( 'small', 'large' ) ); + + $this->assertEquals( $expected_visibility, $sut->is_visible() ); + } } diff --git a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php index da9b8e751c2..27d8184b129 100644 --- a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php +++ b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php @@ -437,4 +437,76 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { WC()->query->remove_ordering_args(); } + + /** + * Setup for a test for adjust_posts. + * + * @param bool $with_nav_filtering_data Should WC_Query::get_layered_nav_chosen_attributes return filtering data?. + * + * @return array An array where the first element is the instance of WC_Query, and the second is an array of sample products created. + */ + private function setup_adjust_posts_test( $with_nav_filtering_data ) { + update_option( 'woocommerce_hide_out_of_stock_items', 'yes' ); + + if ( $with_nav_filtering_data ) { + $nav_filtering_data = array( 'pa_something' => array( 'terms' => array( 'foo', 'bar' ) ) ); + } else { + $nav_filtering_data = array(); + } + + $products = array(); + $product_ids = array(); + for ( $i = 0; $i < 5; $i++ ) { + $product = WC_Helper_Product::create_simple_product(); + array_push( $products, $product ); + array_push( $product_ids, $product->get_id() ); + } + + $products[0]->set_stock_status( 'outofstock' ); + + $sut = $this + ->getMockBuilder( WC_Query::class ) + ->setMethods( array( 'get_current_post_ids', 'get_layered_nav_chosen_attributes_inst' ) ) + ->getMock(); + + $sut->method( 'get_current_post_ids' )->willReturn( $product_ids ); + $sut->method( 'get_layered_nav_chosen_attributes_inst' )->willReturn( $nav_filtering_data ); + + return array( $sut, $products ); + } + + /** + * @testdox adjust_posts should do nothing when there are no nav filtering attributes in the request. + */ + public function test_adjust_posts_count_without_nav_filtering_attributes() { + list($sut, $products) = $this->setup_adjust_posts_test( false ); + + $products[0]->set_stock_status( 'outofstock' ); + $products[0]->save(); + + $this->assertEquals( 34, $sut->adjust_posts_count( 34 ) ); + foreach ( $products as $product ) { + $this->assertNull( wc_get_loop_product_visibility( $product->get_id() ) ); + } + } + + /** + * @testdox adjust_posts should return the number of visible products, and create product visibility loop variables, then there are nav filtering attributes in the request. + */ + public function test_adjust_posts_count_with_nav_filtering_attributes() { + list($sut, $products) = $this->setup_adjust_posts_test( true ); + + $products[0]->set_stock_status( 'outofstock' ); + $products[0]->save(); + $products[1]->set_stock_status( 'outofstock' ); + $products[1]->save(); + + $this->assertEquals( 3, $sut->adjust_posts_count( 34 ) ); + $this->assertEquals( 3, wc_get_loop_prop( 'total' ) ); + $this->assertEquals( false, wc_get_loop_product_visibility( $products[0]->get_id() ) ); + $this->assertEquals( false, wc_get_loop_product_visibility( $products[1]->get_id() ) ); + foreach ( array_slice( $products, 2 ) as $product ) { + $this->assertEquals( true, wc_get_loop_product_visibility( $product->get_id() ) ); + } + } } From 752b47513da40986139f0d13f35df6570d5a5389 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Wed, 29 Apr 2020 17:16:30 +0200 Subject: [PATCH 346/440] Fix code sniffer errors in some files. Fixed files: includes/data-stores/class-wc-product-variable-data-store-cpt.php includes/wc-update-functions.php --- ...ass-wc-product-variable-data-store-cpt.php | 4 +- includes/wc-update-functions.php | 48 +++++++++++++------ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/includes/data-stores/class-wc-product-variable-data-store-cpt.php index c579aed5bda..f27c5abe687 100644 --- a/includes/data-stores/class-wc-product-variable-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variable-data-store-cpt.php @@ -190,7 +190,7 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple $query_args = array( 'attribute_name' => wc_variation_attribute_name( $attribute['name'] ) ) + $child_ids; $values = array_unique( $wpdb->get_col( - $wpdb->prepare( // wpcs: PreparedSQLPlaceholders replacement count ok. + $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s AND post_id IN {$query_in}", // @codingStandardsIgnoreLine. $query_args ) @@ -200,7 +200,7 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple $values = array(); } - // Empty value indicates that all options for given attribute are available. + // Empty value inicates that all options for given attribute are available. if ( in_array( null, $values, true ) || in_array( '', $values, true ) || empty( $values ) ) { $values = $attribute['is_taxonomy'] ? wc_get_object_terms( $product->get_id(), $attribute['name'], 'slug' ) : wc_get_text_attributes( $attribute['value'] ); // Get custom attributes (non taxonomy) as defined. diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index ac02393eade..526d9bc579f 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -28,6 +28,7 @@ function wc_update_200_file_paths() { $old_file_path = trim( $existing_file_path->meta_value ); if ( ! empty( $old_file_path ) ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize $file_paths = serialize( array( md5( $old_file_path ) => $old_file_path ) ); $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = '_file_paths', meta_value = %s WHERE meta_id = %d", $file_paths, $existing_file_path->meta_id ) ); @@ -53,11 +54,11 @@ function wc_update_200_permalinks() { $base_slug = $shop_page_id > 0 && get_post( $shop_page_id ) ? get_page_uri( $shop_page_id ) : 'shop'; - $category_base = get_option( 'woocommerce_prepend_shop_page_to_urls' ) == 'yes' ? trailingslashit( $base_slug ) : ''; + $category_base = 'yes' === get_option( 'woocommerce_prepend_shop_page_to_urls' ) ? trailingslashit( $base_slug ) : ''; $category_slug = get_option( 'woocommerce_product_category_slug' ) ? get_option( 'woocommerce_product_category_slug' ) : _x( 'product-category', 'slug', 'woocommerce' ); $tag_slug = get_option( 'woocommerce_product_tag_slug' ) ? get_option( 'woocommerce_product_tag_slug' ) : _x( 'product-tag', 'slug', 'woocommerce' ); - if ( 'yes' == get_option( 'woocommerce_prepend_shop_page_to_products' ) ) { + if ( 'yes' === get_option( 'woocommerce_prepend_shop_page_to_products' ) ) { $product_base = trailingslashit( $base_slug ); } else { $product_slug = get_option( 'woocommerce_product_slug' ); @@ -68,7 +69,7 @@ function wc_update_200_permalinks() { } } - if ( get_option( 'woocommerce_prepend_category_to_products' ) == 'yes' ) { + if ( 'yes' === get_option( 'woocommerce_prepend_category_to_products' ) ) { $product_base .= trailingslashit( '%product_cat%' ); } @@ -90,16 +91,16 @@ function wc_update_200_permalinks() { */ function wc_update_200_subcat_display() { // Update subcat display settings. - if ( get_option( 'woocommerce_shop_show_subcategories' ) == 'yes' ) { - if ( get_option( 'woocommerce_hide_products_when_showing_subcategories' ) == 'yes' ) { + if ( 'yes' === get_option( 'woocommerce_shop_show_subcategories' ) ) { + if ( 'yes' === get_option( 'woocommerce_hide_products_when_showing_subcategories' ) ) { update_option( 'woocommerce_shop_page_display', 'subcategories' ); } else { update_option( 'woocommerce_shop_page_display', 'both' ); } } - if ( get_option( 'woocommerce_show_subcategories' ) == 'yes' ) { - if ( get_option( 'woocommerce_hide_products_when_showing_subcategories' ) == 'yes' ) { + if ( 'yes' === get_option( 'woocommerce_show_subcategories' ) ) { + if ( 'yes' === get_option( 'woocommerce_hide_products_when_showing_subcategories' ) ) { update_option( 'woocommerce_category_archive_display', 'subcategories' ); } else { update_option( 'woocommerce_category_archive_display', 'both' ); @@ -128,7 +129,7 @@ function wc_update_200_taxrates() { foreach ( $states as $state ) { - if ( '*' == $state ) { + if ( '*' === $state ) { $state = ''; } @@ -160,7 +161,7 @@ function wc_update_200_taxrates() { $location_type = ( 'postcode' === $tax_rate['location_type'] ) ? 'postcode' : 'city'; - if ( '*' == $tax_rate['state'] ) { + if ( '*' === $tax_rate['state'] ) { $tax_rate['state'] = ''; } @@ -246,7 +247,7 @@ function wc_update_200_line_items() { ) ); - // Add line item meta. + // Add line item meta. if ( $item_id ) { wc_add_order_item_meta( $item_id, '_qty', absint( $order_item['qty'] ) ); wc_add_order_item_meta( $item_id, '_tax_class', $order_item['tax_class'] ); @@ -324,7 +325,7 @@ function wc_update_200_line_items() { ) ); - // Add line item meta. + // Add line item meta. if ( $item_id ) { wc_add_order_item_meta( $item_id, 'compound', absint( isset( $order_tax['compound'] ) ? $order_tax['compound'] : 0 ) ); wc_add_order_item_meta( $item_id, 'tax_amount', wc_clean( $order_tax['cart_tax'] ) ); @@ -393,6 +394,8 @@ function wc_update_200_db_version() { function wc_update_209_brazillian_state() { global $wpdb; + // phpcs:disable WordPress.DB.SlowDBQuery + // Update brazillian state codes. $wpdb->update( $wpdb->postmeta, @@ -434,6 +437,8 @@ function wc_update_209_brazillian_state() { 'meta_value' => 'BH', ) ); + + // phpcs:enable WordPress.DB.SlowDBQuery } /** @@ -492,6 +497,7 @@ function wc_update_210_file_paths() { } } if ( $needs_update ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize $new_value = serialize( $new_value ); $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = %s, meta_value = %s WHERE meta_id = %d", '_downloadable_files', $new_value, $existing_file_path->meta_id ) ); @@ -857,6 +863,8 @@ function wc_update_240_api_keys() { * @return void */ function wc_update_240_webhooks() { + // phpcs:disable WordPress.DB.SlowDBQuery + /** * Webhooks. * Make sure order.update webhooks get the woocommerce_order_edit_status hook. @@ -873,6 +881,8 @@ function wc_update_240_webhooks() { $webhook = new WC_Webhook( $order_update_webhook->ID ); $webhook->set_topic( 'order.updated' ); } + + // phpcs:enable WordPress.DB.SlowDBQuery } /** @@ -993,6 +1003,8 @@ function wc_update_250_currency() { update_option( 'woocommerce_currency', 'LAK' ); } + // phpcs:disable WordPress.DB.SlowDBQuery + // Update LAK currency code. $wpdb->update( $wpdb->postmeta, @@ -1005,6 +1017,7 @@ function wc_update_250_currency() { ) ); + // phpcs:enable WordPress.DB.SlowDBQuery } /** @@ -1184,6 +1197,8 @@ function wc_update_260_db_version() { * @return void */ function wc_update_300_webhooks() { + // phpcs:disable WordPress.DB.SlowDBQuery + /** * Make sure product.update webhooks get the woocommerce_product_quick_edit_save * and woocommerce_product_bulk_edit_save hooks. @@ -1200,6 +1215,8 @@ function wc_update_300_webhooks() { $webhook = new WC_Webhook( $product_update_webhook->ID ); $webhook->set_topic( 'product.updated' ); } + + // phpcs:enable WordPress.DB.SlowDBQuery } /** @@ -1601,7 +1618,7 @@ function wc_update_330_product_stock_status() { AND t3.meta_key = '_backorders' AND ( t3.meta_value = 'yes' OR t3.meta_value = 'notify' )", $min_stock_amount ) - ); // WPCS: db call ok, unprepared SQL ok, cache ok. + ); if ( empty( $post_ids ) ) { return; @@ -1609,12 +1626,14 @@ function wc_update_330_product_stock_status() { $post_ids = array_map( 'absint', $post_ids ); + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared // Set the status to onbackorder for those products. $wpdb->query( "UPDATE $wpdb->postmeta SET meta_value = 'onbackorder' WHERE meta_key = '_stock_status' AND post_id IN ( " . implode( ',', $post_ids ) . ' )' - ); // WPCS: db call ok, unprepared SQL ok, cache ok. + ); + // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared } /** @@ -2065,7 +2084,8 @@ function wc_update_390_move_maxmind_database() { $new_path = apply_filters( 'woocommerce_geolocation_local_database_path', $new_path, 2 ); $new_path = apply_filters( 'woocommerce_maxmind_geolocation_database_path', $new_path ); - @rename( $old_path, $new_path ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged + @rename( $old_path, $new_path ); } /** From e1265bfa255da57c173019390b7ce7b3d6fd1a7d Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Wed, 29 Apr 2020 17:18:48 +0200 Subject: [PATCH 347/440] Refactor WC_Helper_Product by extracting duplicated code to methods. The new methods are create_product_variation_object and create_product_attribute_object, they are public. --- .../helpers/class-wc-helper-product.php | 135 +++++++++--------- 1 file changed, 68 insertions(+), 67 deletions(-) diff --git a/tests/legacy/framework/helpers/class-wc-helper-product.php b/tests/legacy/framework/helpers/class-wc-helper-product.php index b76b27e13a9..2691c6ae804 100644 --- a/tests/legacy/framework/helpers/class-wc-helper-product.php +++ b/tests/legacy/framework/helpers/class-wc-helper-product.php @@ -125,94 +125,48 @@ class WC_Helper_Product { $attributes = array(); - $attribute = new WC_Product_Attribute(); - $attribute_data = self::create_attribute( 'size', array( 'small', 'large', 'huge' ) ); - $attribute->set_id( $attribute_data['attribute_id'] ); - $attribute->set_name( $attribute_data['attribute_taxonomy'] ); - $attribute->set_options( $attribute_data['term_ids'] ); - $attribute->set_position( 1 ); - $attribute->set_visible( true ); - $attribute->set_variation( true ); - $attributes[] = $attribute; - - $attribute = new WC_Product_Attribute(); - $attribute_data = self::create_attribute( 'colour', array( 'red', 'blue' ) ); - $attribute->set_id( $attribute_data['attribute_id'] ); - $attribute->set_name( $attribute_data['attribute_taxonomy'] ); - $attribute->set_options( $attribute_data['term_ids'] ); - $attribute->set_position( 1 ); - $attribute->set_visible( true ); - $attribute->set_variation( true ); - $attributes[] = $attribute; - - $attribute = new WC_Product_Attribute(); - $attribute_data = self::create_attribute( 'number', array( '0', '1', '2' ) ); - $attribute->set_id( $attribute_data['attribute_id'] ); - $attribute->set_name( $attribute_data['attribute_taxonomy'] ); - $attribute->set_options( $attribute_data['term_ids'] ); - $attribute->set_position( 1 ); - $attribute->set_visible( true ); - $attribute->set_variation( true ); - $attributes[] = $attribute; + $attributes[] = self::create_product_attribute_object( 'size', array( 'small', 'large', 'huge' ) ); + $attributes[] = self::create_product_attribute_object( 'colour', array( 'red', 'blue' ) ); + $attributes[] = self::create_product_attribute_object( 'number', array( '0', '1', '2' ) ); $product->set_attributes( $attributes ); $product->save(); - $variation_1 = new WC_Product_Variation(); - $variation_1->set_props( - array( - 'parent_id' => $product->get_id(), - 'sku' => 'DUMMY SKU VARIABLE SMALL', - 'regular_price' => 10, - ) + $variation_1 = self::create_product_variation_object( + $product->get_id(), + 'DUMMY SKU VARIABLE SMALL', + 10, + array( 'pa_size' => 'small' ) ); - $variation_1->set_attributes( array( 'pa_size' => 'small' ) ); - $variation_1->save(); - $variation_2 = new WC_Product_Variation(); - $variation_2->set_props( - array( - 'parent_id' => $product->get_id(), - 'sku' => 'DUMMY SKU VARIABLE LARGE', - 'regular_price' => 15, - ) + $variation_2 = self::create_product_variation_object( + $product->get_id(), + 'DUMMY SKU VARIABLE LARGE', + 15, + array( 'pa_size' => 'large' ) ); - $variation_2->set_attributes( array( 'pa_size' => 'large' ) ); - $variation_2->save(); - $variation_3 = new WC_Product_Variation(); - $variation_3->set_props( - array( - 'parent_id' => $product->get_id(), - 'sku' => 'DUMMY SKU VARIABLE HUGE RED 0', - 'regular_price' => 16, - ) - ); - $variation_3->set_attributes( + $variation_3 = self::create_product_variation_object( + $product->get_id(), + 'DUMMY SKU VARIABLE RED 0', + 16, array( 'pa_size' => 'huge', 'pa_colour' => 'red', 'pa_number' => '0', ) ); - $variation_3->save(); - $variation_4 = new WC_Product_Variation(); - $variation_4->set_props( - array( - 'parent_id' => $product->get_id(), - 'sku' => 'DUMMY SKU VARIABLE HUGE RED 2', - 'regular_price' => 17, - ) - ); - $variation_4->set_attributes( + $variation_4 = self::create_product_variation_object( + $product->get_id(), + 'DUMMY SKU VARIABLE RED 2', + 17, array( 'pa_size' => 'huge', 'pa_colour' => 'red', 'pa_number' => '2', ) ); - $variation_4->save(); if ( $is_new_product ) { return wc_get_product( $product->get_id() ); @@ -222,6 +176,53 @@ class WC_Helper_Product { return $product; } + /** + * Creates an instance of WC_Product_Variation with the supplied parameters, optionally persisting it to the database. + * + * @param string $parent_id Parent product id. + * @param string $sku SKU for the variation. + * @param int $price Price of the variation. + * @param array $attributes Attributes that define the variation, e.g. ['pa_color'=>'red']. + * @param bool $save If true, the object will be saved to the database after being created and configured. + * + * @return WC_Product_Variation The created object. + */ + public static function create_product_variation_object( $parent_id, $sku, $price, $attributes, $save = true ) { + $variation = new WC_Product_Variation(); + $variation->set_props( + array( + 'parent_id' => $parent_id, + 'sku' => $sku, + 'regular_price' => $price, + ) + ); + $variation->set_attributes( $attributes ); + if ( $save ) { + $variation->save(); + } + return $variation; + } + + /** + * Creates an instance of WC_Product_Attribute with the supplied parameters. + * + * @param string $raw_name Attribute raw name (without 'pa_' prefix). + * @param array $terms Possible values for the attribute. + * + * @return WC_Product_Attribute The created attribute object. + */ + public static function create_product_attribute_object( $raw_name = 'size', $terms = array( 'small' ) ) { + $attribute = new WC_Product_Attribute(); + $attribute_data = self::create_attribute( $raw_name, $terms ); + $attribute->set_id( $attribute_data['attribute_id'] ); + $attribute->set_name( $attribute_data['attribute_taxonomy'] ); + $attribute->set_options( $attribute_data['term_ids'] ); + $attribute->set_position( 1 ); + $attribute->set_visible( true ); + $attribute->set_variation( true ); + return $attribute; + } + /** * Create a dummy attribute. * From 9c6c0d73d817328e3a90b6e3e0b1b0f0b7662270 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Wed, 29 Apr 2020 17:35:56 +0200 Subject: [PATCH 348/440] Record attribute terms for product variations in wp_term_relationships. Product attributes are currently recorded as terms in wp_term_relationships (product attributes are actually taxonomies). In the case of variable products this is true for the main product, but not for the variations. The attributes used to define variations are stored as post meta, but nothing is recorded in the term relationships table. This is a problem when using the layered nav filtering plugin, since the attribute counters displayed are calculated based solely on the contents of the term relationships table. Adding meta queries would be really messy (especially when the widget is configured with AND operator) and would probably also hurt performance. This commit adds a change to store the attributes for variations as term relationships, additionally to storing them as post meta. Terms are stored on variation creation, and updated/deleted together with the variation as appropriate. "Any" variations (stored in meta as empty values) are not stored as terms. Additionally, a database upgrade is included in order to backfill terms for already existing products. --- includes/class-wc-install.php | 8 +- includes/class-wc-product-variation.php | 29 +++- ...ass-wc-product-variable-data-store-cpt.php | 1 + ...ss-wc-product-variation-data-store-cpt.php | 22 ++- includes/wc-update-functions.php | 45 ++++++ .../unit-tests/product/product-variation.php | 39 +++++ ...-tests-product-variable-data-store-cpt.php | 29 ++++ ...tests-product-variation-data-store-cpt.php | 137 ++++++++++++++++++ 8 files changed, 301 insertions(+), 9 deletions(-) create mode 100644 tests/unit-tests/product/class-wc-tests-product-variable-data-store-cpt.php create mode 100644 tests/unit-tests/product/class-wc-tests-product-variation-data-store-cpt.php diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index e6b2d9e1379..81852351601 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -149,6 +149,10 @@ class WC_Install { 'wc_update_400_reset_action_scheduler_migration_status', 'wc_update_400_db_version', ), + '4.2.0' => array( + 'wc_update_420_insert_attribute_terms_for_variable_products', + 'wc_update_420_db_version', + ), ); /** @@ -752,14 +756,14 @@ class WC_Install { AND CONSTRAINT_NAME = 'fk_{$wpdb->prefix}wc_download_log_permission_id' AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_NAME = '{$wpdb->prefix}wc_download_log'" - ); // WPCS: unprepared SQL ok. + ); if ( 0 === (int) $fk_result->fk_count ) { $wpdb->query( "ALTER TABLE `{$wpdb->prefix}wc_download_log` ADD CONSTRAINT `fk_{$wpdb->prefix}wc_download_log_permission_id` FOREIGN KEY (`permission_id`) REFERENCES `{$wpdb->prefix}woocommerce_downloadable_product_permissions` (`permission_id`) ON DELETE CASCADE;" - ); // WPCS: unprepared SQL ok. + ); } } diff --git a/includes/class-wc-product-variation.php b/includes/class-wc-product-variation.php index d3b159f60df..e3e6cf04a66 100644 --- a/includes/class-wc-product-variation.php +++ b/includes/class-wc-product-variation.php @@ -110,15 +110,18 @@ class WC_Product_Variation extends WC_Product_Simple { } /** - * Get variation attribute values. Keys are prefixed with attribute_, as stored. + * Get variation attribute values. Keys are prefixed with attribute_, as stored, unless $with_prefix is false. * - * @return array of attributes and their values for this variation + * @param bool $with_prefix Whether keys should be prepended with attribute_ or not, default is true. + * @return array of attributes and their values for this variation. */ - public function get_variation_attributes() { + public function get_variation_attributes( $with_prefix = true ) { $attributes = $this->get_attributes(); $variation_attributes = array(); + $prefix = $with_prefix ? 'attribute_' : ''; + foreach ( $attributes as $key => $value ) { - $variation_attributes[ 'attribute_' . $key ] = $value; + $variation_attributes[ $prefix . $key ] = $value; } return $variation_attributes; } @@ -580,4 +583,22 @@ class WC_Product_Variation extends WC_Product_Simple { return $valid_classes; } + + /** + * Delete variation, set the ID to 0, and return result. + * + * @since 2.6.0 + * @param bool $force_delete Should the variation be deleted permanently. + * @return bool result + */ + public function delete( $force_delete = false ) { + $variation_id = $this->get_id(); + + if ( ! parent::delete( $force_delete ) ) { + return false; + } + + wp_delete_object_term_relationships( $variation_id, wc_get_attribute_taxonomy_names() ); + return true; + } } diff --git a/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/includes/data-stores/class-wc-product-variable-data-store-cpt.php index f27c5abe687..a6e8a3781e2 100644 --- a/includes/data-stores/class-wc-product-variable-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variable-data-store-cpt.php @@ -661,6 +661,7 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple if ( $force_delete ) { do_action( 'woocommerce_before_delete_product_variation', $variation_id ); wp_delete_post( $variation_id, true ); + wp_delete_object_term_relationships( $variation_id, wc_get_attribute_taxonomy_names() ); do_action( 'woocommerce_delete_product_variation', $variation_id ); } else { wp_trash_post( $variation_id ); diff --git a/includes/data-stores/class-wc-product-variation-data-store-cpt.php b/includes/data-stores/class-wc-product-variation-data-store-cpt.php index 2dd1d116678..85e40c86da0 100644 --- a/includes/data-stores/class-wc-product-variation-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variation-data-store-cpt.php @@ -473,10 +473,12 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl if ( $force || array_key_exists( 'attributes', $changes ) ) { global $wpdb; + + $product_id = $product->get_id(); $attributes = $product->get_attributes(); $updated_attribute_keys = array(); foreach ( $attributes as $key => $value ) { - update_post_meta( $product->get_id(), 'attribute_' . $key, wp_slash( $value ) ); + update_post_meta( $product_id, 'attribute_' . $key, wp_slash( $value ) ); $updated_attribute_keys[] = 'attribute_' . $key; } @@ -486,13 +488,27 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration "SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE %s AND meta_key NOT IN ( '" . implode( "','", array_map( 'esc_sql', $updated_attribute_keys ) ) . "' ) AND post_id = %d", $wpdb->esc_like( 'attribute_' ) . '%', - $product->get_id() + $product_id ) ); foreach ( $delete_attribute_keys as $key ) { - delete_post_meta( $product->get_id(), $key ); + delete_post_meta( $product_id, $key ); } + + // Set the attributes as regular taxonomy terms too... + $variation_attributes = array_keys( $product->get_variation_attributes( false ) ); + foreach ( $attributes as $name => $value ) { + if ( '' !== $value && in_array( $name, $variation_attributes, true ) && term_exists( $value, $name ) ) { + wp_set_post_terms( $product_id, array( $value ), $name ); + } elseif ( taxonomy_exists( $name ) ) { + wp_delete_object_term_relationships( $product_id, $name ); + } + } + + // ...and remove old taxonomy terms. + $attributes_to_delete = array_diff( wc_get_attribute_taxonomy_names(), array_keys( $attributes ) ); + wp_delete_object_term_relationships( $product_id, $attributes_to_delete ); } } diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 526d9bc579f..c57bb7d4d1a 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2130,3 +2130,48 @@ function wc_update_400_reset_action_scheduler_migration_status() { function wc_update_400_db_version() { WC_Install::update_db_version( '4.0.0' ); } + +/** + * Register attributes as terms for variable products, in increments of 100 products. + * + * @return bool true if there are more products to process. + */ +function wc_update_420_insert_attribute_terms_for_variable_products() { + $state_option_name = 'woocommerce_' . __FUNCTION__ . '_state'; + + $page = intval( get_option( $state_option_name, 1 ) ); + $products = wc_get_products( + array( + 'type' => 'variable', + 'limit' => 100, + 'page' => $page, + ) + ); + if ( empty( $products ) ) { + delete_option( $state_option_name ); + return false; + } + + $attribute_taxonomy_names = wc_get_attribute_taxonomy_names(); + foreach ( $products as $product ) { + $variation_ids = $product->get_children(); + foreach ( $variation_ids as $variation_id ) { + $variation = wc_get_product( $variation_id ); + $variation_attributes = $variation->get_attributes(); + foreach ( $variation_attributes as $attr_name => $attr_value ) { + wp_set_post_terms( $variation_id, array( $attr_value ), $attr_name ); + } + $attributes_to_delete = array_diff( $attribute_taxonomy_names, array_keys( $variation_attributes ) ); + wp_delete_object_term_relationships( $variation_id, $attributes_to_delete ); + } + } + + return update_option( $state_option_name, $page + 1 ); +} + +/** + * Update DB version. + */ +function wc_update_420_db_version() { + WC_Install::update_db_version( '4.2.0' ); +} diff --git a/tests/legacy/unit-tests/product/product-variation.php b/tests/legacy/unit-tests/product/product-variation.php index ece9efbdb2e..c8102764cce 100644 --- a/tests/legacy/unit-tests/product/product-variation.php +++ b/tests/legacy/unit-tests/product/product-variation.php @@ -91,4 +91,43 @@ class WC_Tests_Product_Variation extends WC_Unit_Test_Case { $variable_product = WC_Helper_Product::create_variation_product(); new WC_Product_Variation( $variable_product->get_id() ); } + + /** + * @testdox Test that get_variation_attributes returns the appropriate values. + * + * @param bool $with_prefix Parameter for get_variation_attributes. + * @param string $expected_prefix Expected prefix on the returned attribute names. + * + * @testWith [true, "attribute_"] + * [false, ""] + */ + public function test_get_variation_attributes( $with_prefix, $expected_prefix ) { + $product = WC_Helper_Product::create_variation_product(); + $sut = wc_get_product( $product->get_children()[2] ); + + $expected = array( + $expected_prefix . 'pa_size' => 'huge', + $expected_prefix . 'pa_colour' => 'red', + $expected_prefix . 'pa_number' => '0', + ); + + $actual = $sut->get_variation_attributes( $with_prefix ); + $this->assertEquals( $expected, $actual ); + } + + /** + * @testdox Test that the delete method removes the attribute terms for the variation. + */ + public function test_delete_removes_attribute_terms() { + $product = WC_Helper_Product::create_variation_product(); + $sut = wc_get_product( $product->get_children()[2] ); + $id = $sut->get_id(); + + $sut->delete( true ); + + $attribute_names = wc_get_attribute_taxonomy_names(); + $variation_attribute_terms = wp_get_post_terms( $id, $attribute_names ); + + $this->assertEmpty( $variation_attribute_terms ); + } } diff --git a/tests/unit-tests/product/class-wc-tests-product-variable-data-store-cpt.php b/tests/unit-tests/product/class-wc-tests-product-variable-data-store-cpt.php new file mode 100644 index 00000000000..46b5c9b30a1 --- /dev/null +++ b/tests/unit-tests/product/class-wc-tests-product-variable-data-store-cpt.php @@ -0,0 +1,29 @@ +get_children()[2] ); + $variation_id = $variation->get_id(); + + $sut = new WC_Product_Variable_Data_Store_CPT(); + $sut->delete_variations( $product->get_id(), true ); + + $attribute_names = wc_get_attribute_taxonomy_names(); + $variation_attribute_terms = wp_get_post_terms( $variation_id, $attribute_names ); + + $this->assertEmpty( $variation_attribute_terms ); + } +} diff --git a/tests/unit-tests/product/class-wc-tests-product-variation-data-store-cpt.php b/tests/unit-tests/product/class-wc-tests-product-variation-data-store-cpt.php new file mode 100644 index 00000000000..b38b9a2dcdf --- /dev/null +++ b/tests/unit-tests/product/class-wc-tests-product-variation-data-store-cpt.php @@ -0,0 +1,137 @@ +set_attributes( array( $attr_size, $attr_color ) ); + $product->save(); + + $variation = WC_Helper_Product::create_product_variation_object( + $product->get_id(), + 'SMALL RED THING', + 10, + array( + 'pa_size' => 'small', + 'pa_color' => 'red', + ) + ); + + return $variation; + } + + /** + * Return a simplified list with the attribute terms for a variation object. + * + * @param int $variation_id Id of the variation product. + * + * @return array Attributes as an "attribute"=>"term" associative array. + */ + private function get_attribute_terms_for_variation( $variation_id ) { + $attribute_names = wc_get_attribute_taxonomy_names(); + $variation_attribute_terms = wp_get_post_terms( $variation_id, $attribute_names ); + $terms = array(); + foreach ( $variation_attribute_terms as $term ) { + $terms[ $term->taxonomy ] = $term->name; + } + return $terms; + } + + /** + * @testdox Test that attribute terms are created for new variations. + */ + public function test_attribute_terms_are_created_for_new_variations() { + $variation = $this->create_variation_object_for_existing_variable_product(); + + $sut = new WC_Product_Variation_Data_Store_CPT(); + $sut->create( $variation ); + + $terms = $this->get_attribute_terms_for_variation( $variation->get_id() ); + + $expected = array( + 'pa_size' => 'small', + 'pa_color' => 'red', + ); + + $this->assertEquals( $expected, $terms ); + + $variation->set_attributes( + array( + 'pa_size' => 'large', + 'pa_color' => 'blue', + ) + ); + + $sut->update( $variation ); + + $terms = $this->get_attribute_terms_for_variation( $variation->get_id() ); + + $expected = array( + 'pa_size' => 'large', + 'pa_color' => 'blue', + ); + + $this->assertEquals( $expected, $terms ); + } + + /** + * @testdox Test that attribute terms are updated for updated variations. + */ + public function test_attribute_terms_are_updated_for_modified_variations() { + $variation = $this->create_variation_object_for_existing_variable_product(); + + $sut = new WC_Product_Variation_Data_Store_CPT(); + $sut->create( $variation ); + + $new_attributes = array( + 'pa_size' => 'small', + 'pa_color' => 'red', + ); + $variation->set_attributes( $new_attributes ); + $sut->update( $variation ); + + $terms = $this->get_attribute_terms_for_variation( $variation->get_id() ); + + $this->assertEquals( $new_attributes, $terms ); + } + + /** + * @testdox Test that attribute terms are removed for variations updated with "Any" value. + */ + public function test_attribute_terms_are_removed_for_variations_set_to_any_attribute_value() { + $variation = $this->create_variation_object_for_existing_variable_product(); + + $sut = new WC_Product_Variation_Data_Store_CPT(); + $sut->create( $variation ); + + $new_attributes = array( + 'pa_size' => 'small', + 'pa_color' => '', + ); + $variation->set_attributes( $new_attributes ); + $sut->update( $variation ); + + $terms = $this->get_attribute_terms_for_variation( $variation->get_id() ); + + $expected = array( 'pa_size' => 'small' ); + + $this->assertEquals( $expected, $terms ); + } +} From 9de1306c21600aa11423361719f260c7069073cd Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Thu, 30 Apr 2020 16:49:36 +0200 Subject: [PATCH 349/440] Fix counters in nav filtering widgets for variable products. After the change that registers variation attributes as terms (in addition to reigstering them as post meta) it is now time to modify the get_filtered_term_product_counts methods in WC_Widget_Layered_Nav so that it works consistently for both variable and non-variable products. The logic for the counters is now as follows: with OR operator: - Simple products: count the attributes of all visible products (unchanged behavior). - Variable products: count attributes corresponding to visible variations. with AND operator: - Simple products: count the attributes of visible products but only for products that have all the selected (unchanged behavior). - Variable products: find all the products for which all the variations corresponding to the selected attributes exist and are visible, then count the attributes corresponding to the visible variations of those products. A product is "visible" if it's published, not excluded for catalog, and has stock. Additionally, a variable product will not be considered visible if the parent product is not. --- .../widgets/class-wc-widget-layered-nav.php | 180 +++++++- .../class-wc-tests-widget-layered-nav.php | 413 ++++++++++++++++++ 2 files changed, 572 insertions(+), 21 deletions(-) create mode 100644 tests/unit-tests/widgets/class-wc-tests-widget-layered-nav.php diff --git a/includes/widgets/class-wc-widget-layered-nav.php b/includes/widgets/class-wc-widget-layered-nav.php index e69f9372497..4f6a693ab82 100644 --- a/includes/widgets/class-wc-widget-layered-nav.php +++ b/includes/widgets/class-wc-widget-layered-nav.php @@ -344,49 +344,85 @@ class WC_Widget_Layered_Nav extends WC_Widget { protected function get_filtered_term_product_counts( $term_ids, $taxonomy, $query_type ) { global $wpdb; - $tax_query = WC_Query::get_main_tax_query(); - $meta_query = WC_Query::get_main_meta_query(); + $main_tax_query = $this->get_main_tax_query(); + $meta_query = $this->get_main_meta_query(); - if ( 'or' === $query_type ) { - foreach ( $tax_query as $key => $query ) { - if ( is_array( $query ) && $taxonomy === $query['taxonomy'] ) { - unset( $tax_query[ $key ] ); + $variable_tax_query_sql = array( 'where' => '' ); + $non_variable_tax_query_sql = array( 'where' => '' ); + + $is_and_query = 'and' === $query_type; + + foreach ( $main_tax_query as $key => $query ) { + if ( is_array( $query ) && $taxonomy === $query['taxonomy'] ) { + if ( $is_and_query ) { + $non_variable_tax_query_sql = $this->convert_tax_query_to_sql( array( $query ) ); + $variable_tax_query_sql = $this->get_extra_tax_query_sql( $taxonomy, $query['terms'], 'IN' ); + $selected_terms_count = count( $query['terms'] ); } + unset( $main_tax_query[ $key ] ); } } - $meta_query = new WP_Meta_Query( $meta_query ); - $tax_query = new WP_Tax_Query( $tax_query ); - $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); - $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); + $needs_extra_query_for_variable_products = $is_and_query && isset( $selected_terms_count ); + + $exclude_variable_products_tax_query_sql = $this->get_extra_tax_query_sql( 'product_type', array( 'variable' ), 'NOT IN' ); + + $meta_query_sql = ( new WP_Meta_Query( $meta_query ) )->get_sql( 'post', $wpdb->posts, 'ID' ); + $main_tax_query_sql = $this->convert_tax_query_to_sql( $main_tax_query ); + $term_ids_sql = '(' . implode( ',', array_map( 'absint', $term_ids ) ) . ')'; // Generate query. $query = array(); $query['select'] = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) as term_count, terms.term_id as term_count_id"; $query['from'] = "FROM {$wpdb->posts}"; $query['join'] = " - INNER JOIN {$wpdb->term_relationships} AS term_relationships ON {$wpdb->posts}.ID = term_relationships.object_id + INNER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id ) INNER JOIN {$wpdb->terms} AS terms USING( term_id ) - " . $tax_query_sql['join'] . $meta_query_sql['join']; + {$main_tax_query_sql['join']} {$meta_query_sql['join']}"; // Not an omission, really no more JOINs required. + + $variable_where_part = " + {$wpdb->posts}.post_type = 'product_variation' + AND NOT EXISTS ( + SELECT ID FROM {$wpdb->posts} AS parent + WHERE parent.ID = {$wpdb->posts}.post_parent AND parent.post_status NOT IN ('publish') + ) + {$variable_tax_query_sql['where']} + "; + $variable_where_part_for_main_query = $needs_extra_query_for_variable_products ? '' : "OR ($variable_where_part)"; + + $search_sql = ''; + $search = $this->get_main_search_query_sql(); + if ( $search ) { + $search_sql = ' AND ' . $search; + } $query['where'] = " - WHERE {$wpdb->posts}.post_type IN ( 'product' ) - AND {$wpdb->posts}.post_status = 'publish'" - . $tax_query_sql['where'] . $meta_query_sql['where'] . - 'AND terms.term_id IN (' . implode( ',', array_map( 'absint', $term_ids ) ) . ')'; + WHERE + {$wpdb->posts}.post_status = 'publish' + {$main_tax_query_sql['where']} {$meta_query_sql['where']} + AND ( + ( + {$wpdb->posts}.post_type = 'product' + {$exclude_variable_products_tax_query_sql['where']} + {$non_variable_tax_query_sql['where']} + ) + {$variable_where_part_for_main_query} + ) + AND terms.term_id IN {$term_ids_sql} + {$search_sql}"; - $search = WC_Query::get_main_search_query_sql(); + $search = $this->get_main_search_query_sql(); if ( $search ) { $query['where'] .= ' AND ' . $search; } $query['group_by'] = 'GROUP BY terms.term_id'; $query = apply_filters( 'woocommerce_get_filtered_term_product_counts_query', $query ); - $query = implode( ' ', $query ); + $query_sql = implode( ' ', $query ); // We have a query - let's see if cached results of this query already exist. - $query_hash = md5( $query ); + $query_hash = md5( $query_sql ); // Maybe store a transient of the count values. $cache = apply_filters( 'woocommerce_layered_nav_count_maybe_cache', true ); @@ -397,17 +433,119 @@ class WC_Widget_Layered_Nav extends WC_Widget { } if ( ! isset( $cached_counts[ $query_hash ] ) ) { - $results = $wpdb->get_results( $query, ARRAY_A ); // @codingStandardsIgnoreLine - $counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) ); + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + $results = $wpdb->get_results( $query_sql, ARRAY_A ); + $counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) ); + if ( $needs_extra_query_for_variable_products ) { + /** + * This query: + * 1. Finds out how many variable products have variations corresponding to all the attributes + * supplied in the filtering request (all the variations must be visible). + * 2. Then, it returns the term_taxonomy_id of all the visible variations for all the products + * found in the previous step. + * + * Each term_taxonomy_id is returned as many times as it's found, this is required for the proper + * generation of the counts. + */ + $variable_count_query_sql = " + SELECT term_taxonomy_id FROM {$wpdb->term_relationships} + INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id + where {$wpdb->posts}.post_parent in ( + SELECT {$wpdb->posts}.post_parent FROM {$wpdb->posts} + {$query['join']} + WHERE + {$wpdb->posts}.post_status = 'publish' + {$main_tax_query_sql['where']} {$meta_query_sql['where']} + AND ( + {$variable_where_part} + ) + + {$variable_tax_query_sql['where']} + GROUP BY post_parent HAVING COUNT(1)>={$selected_terms_count} + ) + AND term_taxonomy_id IN {$term_ids_sql} + {$main_tax_query_sql['where']} + "; + $term_ids_result = $wpdb->get_results( $variable_count_query_sql, ARRAY_N ); + foreach ( $term_ids_result as $result ) { + $term_id = $result[0]; + $counts[ $term_id ] = array_key_exists( $term_id, $counts ) ? $counts[ $term_id ] + 1 : 1; + } + } $cached_counts[ $query_hash ] = $counts; if ( true === $cache ) { set_transient( 'wc_layered_nav_counts_' . sanitize_title( $taxonomy ), $cached_counts, DAY_IN_SECONDS ); } + // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared } return array_map( 'absint', (array) $cached_counts[ $query_hash ] ); } + /** + * Wrapper for WC_Query::get_main_tax_query() to ease unit testing. + * + * @return array + */ + protected function get_main_tax_query() { + return WC_Query::get_main_tax_query(); + } + + /** + * Wrapper for WC_Query::get_main_search_query_sql() to ease unit testing. + * + * @return string + */ + protected function get_main_search_query_sql() { + return WC_Query::get_main_search_query_sql(); + } + + /** + * Wrapper for WC_Query::get_main_search_queryget_main_meta_query to ease unit testing. + * + * @return array + */ + protected function get_main_meta_query() { + return WC_Query::get_main_meta_query(); + } + + /** + * Get a tax query SQL for a given set of taxonomy, terms and operator. + * Uses an intermediate WP_Tax_Query object. + * + * @param string $taxonomy Taxonomy name. + * @param array $terms Terms to include in the query. + * @param string $operator Query operator, as supported by WP_Tax_Query; e.g. "NOT IN". + * + * @return array + */ + private function get_extra_tax_query_sql( $taxonomy, $terms, $operator ) { + $query = array( + array( + 'taxonomy' => $taxonomy, + 'field' => 'slug', + 'terms' => $terms, + 'operator' => $operator, + 'include_children' => false, + ), + ); + + return $this->convert_tax_query_to_sql( $query ); + } + + /** + * Convert a tax query array to SQL using an intermediate WP_Tax_Query object. + * + * @param array $query Query array in the same format accepted by WP_Tax_Query constructor. + * + * @return array Query SQL as returned by WP_Tax_Query->get_sql. + */ + private function convert_tax_query_to_sql( $query ) { + global $wpdb; + + return ( new WP_Tax_Query( $query ) )->get_sql( $wpdb->posts, 'ID' ); + } + /** * Show list based layered nav. * diff --git a/tests/unit-tests/widgets/class-wc-tests-widget-layered-nav.php b/tests/unit-tests/widgets/class-wc-tests-widget-layered-nav.php new file mode 100644 index 00000000000..feda88bd059 --- /dev/null +++ b/tests/unit-tests/widgets/class-wc-tests-widget-layered-nav.php @@ -0,0 +1,413 @@ + 'and', + 0 => array( + 'taxonomy' => 'product_visibility', + 'terms' => array( + get_term_by( 'slug', 'outofstock', 'product_visibility' )->term_taxonomy_id, + get_term_by( 'slug', 'exclude-from-catalog', 'product_visibility' )->term_taxonomy_id, + ), + 'field' => 'term_taxonomy_id', + 'operator' => 'NOT IN', + ), + ); + + if ( ! empty( $filter_colors ) ) { + array_push( + $tax_query, + array( + 'taxonomy' => 'pa_color', + 'terms' => $filter_colors, + 'field' => 'slug', + 'operator' => $filter_operation, + ) + ); + } + + $sut = $this + ->getMockBuilder( WC_Widget_Layered_Nav::class ) + ->setMethods( array( 'get_main_tax_query', 'get_main_meta_query', 'get_main_search_query_sql' ) ) + ->getMock(); + + $sut->method( 'get_main_tax_query' )->willReturn( $tax_query ); + $sut->method( 'get_main_meta_query' )->willReturn( array() ); + $sut->method( 'get_main_search_query_sql' )->willReturn( null ); + + return $sut; + } + + /** + * Create a simple or variable product that has color attributes. + * If a variable product is created, a variation will be created for each color. + * + * @param string $name Name of the product. + * @param array $colors_in_stock Slugs of the colors whose variations will have stock. If null, a simple product is created. + * @param array $colors_disabled Slugs of the colors whose variations will be disabled, N/A for a simple product. + * + * @return WC_Product_Simple|WC_Product_Variable The created product. + */ + private function create_colored_product( $name, $colors_in_stock, $colors_disabled = array() ) { + $create_as_simple = is_null( $colors_in_stock ); + $main_product = $create_as_simple ? new WC_Product_Simple() : new WC_Product_Variable(); + + $main_product->set_props( + array( + 'name' => $name, + 'sku' => 'SKU for' . $name, + ) + ); + + $existing_colors = array( 'black', 'brown', 'blue', 'green', 'pink', 'yellow' ); + $attributes = array( WC_Helper_Product::create_product_attribute_object( 'color', $existing_colors ) ); + $main_product->set_attributes( $attributes ); + $main_product->save(); + + if ( $create_as_simple ) { + return $main_product; + } + + $variation_objects = array(); + foreach ( $existing_colors as $color ) { + $variation_object = WC_Helper_Product::create_product_variation_object( + $main_product->get_id(), + "SKU for $color $name", + 10, + array( 'pa_color' => $color ) + ); + if ( ! in_array( $color, $colors_in_stock, true ) ) { + $variation_object->set_stock_status( 'outofstock' ); + } + $variation_object->save(); + + if ( in_array( $color, $colors_disabled, true ) ) { + wp_update_post( + array( + 'ID' => $variation_object->get_id(), + 'post_status' => 'draft', + ) + ); + } + + array_push( $variation_objects, $variation_object->get_id() ); + } + + $main_product->set_children( $variation_objects ); + + return $main_product; + } + + /** + * Invoke a protected method in an object. + * + * @param object $object Object whose method will be invoked. + * @param string $method Name of the method to invoke. + * @param array $args Arguments for the method. + * + * @return mixed Result from the method invocation. + * @throws ReflectionException Error when dealing with reflection. + */ + private function invoke_protected( $object, $method, $args ) { + $class = new ReflectionClass( $object ); + $method = $class->getMethod( $method ); + $method->setAccessible( true ); + return $method->invokeArgs( $object, $args ); + } + + /** + * Invokes the get_filtered_term_product_counts method on an instance the widget, + * for a given filtering request, and returns the resulting counts. + * + * @param string $operator Operator in the filtering request. + * @param array $colors Slugs of the colors included in the filtering request. + * + * @return array An associative array where the keys are the color slugs and the values are the counts for each color. + * @throws ReflectionException Error when dealing with reflection to invoke the method. + */ + private function run_get_filtered_term_product_counts( $operator, $colors ) { + $sut = $this->get_widget( $operator, $colors ); + + $color_terms = get_terms( 'pa_color', array( 'hide_empty' => '1' ) ); + $color_term_ids = wp_list_pluck( $color_terms, 'term_id' ); + $color_term_names = wp_list_pluck( $color_terms, 'slug' ); + $color_names_by_id = array_combine( $color_term_ids, $color_term_names ); + + $counts = $this->invoke_protected( + $sut, + 'get_filtered_term_product_counts', + array( + $color_term_ids, + 'pa_color', + $operator, + ) + ); + + $counts_by_name = array(); + foreach ( $counts as $id => $count ) { + $counts_by_name[ $color_names_by_id[ $id ] ] = $count; + } + + return $counts_by_name; + } + + /** + * Changes the status of a post to 'draft'. + * + * @param int $post_id Id of the post to change. + */ + private function set_post_as_draft( $post_id ) { + global $wpdb; + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $wpdb->query( 'update ' . $wpdb->posts . " set post_status='draft' where ID=" . $post_id ); + } + + /** + * Data provider for test_product_count_per_attribute. + * + * @return array[] + */ + public function data_provider_for_test_product_count_per_attribute() { + return array( + // OR filtering, no attributes selected. + // Should count all the visible variations of all the products. + array( + 'or', + array(), + false, + array( + 'black' => 1, + 'brown' => 2, + 'blue' => 2, + 'green' => 2, + 'pink' => 1, + 'yellow' => 1, + ), + ), + + // OR filtering, some attributes selected + // (doesn't matter, the result is the same as in the previous case). + array( + 'or', + array( 'black', 'green' ), + false, + array( + 'black' => 1, + 'brown' => 2, + 'blue' => 2, + 'green' => 2, + 'pink' => 1, + 'yellow' => 1, + ), + ), + + // OR filtering, no attributes selected. Simple product is created too. + // Now it should include all the attributes of the simple product too. + array( + 'or', + array(), + true, + array( + 'black' => 2, + 'brown' => 3, + 'blue' => 3, + 'green' => 3, + 'pink' => 2, + 'yellow' => 2, + ), + ), + + // OR filtering, some attributes selected, Simple product is created too. + // Again, the attributes selected don't change the result. + array( + 'or', + array( 'black', 'green' ), + true, + array( + 'black' => 2, + 'brown' => 3, + 'blue' => 3, + 'green' => 3, + 'pink' => 2, + 'yellow' => 2, + ), + ), + + // AND filtering, no attributes selected. + // Should count all the visible variations of all the products as in the 'or' case. + array( + 'and', + array(), + false, + array( + 'black' => 1, + 'brown' => 2, + 'blue' => 2, + 'green' => 2, + 'pink' => 1, + 'yellow' => 1, + ), + ), + + // AND filtering, one attribute selected. + // Should count the visible variations for all products that have the variation for + // the selected attribute visible. + // E.g. 2 products have 'green' visible, and of those, one has also 'blue' + // and other has also 'pink' and 'yellow'. + array( + 'and', + array( 'green' ), + false, + array( + 'green' => 2, + 'blue' => 1, + 'pink' => 1, + 'yellow' => 1, + ), + ), + + // AND filtering, more than one attribute selected. + // Same as the previous one, but the products must have the variations for all selected attributes + // visible. + // E.g. only one product has both 'green' and 'pink' visible, and it has also 'yellow' visible. + array( + 'and', + array( 'green', 'pink' ), + false, + array( + 'green' => 1, + 'pink' => 1, + 'yellow' => 1, + ), + ), + + // AND filtering, no attributes selected, include simple product too. + // Same case as 'or': it should include all the attributes of the simple product too. + array( + 'and', + array(), + true, + array( + 'black' => 2, + 'brown' => 3, + 'blue' => 3, + 'green' => 3, + 'pink' => 2, + 'yellow' => 2, + ), + ), + + // AND filtering, select one attribute, include simple product too. + // The simple product is now included in all counters, since it has the selected attribute. + array( + 'and', + array( 'green' ), + true, + array( + 'black' => 1, + 'brown' => 1, + 'blue' => 2, + 'green' => 3, + 'pink' => 2, + 'yellow' => 2, + ), + ), + + // AND filtering, select a couple of attributes, include simple product too. + // The simple product is included too in all counter, since it has all of the selected attributes. + array( + 'and', + array( 'green', 'pink' ), + true, + array( + 'black' => 1, + 'brown' => 1, + 'blue' => 1, + 'green' => 2, + 'pink' => 2, + 'yellow' => 2, + ), + ), + ); + } + + /** + * @testdox Test that the counters are correct for different filtering combinations, see the data provider method for details. + * + * @dataProvider data_provider_for_test_product_count_per_attribute + * + * @param string $filter_operator Filtering operator to use, 'or' or 'and'. + * @param array $filter_terms Slugs of the colors selected for filtering. + * @param bool $create_simple_product_too If true, create one simple product too. If false, create only the variable products. + * @param array $expected_counts An associative array where the keys are the color slugs and the values are the counts for each color. + */ + public function test_product_count_per_attribute( $filter_operator, $filter_terms, $create_simple_product_too, $expected_counts ) { + if ( $create_simple_product_too ) { + $this->create_colored_product( 'Something with many colors', null ); + } + $this->create_colored_product( 'Big shoes', array( 'black', 'brown' ) ); + $this->create_colored_product( 'Medium shoes', array( 'blue', 'brown' ) ); + $this->create_colored_product( 'Small shoes', array( 'blue', 'green' ) ); + $this->create_colored_product( 'Kids shoes', array( 'green', 'pink', 'yellow' ) ); + + $counts = $this->run_get_filtered_term_product_counts( $filter_operator, $filter_terms ); + $this->assertEquals( $expected_counts, $counts ); + } + + /** + * @testdox When a variable product is not published, none of its variations should be included in the counts. + * + * @throws ReflectionException Error when dealing with reflection to invoke the tested method. + */ + public function test_product_count_per_attribute_with_parent_not_published() { + $this->create_colored_product( 'Big shoes', array( 'black', 'brown' ) ); + $medium = $this->create_colored_product( 'Medium shoes', array( 'blue', 'brown' ) ); + $this->set_post_as_draft( $medium->get_id() ); + + $actual = $this->run_get_filtered_term_product_counts( 'or', array() ); + + $expected = array( + 'black' => 1, + 'brown' => 1, + ); + $this->assertEquals( $expected, $actual ); + } + + /** + * @testdox When a variation is not published it should not be included in the counts (but other variations of the same product should). + * + * @throws ReflectionException Error when dealing with reflection to invoke the tested method. + */ + public function test_product_count_per_attribute_with_variation_not_published() { + $this->create_colored_product( 'Big shoes', array( 'black', 'brown' ) ); + $this->create_colored_product( 'Medium shoes', array( 'blue', 'brown' ), array( 'brown' ) ); + + $actual = $this->run_get_filtered_term_product_counts( 'or', array() ); + + $expected = array( + 'black' => 1, + 'brown' => 1, + 'blue' => 1, + ); + $this->assertEquals( $expected, $actual ); + } +} From 9142e27a193f1deaa18b2a30a2e1749fb74a69dc Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Thu, 14 May 2020 16:22:16 +0200 Subject: [PATCH 350/440] Adjustments in WC_Query::adjust_posts_count Two adjustments were needed: - Adjust the count even when there's no nav filtering in the query. This is necessary to present the proper products count. even when the woocommerce_product_is_visible filter is used. - Account for the case where $GLOBALS['wp_query']->posts returns objects instead of ids (for example when viewing a product page). --- includes/class-wc-query.php | 17 ++++---- .../util/class-wc-tests-wc-query.php | 40 ++++++++----------- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index 98338422ce8..7b1a56e8e1f 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -379,13 +379,10 @@ class WC_Query { * @return int Adjusted posts count. */ public function adjust_posts_count( $count ) { - if ( empty( $this->get_layered_nav_chosen_attributes_inst() ) ) { - return $count; - } - - $post_ids = $this->get_current_post_ids(); - $count = 0; - foreach ( $post_ids as $id ) { + $posts = $this->get_current_posts(); + $count = 0; + foreach ( $posts as $post ) { + $id = is_object( $post ) ? $post->ID : $post; $product = wc_get_product( $id ); if ( ! is_object( $product ) ) { continue; @@ -412,11 +409,11 @@ class WC_Query { } /** - * Get the ids of the posts found in the current WP loop. + * Get the posts (or the ids of the posts) found in the current WP loop. * - * @return array Array of post ids. + * @return array Array of posts or post ids. */ - protected function get_current_post_ids() { + protected function get_current_posts() { return $GLOBALS['wp_query']->posts; } diff --git a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php index 27d8184b129..a7e91f92f1e 100644 --- a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php +++ b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php @@ -442,10 +442,11 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { * Setup for a test for adjust_posts. * * @param bool $with_nav_filtering_data Should WC_Query::get_layered_nav_chosen_attributes return filtering data?. + * @param bool $use_objects If true, get_current_posts will return objects with an ID property; if false, it will returns the ids. * * @return array An array where the first element is the instance of WC_Query, and the second is an array of sample products created. */ - private function setup_adjust_posts_test( $with_nav_filtering_data ) { + private function setup_adjust_posts_test( $with_nav_filtering_data, $use_objects ) { update_option( 'woocommerce_hide_out_of_stock_items', 'yes' ); if ( $with_nav_filtering_data ) { @@ -455,46 +456,39 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { } $products = array(); - $product_ids = array(); + $posts = array(); for ( $i = 0; $i < 5; $i++ ) { $product = WC_Helper_Product::create_simple_product(); array_push( $products, $product ); - array_push( $product_ids, $product->get_id() ); + $post = $use_objects ? (object)['ID' => $product->get_id()] : $product->get_id(); + array_push( $posts, $post ); } $products[0]->set_stock_status( 'outofstock' ); $sut = $this ->getMockBuilder( WC_Query::class ) - ->setMethods( array( 'get_current_post_ids', 'get_layered_nav_chosen_attributes_inst' ) ) + ->setMethods( array( 'get_current_posts', 'get_layered_nav_chosen_attributes_inst' ) ) ->getMock(); - $sut->method( 'get_current_post_ids' )->willReturn( $product_ids ); + $sut->method( 'get_current_posts' )->willReturn( $posts ); $sut->method( 'get_layered_nav_chosen_attributes_inst' )->willReturn( $nav_filtering_data ); return array( $sut, $products ); } /** - * @testdox adjust_posts should do nothing when there are no nav filtering attributes in the request. + * @param bool $with_nav_filtering_data Should WC_Query::get_layered_nav_chosen_attributes return filtering data?. + * @param bool $use_objects If true, get_current_posts will return objects with an ID property; if false, it will returns the ids. + * + * @testdox adjust_posts should return the number of visible products and create product visibility loop variables + * @testWith [true, true] + * [false, false] + * [true, false] + * [false, true] */ - public function test_adjust_posts_count_without_nav_filtering_attributes() { - list($sut, $products) = $this->setup_adjust_posts_test( false ); - - $products[0]->set_stock_status( 'outofstock' ); - $products[0]->save(); - - $this->assertEquals( 34, $sut->adjust_posts_count( 34 ) ); - foreach ( $products as $product ) { - $this->assertNull( wc_get_loop_product_visibility( $product->get_id() ) ); - } - } - - /** - * @testdox adjust_posts should return the number of visible products, and create product visibility loop variables, then there are nav filtering attributes in the request. - */ - public function test_adjust_posts_count_with_nav_filtering_attributes() { - list($sut, $products) = $this->setup_adjust_posts_test( true ); + public function test_adjust_posts_count_with_nav_filtering_attributes( $with_nav_filtering_data, $use_objects ) { + list($sut, $products) = $this->setup_adjust_posts_test( $with_nav_filtering_data, $use_objects ); $products[0]->set_stock_status( 'outofstock' ); $products[0]->save(); From c074f085cccb45d10ebda9946bcd1a58cb0a5a04 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Fri, 5 Jun 2020 15:53:15 +0200 Subject: [PATCH 351/440] Remove two phpcs:ignores, improve code instead --- includes/abstracts/abstract-wc-product.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/includes/abstracts/abstract-wc-product.php b/includes/abstracts/abstract-wc-product.php index 4cf70ec1c8f..6109689ab33 100644 --- a/includes/abstracts/abstract-wc-product.php +++ b/includes/abstracts/abstract-wc-product.php @@ -2000,13 +2000,8 @@ class WC_Product extends WC_Abstract_Legacy_Product { public function get_price_suffix( $price = '', $qty = 1 ) { $html = ''; -<<<<<<< HEAD $suffix = get_option( 'woocommerce_price_display_suffix' ); if ( $suffix && wc_tax_enabled() && 'taxable' === $this->get_tax_status() ) { -======= - // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure, WordPress.CodeAnalysis.AssignmentInCondition.Found - if ( ( $suffix = get_option( 'woocommerce_price_display_suffix' ) ) && wc_tax_enabled() && 'taxable' === $this->get_tax_status() ) { ->>>>>>> cd077dfb6... Fix code sniffer errors in some files. if ( '' === $price ) { $price = $this->get_price(); } From 3fefe84a51af7b19364a5a93543c285926a49ce5 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Mon, 15 Jun 2020 14:58:48 +0200 Subject: [PATCH 352/440] Fix: WC_Query()::adjust_posts_count failing when posts list is null. --- includes/class-wc-query.php | 4 ++++ .../util/class-wc-tests-wc-query.php | 20 ++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index 7b1a56e8e1f..f369b1571f7 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -380,6 +380,10 @@ class WC_Query { */ public function adjust_posts_count( $count ) { $posts = $this->get_current_posts(); + if ( is_null( $posts ) ) { + return $count; + } + $count = 0; foreach ( $posts as $post ) { $id = is_object( $post ) ? $post->ID : $post; diff --git a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php index a7e91f92f1e..c918e7963a8 100644 --- a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php +++ b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php @@ -455,12 +455,12 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { $nav_filtering_data = array(); } - $products = array(); - $posts = array(); + $products = array(); + $posts = array(); for ( $i = 0; $i < 5; $i++ ) { $product = WC_Helper_Product::create_simple_product(); array_push( $products, $product ); - $post = $use_objects ? (object)['ID' => $product->get_id()] : $product->get_id(); + $post = $use_objects ? (object) array( 'ID' => $product->get_id() ) : $product->get_id(); array_push( $posts, $post ); } @@ -503,4 +503,18 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { $this->assertEquals( true, wc_get_loop_product_visibility( $product->get_id() ) ); } } + + /** + * @testdox adjust_posts should return the input unmodified if get_current_posts returns null. + */ + public function test_adjust_posts_count_when_there_are_no_posts() { + $sut = $this + ->getMockBuilder( WC_Query::class ) + ->setMethods( array( 'get_current_posts', 'get_layered_nav_chosen_attributes_inst' ) ) + ->getMock(); + + $sut->method( 'get_current_posts' )->willReturn( null ); + + $this->assertEquals( 34, $sut->adjust_posts_count( 34 ) ); + } } From 29843b93967aad7cad4b08747266c3045b87413a Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Thu, 9 Jul 2020 15:46:29 +0200 Subject: [PATCH 353/440] Change in the logic of is_visible_core for variable products Now, if there are filters present the logic is as follows: - For multiple filtering values of the same attribute: the product is visible if there's at least one variation that has one of the filtering values associated to the attribute, or if there's at least one variation having the attribute with a value of "Any". - For filtering by more than one attribute: the product is visible if there's at least one variation that is visible for ALL the attributes according to the above rule. Note that this is irrespective of the type of logic configured for the filter (OR or AND). --- includes/class-wc-product-variable.php | 103 +++++++--- .../helpers/class-wc-helper-product.php | 44 ++++- ...class-wc-tests-admin-duplicate-product.php | 18 +- tests/legacy/unit-tests/cart/cart.php | 19 +- .../legacy/unit-tests/product/data-store.php | 15 +- tests/legacy/unit-tests/product/functions.php | 10 +- .../unit-tests/product/product-variable.php | 177 ++++++++++++------ 7 files changed, 268 insertions(+), 118 deletions(-) diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index 5d3b33f6157..9a03eb1ee99 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -283,10 +283,11 @@ class WC_Product_Variable extends WC_Product { * Get an array of available variations for the current product. * * @param bool $render_variations Prepares a data array for each variant for output in the add to cart form. Pass `false` to only return the available variations as objects. - * @return array + * @param bool $return_array_of_data If true, return an array of data for the variation; if false, return a WC_Product_Variation object. + * + * @return array|WC_Product_Variation */ - public function get_available_variations( $render_variations = true ) { - + public function get_available_variations( $render_variations = true, $return_array_of_data = true ) { $variation_ids = $this->get_children(); $available_variations = array(); @@ -298,20 +299,18 @@ class WC_Product_Variable extends WC_Product { $variation = wc_get_product( $variation_id ); - // Hide out of stock variations if 'Hide out of stock items from the catalog' is checked. - if ( ! $variation || ! $variation->exists() || ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && ! $variation->is_in_stock() ) ) { - continue; - } - // Filter 'woocommerce_hide_invisible_variations' to optionally hide invisible variations (disabled variations and variations with empty price). if ( apply_filters( 'woocommerce_hide_invisible_variations', true, $this->get_id(), $variation ) && ! $variation->variation_is_visible() ) { continue; } - if ( $render_variations ) { - $available_variations[] = $this->get_available_variation( $variation ); - } else { + if ( ! $render_variations ) { $available_variations[] = $variation; + continue; + } + + if ( $this->variation_is_available( $variation ) ) { + $available_variations[] = $return_array_of_data ? $this->get_available_variation( $variation ) : $variation; } } @@ -322,6 +321,27 @@ class WC_Product_Variable extends WC_Product { return $available_variations; } + /** + * Check if a given variation is currently available. + * + * @param WC_Product_Variation $variation Variation to check. + * + * @return bool True if the variation is available, false otherwise. + */ + private function variation_is_available( WC_Product_Variation $variation ) { + // Hide out of stock variations if 'Hide out of stock items from the catalog' is checked. + if ( ! $variation || ! $variation->exists() || ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && ! $variation->is_in_stock() ) ) { + return false; + } + + // Filter 'woocommerce_hide_invisible_variations' to optionally hide invisible variations (disabled variations and variations with empty price). + if ( apply_filters( 'woocommerce_hide_invisible_variations', true, $this->get_id(), $variation ) && ! $variation->variation_is_visible() ) { + return false; + } + + return true; + } + /** * Returns an array of data for a variation. Used in the add to cart form. * @@ -589,29 +609,56 @@ class WC_Product_Variable extends WC_Product { /** * If there are attribute filters in the request, a variable product will be visible - * only if at least one of the corresponding variations is visible (for OR filtering) - * or if all of them are (for AND filtering). - * - * Note that for "Any..." variations the attribute value will be empty, these must be - * always included in the result and hence the '' === $value check. + * if at least one of the available variations matches the filters. */ - $filter_attribute = array_keys( $query_filters )[0]; - $temp = array_values( $query_filters )[0]; - $filter_values = $temp['terms']; - $filter_type = $temp['query_type']; + $attributes_with_terms = array(); + array_walk( + $query_filters, + function( $value, $key ) use ( &$attributes_with_terms ) { + $attributes_with_terms[ $key ] = $value['terms']; + } + ); - $attributes = array(); - foreach ( $this->get_available_variations() as $variation ) { - foreach ( $variation['attributes'] as $attribute => $value ) { - $attribute = substr( $attribute, strlen( 'attribute_' ) ); - if ( $attribute === $filter_attribute && ( '' === $value || in_array( $value, $filter_values, true ) ) && ! in_array( $value, $attributes, true ) ) { - array_push( $attributes, $value ); - } + $variations = $this->get_available_variations( false ); + foreach ( $variations as $variation ) { + if ( $this->variation_matches_filters( $variation, $attributes_with_terms ) ) { + return true; } } - return ( 'or' === $filter_type && count( $attributes ) > 0 ) || ( count( $attributes ) === count( $filter_values ) ); + return false; + } + + /** + * Checks if a given variation matches the active attribute filters. + * + * @param WC_Product_Variation $variation The variation to check. + * @param array $query_filters The active filters as an array of attribute_name => [term1, term2...]. + * + * @return bool True if the variation matches the active attribute filters. + */ + private function variation_matches_filters( WC_Product_Variation $variation, array $query_filters ) { + // Get the variation attributes as an array of attribute_name => attribute_value. + // The array_filter will filter out attributes having a value of '', these correspond + // to "Any..." variations that don't participate in filtering. + $variation_attributes = array_filter( $variation->get_variation_attributes( false ) ); + + $variation_attribute_names_in_filters = array_intersect( array_keys( $query_filters ), array_keys( $variation_attributes ) ); + if ( empty( $variation_attribute_names_in_filters ) ) { + // The variation doesn't have any attribute that participates in filtering so we consider it a match. + return true; + } + + foreach ( $variation_attribute_names_in_filters as $attribute_name ) { + if ( ! in_array( $variation_attributes[ $attribute_name ], $query_filters[ $attribute_name ], true ) ) { + // Multiple filters interact with AND logic, so as soon as one of them + // doesn't match then the variation doesn't match. + return false; + } + } + + return true; } /** diff --git a/tests/legacy/framework/helpers/class-wc-helper-product.php b/tests/legacy/framework/helpers/class-wc-helper-product.php index 2691c6ae804..a7556b46f3a 100644 --- a/tests/legacy/framework/helpers/class-wc-helper-product.php +++ b/tests/legacy/framework/helpers/class-wc-helper-product.php @@ -132,23 +132,25 @@ class WC_Helper_Product { $product->set_attributes( $attributes ); $product->save(); - $variation_1 = self::create_product_variation_object( + $variations = array(); + + $variations[] = self::create_product_variation_object( $product->get_id(), 'DUMMY SKU VARIABLE SMALL', 10, array( 'pa_size' => 'small' ) ); - $variation_2 = self::create_product_variation_object( + $variations[] = self::create_product_variation_object( $product->get_id(), 'DUMMY SKU VARIABLE LARGE', 15, array( 'pa_size' => 'large' ) ); - $variation_3 = self::create_product_variation_object( + $variations[] = self::create_product_variation_object( $product->get_id(), - 'DUMMY SKU VARIABLE RED 0', + 'DUMMY SKU VARIABLE HUGE RED 0', 16, array( 'pa_size' => 'huge', @@ -157,9 +159,9 @@ class WC_Helper_Product { ) ); - $variation_4 = self::create_product_variation_object( + $variations[] = self::create_product_variation_object( $product->get_id(), - 'DUMMY SKU VARIABLE RED 2', + 'DUMMY SKU VARIABLE HUGE RED 2', 17, array( 'pa_size' => 'huge', @@ -168,11 +170,39 @@ class WC_Helper_Product { ) ); + $variations[] = self::create_product_variation_object( + $product->get_id(), + 'DUMMY SKU VARIABLE HUGE BLUE 2', + 18, + array( + 'pa_size' => 'huge', + 'pa_colour' => 'blue', + 'pa_number' => '2', + ) + ); + + $variations[] = self::create_product_variation_object( + $product->get_id(), + 'DUMMY SKU VARIABLE HUGE BLUE ANY NUMBER', + 19, + array( + 'pa_size' => 'huge', + 'pa_colour' => 'blue', + 'pa_number' => '', + ) + ); + if ( $is_new_product ) { return wc_get_product( $product->get_id() ); } - $product->set_children( array( $variation_1->get_id(), $variation_2->get_id(), $variation_3->get_id(), $variation_4->get_id() ) ); + $variation_ids = array_map( + function( $variation ) { + return $variation->get_id(); + }, + $variations + ); + $product->set_children( $variation_ids ); return $product; } diff --git a/tests/legacy/unit-tests/admin/class-wc-tests-admin-duplicate-product.php b/tests/legacy/unit-tests/admin/class-wc-tests-admin-duplicate-product.php index aa1671d47a9..9b8972357ec 100644 --- a/tests/legacy/unit-tests/admin/class-wc-tests-admin-duplicate-product.php +++ b/tests/legacy/unit-tests/admin/class-wc-tests-admin-duplicate-product.php @@ -66,20 +66,20 @@ class WC_Tests_Admin_Duplicate_Product extends WC_Unit_Test_Case { array( 'dummy-variable-product-small-2', 'dummy-variable-product-large-2', - 'dummy-variable-product-3', - 'dummy-variable-product-4', - ), - array( - 'dummy-variable-product-small-3', - 'dummy-variable-product-large-3', 'dummy-variable-product-5', 'dummy-variable-product-6', ), + array( + 'dummy-variable-product-small-3', + 'dummy-variable-product-large-3', + 'dummy-variable-product-9', + 'dummy-variable-product-10', + ), array( 'dummy-variable-product-small-4', 'dummy-variable-product-large-4', - 'dummy-variable-product-7', - 'dummy-variable-product-8', + 'dummy-variable-product-13', + 'dummy-variable-product-14', ), ); @@ -88,7 +88,7 @@ class WC_Tests_Admin_Duplicate_Product extends WC_Unit_Test_Case { $duplicate_children = $duplicate->get_children(); - $this->assertEquals( 4, count( $duplicate_children ) ); + $this->assertEquals( 6, count( $duplicate_children ) ); foreach ( $slug_match as $key => $slug ) { $child = wc_get_product( $duplicate_children[ $key ] ); $this->assertEquals( $slug, $child->get_slug() ); diff --git a/tests/legacy/unit-tests/cart/cart.php b/tests/legacy/unit-tests/cart/cart.php index 8101bd79d4a..74e574a3368 100644 --- a/tests/legacy/unit-tests/cart/cart.php +++ b/tests/legacy/unit-tests/cart/cart.php @@ -2067,7 +2067,7 @@ class WC_Tests_Cart extends WC_Unit_Test_Case { update_option( 'woocommerce_tax_round_at_subtotal', 'yes' ); WC()->cart->empty_cart(); - $tax_rate = array( + $tax_rate = array( 'tax_rate_country' => '', 'tax_rate_state' => '', 'tax_rate' => '10.0000', @@ -2112,7 +2112,14 @@ class WC_Tests_Cart extends WC_Unit_Test_Case { $product = WC_Helper_Product::create_variation_product(); $variations = $product->get_available_variations(); - $variation = array_pop( $variations ); + $variation = current( + array_filter( + $variations, + function( $variation ) { + return 'DUMMY SKU VARIABLE HUGE RED 2' === $variation['sku']; + } + ) + ); // Add variation with add_to_cart_action. $_REQUEST['add-to-cart'] = $variation['variation_id']; @@ -2137,7 +2144,7 @@ class WC_Tests_Cart extends WC_Unit_Test_Case { $variation['variation_id'], array( 'attribute_pa_size' => 'huge', - 'attribute_pa_colour' => 'red', + 'attribute_pa_colour' => 'red', 'attribute_pa_number' => '2', ) ); @@ -2166,7 +2173,7 @@ class WC_Tests_Cart extends WC_Unit_Test_Case { $variation = array_pop( $variations ); // Attempt adding variation with add_to_cart_action, specifying a different colour. - $_REQUEST['add-to-cart'] = $variation['variation_id']; + $_REQUEST['add-to-cart'] = $variation['variation_id']; $_REQUEST['attribute_pa_colour'] = 'green'; WC_Form_Handler::add_to_cart_action( false ); $notices = WC()->session->get( 'wc_notices', array() ); @@ -2197,7 +2204,7 @@ class WC_Tests_Cart extends WC_Unit_Test_Case { $variation = array_shift( $variations ); // Attempt adding variation with add_to_cart_action, specifying attributes not defined in the variation. - $_REQUEST['add-to-cart'] = $variation['variation_id']; + $_REQUEST['add-to-cart'] = $variation['variation_id']; $_REQUEST['attribute_pa_colour'] = 'red'; $_REQUEST['attribute_pa_number'] = '1'; WC_Form_Handler::add_to_cart_action( false ); @@ -2231,7 +2238,7 @@ class WC_Tests_Cart extends WC_Unit_Test_Case { $variation = array_shift( $variations ); // Attempt adding variation with add_to_cart_action, without specifying attribute_pa_colour. - $_REQUEST['add-to-cart'] = $variation['variation_id']; + $_REQUEST['add-to-cart'] = $variation['variation_id']; $_REQUEST['attribute_pa_number'] = '0'; WC_Form_Handler::add_to_cart_action( false ); $notices = WC()->session->get( 'wc_notices', array() ); diff --git a/tests/legacy/unit-tests/product/data-store.php b/tests/legacy/unit-tests/product/data-store.php index b67ad8a4621..444ae97fc1a 100644 --- a/tests/legacy/unit-tests/product/data-store.php +++ b/tests/legacy/unit-tests/product/data-store.php @@ -216,29 +216,38 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case { $product = new WC_Product_Variable( $product->get_id() ); - $this->assertEquals( 4, count( $product->get_children() ) ); + $this->assertEquals( 6, count( $product->get_children() ) ); $expected_prices['price'][ $children[0] ] = 8.00; $expected_prices['price'][ $children[1] ] = 15.00; $expected_prices['price'][ $children[2] ] = 16.00; $expected_prices['price'][ $children[3] ] = 17.00; + $expected_prices['price'][ $children[4] ] = 18.00; + $expected_prices['price'][ $children[5] ] = 19.00; $expected_prices['regular_price'][ $children[0] ] = 10.00; $expected_prices['regular_price'][ $children[1] ] = 15.00; $expected_prices['regular_price'][ $children[2] ] = 16.00; $expected_prices['regular_price'][ $children[3] ] = 17.00; + $expected_prices['regular_price'][ $children[4] ] = 18.00; + $expected_prices['regular_price'][ $children[5] ] = 19.00; $expected_prices['sale_price'][ $children[0] ] = 8.00; $expected_prices['sale_price'][ $children[1] ] = 15.00; $expected_prices['sale_price'][ $children[2] ] = 16.00; $expected_prices['sale_price'][ $children[3] ] = 17.00; + $expected_prices['sale_price'][ $children[4] ] = 18.00; + $expected_prices['sale_price'][ $children[5] ] = 19.00; $this->assertEquals( $expected_prices, $product->get_variation_prices() ); $expected_attributes = array( 'pa_size' => array( 'small', 'large', 'huge' ), - 'pa_colour' => array( 'red' ), - 'pa_number' => array( '0', '2' ), + 'pa_colour' => array( + 0 => 'red', + 2 => 'blue', + ), + 'pa_number' => array( '0', '1', '2' ), ); $this->assertEquals( $expected_attributes, $product->get_variation_attributes() ); } diff --git a/tests/legacy/unit-tests/product/functions.php b/tests/legacy/unit-tests/product/functions.php index f731c96e879..6146b414418 100644 --- a/tests/legacy/unit-tests/product/functions.php +++ b/tests/legacy/unit-tests/product/functions.php @@ -5,9 +5,9 @@ * @since 2.3 */ - /** - * WC_Tests_Product_Functions class. - */ +/** + * WC_Tests_Product_Functions class. + */ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { /** @@ -70,7 +70,7 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { 'type' => 'variation', ) ); - $this->assertCount( 4, $products ); + $this->assertCount( 6, $products ); // Test parent. $products = wc_get_products( @@ -80,7 +80,7 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case { 'parent' => $variation->get_id(), ) ); - $this->assertCount( 4, $products ); + $this->assertCount( 6, $products ); // Test parent_exclude. $products = wc_get_products( diff --git a/tests/legacy/unit-tests/product/product-variable.php b/tests/legacy/unit-tests/product/product-variable.php index 48d0feeba10..66de936995c 100644 --- a/tests/legacy/unit-tests/product/product-variable.php +++ b/tests/legacy/unit-tests/product/product-variable.php @@ -180,55 +180,51 @@ class WC_Tests_Product_Variable extends WC_Unit_Test_Case { /** * Setup for a test for is_visible. * - * @param array $terms Terms for the "size" attribute that will be supplied as layered nav filtering. - * @param string $query_type Logical operation for the nav filtering, "or" or "and". - * @param bool $hide_out_of_stock_products Should the woocommerce_hide_out_of_stock_items option be set?. - * @param bool $is_visible_from_parent Return value of is_visible from base class. + * @param array $filtering_attributes Simulated filtering attributes as an array of attribute_name => [term1, term2...]. + * @param bool $hide_out_of_stock_products Should the woocommerce_hide_out_of_stock_items option be set?. + * @param bool $is_visible_from_parent Return value of is_visible from base class. * * @return WC_Product_Variable A properly configured instance of WC_Product_Variable to test. */ - private function prepare_visibility_test( $terms, $query_type, $hide_out_of_stock_products = true, $is_visible_from_parent = true ) { - if ( empty( $terms ) ) { - $layered_nav_chosen_attributes = array(); - } else { - $layered_nav_chosen_attributes = array( - 'pa_size' => array( - 'terms' => $terms, - 'query_type' => $query_type, - ), - ); + private function prepare_visibility_test( $filtering_attributes, $hide_out_of_stock_products = true, $is_visible_from_parent = true ) { + foreach ( $filtering_attributes as $attribute_name => $terms ) { + $filtering_attributes[ $attribute_name ]['query_type'] = 'ANY_QUERY_TYPE'; + $filtering_attributes[ $attribute_name ]['terms'] = $terms; } - if ( $hide_out_of_stock_products ) { - update_option( 'woocommerce_hide_out_of_stock_items', 'yes' ); - } + update_option( 'woocommerce_hide_out_of_stock_items', $hide_out_of_stock_products ? 'yes' : 'no' ); $sut = $this ->getMockBuilder( WC_Product_Variable::class ) ->setMethods( array( 'parent_is_visible_core', 'get_layered_nav_chosen_attributes' ) ) ->getMock(); - $sut = WC_Helper_Product::create_variation_product( $sut ); + $sut = WC_Helper_Product::create_variation_product( $sut, true ); $sut->save(); $sut->method( 'parent_is_visible_core' )->willReturn( $is_visible_from_parent ); - $sut->method( 'get_layered_nav_chosen_attributes' )->willReturn( $layered_nav_chosen_attributes ); + $sut->method( 'get_layered_nav_chosen_attributes' )->willReturn( $filtering_attributes ); return $sut; } /** - * Configure the stock status for the "size" attribute-based variations of a product. + * Configure the stock status for the attribute-based variations of a product. * * @param WC_Product_Variable $product Product with the variations to configure. - * @param array $size_names Terms whose variations will have stock, all others won't have. + * @param array $attributes An array of attribute_name => [attribute_values], only the matching variations will have stock. */ - private function set_size_variations_with_stock( $product, $size_names ) { + private function set_variations_with_stock( $product, $attributes ) { $variation_ids = $product->get_children(); foreach ( $variation_ids as $id ) { - $variation = wc_get_product( $id ); - $size = $variation->get_attribute( 'pa_size' ); - $variation->set_stock_status( in_array( $size, $size_names, true ) ? 'instock' : 'outofstock' ); + $variation = wc_get_product( $id ); + $attribute_matches = true; + foreach ( $attributes as $name => $values ) { + if ( ! in_array( $variation->get_attribute( $name ), $values, true ) ) { + $attribute_matches = false; + } + } + $variation->set_stock_status( $attribute_matches ? 'instock' : 'outofstock' ); $variation->save(); } } @@ -250,7 +246,7 @@ class WC_Tests_Product_Variable extends WC_Unit_Test_Case { public function test_is_visible_when_no_filtering_supplied_and_at_least_one_variation_has_stock() { $sut = $this->prepare_visibility_test( array(), '' ); - $this->set_size_variations_with_stock( $sut, array( 'small' ) ); + $this->set_variations_with_stock( $sut, array( 'pa_size' => array( 'small' ) ) ); $this->assertTrue( $sut->is_visible() ); } @@ -258,60 +254,121 @@ class WC_Tests_Product_Variable extends WC_Unit_Test_Case { /** * @testdox Test product visibility when the variation requested in nav filtering has no stock, result depends on woocommerce_hide_out_of_stock_items option. * - * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. - * @param string $query_type "or" or "and". - * @param bool $expected_visibility Expected value of is_visible for the tested product. + * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. + * @param bool $expected_visibility Expected value of is_visible for the tested product. * - * @testWith [true, "or", false] - * [false, "or", true] - * [true, "and", false] - * [false, "and", true] + * @testWith [true, false] + * [false, true] */ - public function test_visibility_when_supplied_filter_has_no_stock( $hide_out_of_stock, $query_type, $expected_visibility ) { - $sut = $this->prepare_visibility_test( array( 'large' ), $query_type, $hide_out_of_stock ); + public function test_visibility_when_supplied_filter_has_no_stock( $hide_out_of_stock, $expected_visibility ) { + $sut = $this->prepare_visibility_test( array( 'pa_size' => array( 'large' ) ), $hide_out_of_stock ); - $this->set_size_variations_with_stock( $sut, array( 'small' ) ); + $this->set_variations_with_stock( $sut, array( 'pa_size' => array( 'small' ) ) ); $this->assertEquals( $expected_visibility, $sut->is_visible() ); } /** - * @testdox Test product visibility when only one of the variations requested in nav filtering has stock, result depends on woocommerce_hide_out_of_stock_items option and query type. + * @testdox Product should always be visible when only one of the variations requested in nav filtering has stock. * - * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. - * @param string $query_type "or" or "and". - * @param bool $expected_visibility Expected value of is_visible for the tested product. + * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. * - * @testWith [true, "or", true] - * [false, "or", true] - * [true, "and", false] - * [false, "and", true] + * @testWith [true] + * [false] */ - public function test_visibility_when_multiple_filters_supplied_and_only_one_has_stock( $hide_out_of_stock, $query_type, $expected_visibility ) { - $sut = $this->prepare_visibility_test( array( 'small', 'large' ), $query_type, $hide_out_of_stock ); + public function test_visibility_when_multiple_filter_values_supplied_and_only_one_has_stock( $hide_out_of_stock ) { + $sut = $this->prepare_visibility_test( array( 'pa_size' => array( 'small', 'large' ) ), $hide_out_of_stock ); - $this->set_size_variations_with_stock( $sut, array( 'small' ) ); + $this->set_variations_with_stock( $sut, array( 'pa_size' => array( 'small' ) ) ); - $this->assertEquals( $expected_visibility, $sut->is_visible() ); + $this->assertTrue( $sut->is_visible() ); } /** - * @testdox Product should always be visible when all of the variations requested in nav filtering have stock. + * @testdox Product should be visible when all of the variations requested in nav filtering have stock. * - * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. - * @param string $query_type "or" or "and". - * @param bool $expected_visibility Expected value of is_visible for the tested product. + * @param bool $hide_out_of_stock Value for woocommerce_hide_out_of_stock_items. * - * @testWith [true, "or", true] - * [false, "or", true] - * [true, "and", true] - * [false, "and", true] + * @testWith [true] + * [false] */ - public function test_visibility_when_multiple_filters_supplied_and_all_of_them_have_stock( $hide_out_of_stock, $query_type, $expected_visibility ) { - $sut = $this->prepare_visibility_test( array( 'small', 'large' ), $query_type, $hide_out_of_stock ); + public function test_visibility_when_multiple_filter_values_supplied_and_all_of_them_have_stock( $hide_out_of_stock ) { + $sut = $this->prepare_visibility_test( array( 'pa_size' => array( 'small', 'large' ) ), $hide_out_of_stock ); - $this->set_size_variations_with_stock( $sut, array( 'small', 'large' ) ); + $this->set_variations_with_stock( $sut, array( 'pa_size' => array( 'small', 'large' ) ) ); - $this->assertEquals( $expected_visibility, $sut->is_visible() ); + $this->assertTrue( $sut->is_visible() ); + } + + /** + * @testdox Product should be visible when multiple filters are present, and there's a variation matching all of them. + */ + public function test_visibility_when_multiple_filters_are_used_and_all_of_them_match() { + $sut = $this->prepare_visibility_test( + array( + 'pa_size' => array( 'huge' ), + 'pa_colour' => array( 'blue' ), + ), + true + ); + + $this->set_variations_with_stock( + $sut, + array( + 'pa_size' => array( 'huge' ), + 'pa_colour' => array( 'blue' ), + 'pa_number' => array( '2' ), + ) + ); + + $this->assertTrue( $sut->is_visible() ); + } + + /** + * @testdox Product should not be visible when multiple filters are present, and there are no variations matching all of them. + */ + public function test_visibility_when_multiple_filters_are_used_and_one_of_them_does_not_match() { + $sut = $this->prepare_visibility_test( + array( + 'pa_size' => array( 'small', 'huge' ), + 'pa_colour' => array( 'red' ), + ), + true + ); + + $this->set_variations_with_stock( + $sut, + array( + 'pa_size' => array( 'huge' ), + 'pa_colour' => array( 'blue' ), + 'pa_number' => array( '2' ), + ) + ); + + $this->assertFalse( $sut->is_visible() ); + } + + /** + * @testdox Attributes having "Any..." as value should not count when searching for matching attributes. + */ + public function test_visibility_when_multiple_filters_are_used_and_an_attribute_has_any_value() { + $sut = $this->prepare_visibility_test( + array( + 'pa_size' => array( 'huge' ), + 'pa_number' => array( '34' ), + ), + true + ); + + $this->set_variations_with_stock( + $sut, + array( + 'pa_size' => array( 'huge' ), + 'pa_colour' => array( 'blue' ), + 'pa_number' => array( '' ), + ) + ); + + $this->assertTrue( $sut->is_visible() ); } } From e9d692f4552633aa99685f6e50fb59ad8e12c9a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor=20Soriano?= Date: Thu, 9 Jul 2020 16:47:14 +0200 Subject: [PATCH 354/440] Apply suggestions from code review Mostly adding "since 4.4.0" annotations and updating db update functions from 4.2 to 4.4. Co-authored-by: Claudio Sanches --- includes/class-wc-install.php | 6 +++--- includes/class-wc-product-variation.php | 2 +- includes/class-wc-query.php | 7 ++++--- .../class-wc-product-variable-data-store-cpt.php | 2 +- includes/wc-template-functions.php | 7 +++---- includes/wc-update-functions.php | 6 +++--- includes/widgets/class-wc-widget-layered-nav.php | 5 +++++ 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index 81852351601..9a58422fbaa 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -149,9 +149,9 @@ class WC_Install { 'wc_update_400_reset_action_scheduler_migration_status', 'wc_update_400_db_version', ), - '4.2.0' => array( - 'wc_update_420_insert_attribute_terms_for_variable_products', - 'wc_update_420_db_version', + '4.4.0' => array( + 'wc_update_440_insert_attribute_terms_for_variable_products', + 'wc_update_440_db_version', ), ); diff --git a/includes/class-wc-product-variation.php b/includes/class-wc-product-variation.php index e3e6cf04a66..f574ba1fd01 100644 --- a/includes/class-wc-product-variation.php +++ b/includes/class-wc-product-variation.php @@ -587,7 +587,7 @@ class WC_Product_Variation extends WC_Product_Simple { /** * Delete variation, set the ID to 0, and return result. * - * @since 2.6.0 + * @since 4.4.0 * @param bool $force_delete Should the variation be deleted permanently. * @return bool result */ diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index f369b1571f7..d5920d9b868 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -374,6 +374,7 @@ class WC_Query { * * We also cache the post visibility so that it isn't checked again when displaying the posts list. * + * @since 4.4.0 * @param int $count Original posts count, as supplied by the found_posts filter. * * @return int Adjusted posts count. @@ -728,11 +729,11 @@ class WC_Query { $product_visibility_not_in[] = $product_visibility_terms['outofstock']; } - // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + // phpcs:disable WordPress.Security.NonceVerification.Recommended // Filter by rating. if ( isset( $_GET['rating_filter'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized - $rating_filter = array_filter( array_map( 'absint', explode( ',', $_GET['rating_filter'] ) ) ); + $rating_filter = array_filter( array_map( 'absint', explode( ',', wp_unslash( $_GET['rating_filter'] ) ) ) ); $rating_terms = array(); for ( $i = 1; $i <= 5; $i ++ ) { if ( in_array( $i, $rating_filter, true ) && isset( $product_visibility_terms[ 'rated-' . $i ] ) ) { @@ -749,7 +750,7 @@ class WC_Query { ); } } - // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + // phpcs:enable WordPress.Security.NonceVerification.Recommended if ( ! empty( $product_visibility_not_in ) ) { $tax_query[] = array( diff --git a/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/includes/data-stores/class-wc-product-variable-data-store-cpt.php index a6e8a3781e2..dd2c2b16bbe 100644 --- a/includes/data-stores/class-wc-product-variable-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variable-data-store-cpt.php @@ -200,7 +200,7 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple $values = array(); } - // Empty value inicates that all options for given attribute are available. + // Empty value indicates that all options for given attribute are available. if ( in_array( null, $values, true ) || in_array( '', $values, true ) || empty( $values ) ) { $values = $attribute['is_taxonomy'] ? wc_get_object_terms( $product->get_id(), $attribute['name'], 'slug' ) : wc_get_text_attributes( $attribute['value'] ); // Get custom attributes (non taxonomy) as defined. diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 6c7e4e7a25c..93c1280e28f 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -8,8 +8,6 @@ * @version 2.5.0 */ -// phpcs:disable Generic.Commenting.Todo.TaskFound - use Automattic\Jetpack\Constants; defined( 'ABSPATH' ) || exit; @@ -241,6 +239,7 @@ function wc_set_loop_prop( $prop, $value = '' ) { /** * Set the current visbility for a product in the woocommerce_loop global. * + * @since 4.4.0 * @param int $product_id Product it to cache visbiility for. * @param bool $value The poduct visibility value to cache. */ @@ -251,6 +250,7 @@ function wc_set_loop_product_visibility( $product_id, $value ) { /** * Gets the cached current visibility for a product from the woocommerce_loop global. * + * @since 4.4.0 * @param int $product_id Product id to get the cached visibility for. * * @return bool|null The cached product visibility, or null if on visibility has been cached for that product. @@ -731,9 +731,8 @@ function wc_product_class( $class = '', $product_id = null ) { */ function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '', $return = false ) { if ( is_null( $values ) ) { - // phpcs:disable WordPress.Security.NonceVerification.Recommended + // phpcs:ignore WordPress.Security.NonceVerification.Recommended $values = $_GET; - // phpcs:enable WordPress.Security.NonceVerification.Recommended } elseif ( is_string( $values ) ) { $url_parts = wp_parse_url( $values ); $values = array(); diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index c57bb7d4d1a..076aa177b14 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2136,7 +2136,7 @@ function wc_update_400_db_version() { * * @return bool true if there are more products to process. */ -function wc_update_420_insert_attribute_terms_for_variable_products() { +function wc_update_440_insert_attribute_terms_for_variable_products() { $state_option_name = 'woocommerce_' . __FUNCTION__ . '_state'; $page = intval( get_option( $state_option_name, 1 ) ); @@ -2172,6 +2172,6 @@ function wc_update_420_insert_attribute_terms_for_variable_products() { /** * Update DB version. */ -function wc_update_420_db_version() { - WC_Install::update_db_version( '4.2.0' ); +function wc_update_440_db_version() { + WC_Install::update_db_version( '4.4.0' ); } diff --git a/includes/widgets/class-wc-widget-layered-nav.php b/includes/widgets/class-wc-widget-layered-nav.php index 4f6a693ab82..1519b16ff43 100644 --- a/includes/widgets/class-wc-widget-layered-nav.php +++ b/includes/widgets/class-wc-widget-layered-nav.php @@ -485,6 +485,7 @@ class WC_Widget_Layered_Nav extends WC_Widget { /** * Wrapper for WC_Query::get_main_tax_query() to ease unit testing. * + * @since 4.4.0 * @return array */ protected function get_main_tax_query() { @@ -494,6 +495,7 @@ class WC_Widget_Layered_Nav extends WC_Widget { /** * Wrapper for WC_Query::get_main_search_query_sql() to ease unit testing. * + * @since 4.4.0 * @return string */ protected function get_main_search_query_sql() { @@ -503,6 +505,7 @@ class WC_Widget_Layered_Nav extends WC_Widget { /** * Wrapper for WC_Query::get_main_search_queryget_main_meta_query to ease unit testing. * + * @since 4.4.0 * @return array */ protected function get_main_meta_query() { @@ -513,6 +516,7 @@ class WC_Widget_Layered_Nav extends WC_Widget { * Get a tax query SQL for a given set of taxonomy, terms and operator. * Uses an intermediate WP_Tax_Query object. * + * @since 4.4.0 * @param string $taxonomy Taxonomy name. * @param array $terms Terms to include in the query. * @param string $operator Query operator, as supported by WP_Tax_Query; e.g. "NOT IN". @@ -536,6 +540,7 @@ class WC_Widget_Layered_Nav extends WC_Widget { /** * Convert a tax query array to SQL using an intermediate WP_Tax_Query object. * + * @since 4.4.0 * @param array $query Query array in the same format accepted by WP_Tax_Query constructor. * * @return array Query SQL as returned by WP_Tax_Query->get_sql. From 681401850a37204e36f80b511cba36647acb1a6f Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Mon, 13 Jul 2020 15:00:02 +0200 Subject: [PATCH 355/440] Adjustments in the items count calculation on the nav filtering widget. The calculations are now consistent with the change made to the visibility of the variable products when using one or multiple filters. --- .../widgets/class-wc-widget-layered-nav.php | 60 ++------- .../class-wc-tests-widget-layered-nav.php | 116 ++++++++++++++---- 2 files changed, 99 insertions(+), 77 deletions(-) diff --git a/includes/widgets/class-wc-widget-layered-nav.php b/includes/widgets/class-wc-widget-layered-nav.php index 1519b16ff43..ea8e65c6265 100644 --- a/includes/widgets/class-wc-widget-layered-nav.php +++ b/includes/widgets/class-wc-widget-layered-nav.php @@ -347,24 +347,18 @@ class WC_Widget_Layered_Nav extends WC_Widget { $main_tax_query = $this->get_main_tax_query(); $meta_query = $this->get_main_meta_query(); - $variable_tax_query_sql = array( 'where' => '' ); $non_variable_tax_query_sql = array( 'where' => '' ); - - $is_and_query = 'and' === $query_type; + $is_and_query = 'and' === $query_type; foreach ( $main_tax_query as $key => $query ) { if ( is_array( $query ) && $taxonomy === $query['taxonomy'] ) { if ( $is_and_query ) { $non_variable_tax_query_sql = $this->convert_tax_query_to_sql( array( $query ) ); - $variable_tax_query_sql = $this->get_extra_tax_query_sql( $taxonomy, $query['terms'], 'IN' ); - $selected_terms_count = count( $query['terms'] ); } unset( $main_tax_query[ $key ] ); } } - $needs_extra_query_for_variable_products = $is_and_query && isset( $selected_terms_count ); - $exclude_variable_products_tax_query_sql = $this->get_extra_tax_query_sql( 'product_type', array( 'variable' ), 'NOT IN' ); $meta_query_sql = ( new WP_Meta_Query( $meta_query ) )->get_sql( 'post', $wpdb->posts, 'ID' ); @@ -376,20 +370,18 @@ class WC_Widget_Layered_Nav extends WC_Widget { $query['select'] = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) as term_count, terms.term_id as term_count_id"; $query['from'] = "FROM {$wpdb->posts}"; $query['join'] = " - INNER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id + INNER JOIN {$wpdb->term_relationships} AS tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id ) INNER JOIN {$wpdb->terms} AS terms USING( term_id ) {$main_tax_query_sql['join']} {$meta_query_sql['join']}"; // Not an omission, really no more JOINs required. - $variable_where_part = " - {$wpdb->posts}.post_type = 'product_variation' + $variable_where_part = " + OR ({$wpdb->posts}.post_type = 'product_variation' AND NOT EXISTS ( SELECT ID FROM {$wpdb->posts} AS parent WHERE parent.ID = {$wpdb->posts}.post_parent AND parent.post_status NOT IN ('publish') - ) - {$variable_tax_query_sql['where']} + )) "; - $variable_where_part_for_main_query = $needs_extra_query_for_variable_products ? '' : "OR ($variable_where_part)"; $search_sql = ''; $search = $this->get_main_search_query_sql(); @@ -407,7 +399,7 @@ class WC_Widget_Layered_Nav extends WC_Widget { {$exclude_variable_products_tax_query_sql['where']} {$non_variable_tax_query_sql['where']} ) - {$variable_where_part_for_main_query} + {$variable_where_part} ) AND terms.term_id IN {$term_ids_sql} {$search_sql}"; @@ -434,44 +426,8 @@ class WC_Widget_Layered_Nav extends WC_Widget { if ( ! isset( $cached_counts[ $query_hash ] ) ) { // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared - $results = $wpdb->get_results( $query_sql, ARRAY_A ); - $counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) ); - if ( $needs_extra_query_for_variable_products ) { - /** - * This query: - * 1. Finds out how many variable products have variations corresponding to all the attributes - * supplied in the filtering request (all the variations must be visible). - * 2. Then, it returns the term_taxonomy_id of all the visible variations for all the products - * found in the previous step. - * - * Each term_taxonomy_id is returned as many times as it's found, this is required for the proper - * generation of the counts. - */ - $variable_count_query_sql = " - SELECT term_taxonomy_id FROM {$wpdb->term_relationships} - INNER JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id - where {$wpdb->posts}.post_parent in ( - SELECT {$wpdb->posts}.post_parent FROM {$wpdb->posts} - {$query['join']} - WHERE - {$wpdb->posts}.post_status = 'publish' - {$main_tax_query_sql['where']} {$meta_query_sql['where']} - AND ( - {$variable_where_part} - ) - - {$variable_tax_query_sql['where']} - GROUP BY post_parent HAVING COUNT(1)>={$selected_terms_count} - ) - AND term_taxonomy_id IN {$term_ids_sql} - {$main_tax_query_sql['where']} - "; - $term_ids_result = $wpdb->get_results( $variable_count_query_sql, ARRAY_N ); - foreach ( $term_ids_result as $result ) { - $term_id = $result[0]; - $counts[ $term_id ] = array_key_exists( $term_id, $counts ) ? $counts[ $term_id ] + 1 : 1; - } - } + $results = $wpdb->get_results( $query_sql, ARRAY_A ); + $counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) ); $cached_counts[ $query_hash ] = $counts; if ( true === $cache ) { set_transient( 'wc_layered_nav_counts_' . sanitize_title( $taxonomy ), $cached_counts, DAY_IN_SECONDS ); diff --git a/tests/unit-tests/widgets/class-wc-tests-widget-layered-nav.php b/tests/unit-tests/widgets/class-wc-tests-widget-layered-nav.php index feda88bd059..bd0a84daa37 100644 --- a/tests/unit-tests/widgets/class-wc-tests-widget-layered-nav.php +++ b/tests/unit-tests/widgets/class-wc-tests-widget-layered-nav.php @@ -15,10 +15,11 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { * * @param string $filter_operation Operation supplied in the filter, 'or' or 'and'. * @param array $filter_colors Slugs of the colors supplied in the filters. + * @param array $filter_styles Slugs of the styles supplied in the filters. * * @return WC_Widget_Layered_Nav An instance of WC_Widget_Layered_Nav ready to test. */ - private function get_widget( $filter_operation, $filter_colors = array() ) { + private function get_widget( $filter_operation, $filter_colors = array(), $filter_styles = array() ) { $tax_query = array( 'relation' => 'and', 0 => array( @@ -44,6 +45,18 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { ); } + if ( ! empty( $filter_styles ) ) { + array_push( + $tax_query, + array( + 'taxonomy' => 'pa_style', + 'terms' => $filter_styles, + 'field' => 'slug', + 'operator' => $filter_operation, + ) + ); + } + $sut = $this ->getMockBuilder( WC_Widget_Layered_Nav::class ) ->setMethods( array( 'get_main_tax_query', 'get_main_meta_query', 'get_main_search_query_sql' ) ) @@ -63,10 +76,11 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { * @param string $name Name of the product. * @param array $colors_in_stock Slugs of the colors whose variations will have stock. If null, a simple product is created. * @param array $colors_disabled Slugs of the colors whose variations will be disabled, N/A for a simple product. + * @param array $styles Array where the key is the colors and the value is the style that will have the variation for that color. * * @return WC_Product_Simple|WC_Product_Variable The created product. */ - private function create_colored_product( $name, $colors_in_stock, $colors_disabled = array() ) { + private function create_colored_product( $name, $colors_in_stock, $colors_disabled = array(), $styles = array() ) { $create_as_simple = is_null( $colors_in_stock ); $main_product = $create_as_simple ? new WC_Product_Simple() : new WC_Product_Variable(); @@ -78,7 +92,11 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { ); $existing_colors = array( 'black', 'brown', 'blue', 'green', 'pink', 'yellow' ); - $attributes = array( WC_Helper_Product::create_product_attribute_object( 'color', $existing_colors ) ); + $existing_styles = array( 'classic', 'sport' ); + $attributes = array( + WC_Helper_Product::create_product_attribute_object( 'color', $existing_colors ), + WC_Helper_Product::create_product_attribute_object( 'style', $existing_styles ), + ); $main_product->set_attributes( $attributes ); $main_product->save(); @@ -88,11 +106,15 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { $variation_objects = array(); foreach ( $existing_colors as $color ) { - $variation_object = WC_Helper_Product::create_product_variation_object( + $variation_attributes = array( + 'pa_color' => $color, + 'pa_style' => array_key_exists( $color, $styles ) ? $styles[ $color ] : '', + ); + $variation_object = WC_Helper_Product::create_product_variation_object( $main_product->get_id(), "SKU for $color $name", 10, - array( 'pa_color' => $color ) + $variation_attributes ); if ( ! in_array( $color, $colors_in_stock, true ) ) { $variation_object->set_stock_status( 'outofstock' ); @@ -139,12 +161,13 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { * * @param string $operator Operator in the filtering request. * @param array $colors Slugs of the colors included in the filtering request. + * @param array $styles Array where the key is the colors and the value is the style that will have the variation for that color. * * @return array An associative array where the keys are the color slugs and the values are the counts for each color. * @throws ReflectionException Error when dealing with reflection to invoke the method. */ - private function run_get_filtered_term_product_counts( $operator, $colors ) { - $sut = $this->get_widget( $operator, $colors ); + private function run_get_filtered_term_product_counts( $operator, $colors, $styles = array() ) { + $sut = $this->get_widget( $operator, $colors, $styles ); $color_terms = get_terms( 'pa_color', array( 'hide_empty' => '1' ) ); $color_term_ids = wp_list_pluck( $color_terms, 'term_id' ); @@ -269,32 +292,32 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { ), // AND filtering, one attribute selected. - // Should count the visible variations for all products that have the variation for - // the selected attribute visible. - // E.g. 2 products have 'green' visible, and of those, one has also 'blue' - // and other has also 'pink' and 'yellow'. + // Should still count the visible variations for all products as in the 'or' case. array( 'and', array( 'green' ), false, array( + 'black' => 1, + 'brown' => 2, + 'blue' => 2, 'green' => 2, - 'blue' => 1, 'pink' => 1, 'yellow' => 1, ), ), // AND filtering, more than one attribute selected. - // Same as the previous one, but the products must have the variations for all selected attributes - // visible. - // E.g. only one product has both 'green' and 'pink' visible, and it has also 'yellow' visible. + // Should still count the visible variations for all products as in the 'or' case. array( 'and', array( 'green', 'pink' ), false, array( - 'green' => 1, + 'black' => 1, + 'brown' => 2, + 'blue' => 2, + 'green' => 2, 'pink' => 1, 'yellow' => 1, ), @@ -317,15 +340,15 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { ), // AND filtering, select one attribute, include simple product too. - // The simple product is now included in all counters, since it has the selected attribute. + // Again, the simple product is now included in all counters, since it has the selected attribute. array( 'and', array( 'green' ), true, array( - 'black' => 1, - 'brown' => 1, - 'blue' => 2, + 'black' => 2, + 'brown' => 3, + 'blue' => 3, 'green' => 3, 'pink' => 2, 'yellow' => 2, @@ -333,16 +356,16 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { ), // AND filtering, select a couple of attributes, include simple product too. - // The simple product is included too in all counter, since it has all of the selected attributes. + // The simple product is still included too in all counters, since it has all of the selected attributes. array( 'and', array( 'green', 'pink' ), true, array( - 'black' => 1, - 'brown' => 1, - 'blue' => 1, - 'green' => 2, + 'black' => 2, + 'brown' => 3, + 'blue' => 3, + 'green' => 3, 'pink' => 2, 'yellow' => 2, ), @@ -373,6 +396,49 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case { $this->assertEquals( $expected_counts, $counts ); } + /** + * @testdox Test that the counters are correct when using more than one filter simultaneously. + * + */ + public function test_product_count_per_multiple_attributes() { + $this->create_colored_product( 'Big shoes', array( 'black', 'brown' ) ); + $this->create_colored_product( + 'Medium shoes', + array( 'blue', 'brown' ), + array(), + array( + 'blue' => 'sport', + 'brown' => 'classic', + ) + ); + $this->create_colored_product( + 'Small shoes', + array( 'blue', 'green' ), + array(), + array( + 'blue' => 'classic', + 'green' => 'sport', + ) + ); + $this->create_colored_product( + 'Kids shoes', + array( 'green', 'pink', 'yellow', 'blue' ), + array(), + array( + 'green' => 'classic', + 'blue' => 'classic', + ) + ); + + $counts = $this->run_get_filtered_term_product_counts( 'IN', array( 'blue' ), array( 'classic' ) ); + $expected_counts = array( + 'brown' => 1, + 'blue' => 2, + 'green' => 1, + ); + $this->assertEquals( $expected_counts, $counts ); + } + /** * @testdox When a variable product is not published, none of its variations should be included in the counts. * From 2283a4c7fd8f271f603ebb1905b999ed0a94a254 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 14 Jul 2020 09:59:09 +0200 Subject: [PATCH 356/440] Revert woocommerce_product_loop to use have_posts instead of wc_get_loop_prop( 'total' ). --- includes/wc-template-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 93c1280e28f..6009d37cdc8 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -268,7 +268,7 @@ function wc_get_loop_product_visibility( $product_id ) { * @return bool */ function woocommerce_product_loop() { - return wc_get_loop_prop( 'total' ) > 0 || 'products' !== woocommerce_get_loop_display_mode(); + return have_posts() || 'products' !== woocommerce_get_loop_display_mode(); } /** From bc7085b3c45cf1e542e941fbd52fd7ad537efa8f Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 28 Jul 2020 09:15:17 +0200 Subject: [PATCH 357/440] Fixes after rebasing. - Fix a call to get_available_variations with incorrect optional arguments. - Add code that has been removed in WC_Product_Variable::get_available_variations. --- includes/class-wc-product-variable.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index 9a03eb1ee99..fe9b1e4416c 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -299,18 +299,20 @@ class WC_Product_Variable extends WC_Product { $variation = wc_get_product( $variation_id ); + // Hide out of stock variations if 'Hide out of stock items from the catalog' is checked. + if ( ! $variation || ! $variation->exists() || ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && ! $variation->is_in_stock() ) ) { + continue; + } + // Filter 'woocommerce_hide_invisible_variations' to optionally hide invisible variations (disabled variations and variations with empty price). if ( apply_filters( 'woocommerce_hide_invisible_variations', true, $this->get_id(), $variation ) && ! $variation->variation_is_visible() ) { continue; } - if ( ! $render_variations ) { - $available_variations[] = $variation; - continue; - } - - if ( $this->variation_is_available( $variation ) ) { + if ( $render_variations ) { $available_variations[] = $return_array_of_data ? $this->get_available_variation( $variation ) : $variation; + } else { + $available_variations[] = $variation; } } @@ -620,7 +622,7 @@ class WC_Product_Variable extends WC_Product { } ); - $variations = $this->get_available_variations( false ); + $variations = $this->get_available_variations( true, false ); foreach ( $variations as $variation ) { if ( $this->variation_matches_filters( $variation, $attributes_with_terms ) ) { return true; From 5e787f836b65e116f1d9fa492e9c0d38a23b8a81 Mon Sep 17 00:00:00 2001 From: Timmy Crawford Date: Mon, 27 Jul 2020 18:18:09 -0700 Subject: [PATCH 358/440] Update woocommerce-admin package to 1.4.0-beta.2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5f28d3e43d0..735f6b31afb 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "maxmind-db/reader": "1.6.0", "pelago/emogrifier": "^3.1", "woocommerce/action-scheduler": "3.1.6", - "woocommerce/woocommerce-admin": "1.4.0-beta.1", + "woocommerce/woocommerce-admin": "1.4.0-beta.2", "woocommerce/woocommerce-blocks": "3.0.0", "woocommerce/woocommerce-rest-api": "1.0.11" }, From 393dbb71249f5b885aee213b176aea300d78dc2b Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 28 Jul 2020 10:09:33 +0200 Subject: [PATCH 359/440] Update composer.lock --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 437dbdce245..86e533b23ec 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8c1f82c00b53093f703e7cecd4e9895c", + "content-hash": "877625af18978cccd2d02780fbd11842", "packages": [ { "name": "automattic/jetpack-autoloader", @@ -554,16 +554,16 @@ }, { "name": "woocommerce/woocommerce-admin", - "version": "v1.4.0-beta.1", + "version": "v1.4.0-beta.2", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-admin.git", - "reference": "9fb6f4167020e1b45c57040b782797a7055a0e95" + "reference": "8c1818854b0188ae636d2a4d065865196e26e002" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/9fb6f4167020e1b45c57040b782797a7055a0e95", - "reference": "9fb6f4167020e1b45c57040b782797a7055a0e95", + "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/8c1818854b0188ae636d2a4d065865196e26e002", + "reference": "8c1818854b0188ae636d2a4d065865196e26e002", "shasum": "" }, "require": { @@ -597,7 +597,7 @@ ], "description": "A modern, javascript-driven WooCommerce Admin experience.", "homepage": "https://github.com/woocommerce/woocommerce-admin", - "time": "2020-07-22T01:44:35+00:00" + "time": "2020-07-28T00:28:40+00:00" }, { "name": "woocommerce/woocommerce-blocks", From ac501dea6453dc1128997aad175729b344685190 Mon Sep 17 00:00:00 2001 From: budzanowski Date: Tue, 28 Jul 2020 11:37:51 +0200 Subject: [PATCH 360/440] Don't request empty locales list for plugin translations. --- includes/admin/helper/class-wc-helper-updater.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/includes/admin/helper/class-wc-helper-updater.php b/includes/admin/helper/class-wc-helper-updater.php index 430fbae027e..89f4c3a048a 100644 --- a/includes/admin/helper/class-wc-helper-updater.php +++ b/includes/admin/helper/class-wc-helper-updater.php @@ -191,6 +191,11 @@ class WC_Helper_Updater { $locales = apply_filters( 'plugins_update_check_locales', $locales ); $locales = array_unique( $locales ); + // No locales, means that the respone will be empty. + if ( empty( $locales ) ) { + return array(); + } + // Scan local plugins which may or may not have a subscription. $plugins = WC_Helper::get_local_woo_plugins(); $active_woo_plugins = array_intersect( array_keys( $plugins ), get_option( 'active_plugins', array() ) ); From 57aeff0a717b7fffea5721ec8badd8a282e7db5f Mon Sep 17 00:00:00 2001 From: budzanowski Date: Tue, 28 Jul 2020 11:49:01 +0200 Subject: [PATCH 361/440] Update comment. --- includes/admin/helper/class-wc-helper-updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/helper/class-wc-helper-updater.php b/includes/admin/helper/class-wc-helper-updater.php index 89f4c3a048a..62941f3f734 100644 --- a/includes/admin/helper/class-wc-helper-updater.php +++ b/includes/admin/helper/class-wc-helper-updater.php @@ -191,7 +191,7 @@ class WC_Helper_Updater { $locales = apply_filters( 'plugins_update_check_locales', $locales ); $locales = array_unique( $locales ); - // No locales, means that the respone will be empty. + // No locales, the respone will be empty, we can return now. if ( empty( $locales ) ) { return array(); } From 7d80474b6049c3b511da967405bf8b34d235e156 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Tue, 28 Jul 2020 08:29:48 -0700 Subject: [PATCH 362/440] Updated the `composer.lock` for re-release of woocommerce/woocommerce-admin@1.4.0-beta.2 --- composer.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.lock b/composer.lock index 86e533b23ec..e892be8c841 100644 --- a/composer.lock +++ b/composer.lock @@ -558,12 +558,12 @@ "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-admin.git", - "reference": "8c1818854b0188ae636d2a4d065865196e26e002" + "reference": "d56ac35bbb62bda2c981443932e7f90b0f6dbe99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/8c1818854b0188ae636d2a4d065865196e26e002", - "reference": "8c1818854b0188ae636d2a4d065865196e26e002", + "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/d56ac35bbb62bda2c981443932e7f90b0f6dbe99", + "reference": "d56ac35bbb62bda2c981443932e7f90b0f6dbe99", "shasum": "" }, "require": { From ae5bd1e14fc8009cb3592b507413c9d02e53f14b Mon Sep 17 00:00:00 2001 From: Joel Rowley Date: Tue, 28 Jul 2020 12:04:39 -0400 Subject: [PATCH 363/440] Add file path to woocommerce_file_download_method filter --- includes/class-wc-download-handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index b956d945424..7ae3695de40 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -214,7 +214,7 @@ class WC_Download_Handler { } $filename = apply_filters( 'woocommerce_file_download_filename', $filename, $product_id ); - $file_download_method = apply_filters( 'woocommerce_file_download_method', get_option( 'woocommerce_file_download_method', 'force' ), $product_id ); + $file_download_method = apply_filters( 'woocommerce_file_download_method', get_option( 'woocommerce_file_download_method', 'force' ), $product_id, $file_path ); // Add action to prevent issues in IE. add_action( 'nocache_headers', array( __CLASS__, 'ie_nocache_headers_fix' ) ); From 008e41170b42ca1b8e68520da065708466be5dfb Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 28 Jul 2020 15:13:00 -0300 Subject: [PATCH 364/440] Improved UX to highlight order data when there's some refund --- assets/css/admin.scss | 4 ++++ .../meta-boxes/views/html-order-items.php | 24 +++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/assets/css/admin.scss b/assets/css/admin.scss index 316f99eafa4..dd4344e2ee3 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -1412,6 +1412,10 @@ ul.wc_coupon_list_block { .refunded-total { color: $red; } + + .label-highlight { + font-weight: bold; + } } .refund-actions { diff --git a/includes/admin/meta-boxes/views/html-order-items.php b/includes/admin/meta-boxes/views/html-order-items.php index d35c4d966c4..034d08eeb87 100644 --- a/includes/admin/meta-boxes/views/html-order-items.php +++ b/includes/admin/meta-boxes/views/html-order-items.php @@ -213,19 +213,23 @@ if ( wc_tax_enabled() ) { - + + + + +
    ::
    - get_total(); - if ( $order->get_total_refunded() ) { - $total_paid_by_customer -= $order->get_total_refunded(); - } - - echo wc_price( $total_paid_by_customer, array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - ?> + get_total(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
    + + get_date_paid()->date_i18n( get_option( 'date_format' ) ), $order->get_payment_method_title() ) ); + ?> + +

    @@ -243,7 +247,7 @@ if ( wc_tax_enabled() ) { get_id() ); ?> - : + : get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> From 61abc7caab2e72dde276e304d99958a3cbaa26a5 Mon Sep 17 00:00:00 2001 From: Joel Rowley Date: Tue, 28 Jul 2020 14:28:15 -0400 Subject: [PATCH 365/440] Add dockblock to the woocommerce_file_download_method filter Co-authored-by: Claudio Sanches --- includes/class-wc-download-handler.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index 7ae3695de40..ff0a82efeff 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -214,6 +214,13 @@ class WC_Download_Handler { } $filename = apply_filters( 'woocommerce_file_download_filename', $filename, $product_id ); + /** + * Filter download method. + * + * @param string $method Download method. + * @param int $product_id Product ID. + * @param string $file_path URL to file. + */ $file_download_method = apply_filters( 'woocommerce_file_download_method', get_option( 'woocommerce_file_download_method', 'force' ), $product_id, $file_path ); // Add action to prevent issues in IE. From 7531d308ca4b4a1ca628eead42b9d09fca237630 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 28 Jul 2020 15:31:08 -0300 Subject: [PATCH 366/440] Included lerna.json to the .distignore file --- .distignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.distignore b/.distignore index cbeeef597c5..eb33c4ac00f 100644 --- a/.distignore +++ b/.distignore @@ -14,6 +14,7 @@ contributors.html docker-compose.yaml Dockerfile Gruntfile.js +lerna.json none package-lock.json package.json From 4d4b9e3432af9a78ebf0da7ec1d6adb396f3e683 Mon Sep 17 00:00:00 2001 From: xristos3490 Date: Wed, 29 Jul 2020 18:21:36 +0300 Subject: [PATCH 367/440] Filter found_posts only on wc_query context --- includes/class-wc-query.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index d5920d9b868..496024c0911 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -45,7 +45,7 @@ class WC_Query { add_action( 'parse_request', array( $this, 'parse_request' ), 0 ); add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); add_filter( 'the_posts', array( $this, 'remove_product_query_filters' ) ); - add_filter( 'found_posts', array( $this, 'adjust_posts_count' ) ); + add_filter( 'found_posts', array( $this, 'adjust_posts_count' ), 10, 2 ); add_filter( 'get_pagenum_link', array( $this, 'remove_add_to_cart_pagination' ), 10, 1 ); } $this->init_query_vars(); @@ -379,7 +379,12 @@ class WC_Query { * * @return int Adjusted posts count. */ - public function adjust_posts_count( $count ) { + public function adjust_posts_count( $count, $query ) { + + if ( ! $query->get( 'wc_query' ) ) { + return $count; + } + $posts = $this->get_current_posts(); if ( is_null( $posts ) ) { return $count; From 6485fc337c21ddd4130d5eaeab5adf3f0bf553f6 Mon Sep 17 00:00:00 2001 From: xristos3490 Date: Wed, 29 Jul 2020 18:30:26 +0300 Subject: [PATCH 368/440] Add docblock param --- includes/class-wc-query.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index 496024c0911..783c0e5ab0f 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -376,6 +376,7 @@ class WC_Query { * * @since 4.4.0 * @param int $count Original posts count, as supplied by the found_posts filter. + * @param WP_Query $query The current WP_Query object. * * @return int Adjusted posts count. */ From 97c7937fd979a10fc0ce1c1ed4328e9d70349379 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 19:12:02 -0300 Subject: [PATCH 369/440] Fixed "Product type" dropdown on WP 5.5 WP 5.5 doesn't introduce a tag inside metaboxes headings --- assets/css/admin.scss | 28 +++++++++++++++++++++------ assets/js/admin/meta-boxes-product.js | 6 +++++- includes/admin/class-wc-admin.php | 5 +++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/assets/css/admin.scss b/assets/css/admin.scss index 316f99eafa4..b5c4d7f188f 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -4347,14 +4347,13 @@ img.help_tip { span { display: block; - vertical-align: middle; line-height: 24px; + } - span { - display: inline; - line-height: inherit; - vertical-align: baseline; - } + .type_box { + display: inline; + line-height: inherit; + vertical-align: baseline; } select { @@ -6819,6 +6818,23 @@ table.bar_chart { } } +.wc-wp-version-gte-55 { + + #woocommerce-product-data { + + .hndle { + display: block; + line-height: 24px; + + .type_box { + display: inline; + line-height: inherit; + vertical-align: baseline; + } + } + } +} + /** * Select2 colors for built-in admin color themes. */ diff --git a/assets/js/admin/meta-boxes-product.js b/assets/js/admin/meta-boxes-product.js index efbae1dbf4d..488344f687d 100644 --- a/assets/js/admin/meta-boxes-product.js +++ b/assets/js/admin/meta-boxes-product.js @@ -27,7 +27,11 @@ jQuery( function( $ ) { }); // Type box. - $( '.type_box' ).appendTo( '#woocommerce-product-data .hndle span' ); + if ( $( 'body' ).hasClass( 'wc-wp-version-gte-55' ) ) { + $( '.type_box' ).appendTo( ' #woocommerce-product-data .hndle' ); + } else { + $( '.type_box' ).appendTo( ' #woocommerce-product-data .hndle span' ); + } $( function() { // Prevent inputs in meta box headings opening/closing contents. diff --git a/includes/admin/class-wc-admin.php b/includes/admin/class-wc-admin.php index 6932f817ca5..8a9d6e8bd43 100644 --- a/includes/admin/class-wc-admin.php +++ b/includes/admin/class-wc-admin.php @@ -331,6 +331,11 @@ class WC_Admin { $classes .= ' wc-wp-version-gte-53'; } + // Add WP 5.5+ compatibility class. + if ( $raw_version && version_compare( $version, '5.5', '>=' ) ) { + $classes .= ' wc-wp-version-gte-55'; + } + return $classes; } } From 94f8d2d5765204ac8bb69151fa983f1d8c741702 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 19:21:24 -0300 Subject: [PATCH 370/440] Fixed jQuery selector --- assets/js/admin/meta-boxes-product.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/admin/meta-boxes-product.js b/assets/js/admin/meta-boxes-product.js index 488344f687d..d54284dd766 100644 --- a/assets/js/admin/meta-boxes-product.js +++ b/assets/js/admin/meta-boxes-product.js @@ -28,9 +28,9 @@ jQuery( function( $ ) { // Type box. if ( $( 'body' ).hasClass( 'wc-wp-version-gte-55' ) ) { - $( '.type_box' ).appendTo( ' #woocommerce-product-data .hndle' ); + $( '.type_box' ).appendTo( '#woocommerce-product-data .hndle' ); } else { - $( '.type_box' ).appendTo( ' #woocommerce-product-data .hndle span' ); + $( '.type_box' ).appendTo( '#woocommerce-product-data .hndle span' ); } $( function() { From d498341f0e850e3d18a88937df24d04e72b09893 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 20:37:12 -0300 Subject: [PATCH 371/440] Added function to get current admin page --- includes/admin/wc-admin-functions.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index 57b9b31cb6b..faf7d045637 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -474,3 +474,21 @@ function wc_render_invalid_variation_notice( $product_object ) { Date: Wed, 29 Jul 2020 20:37:27 -0300 Subject: [PATCH 372/440] Return to the current page after enabled or disabling db update notices --- includes/admin/notes/class-wc-notes-run-db-update.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/admin/notes/class-wc-notes-run-db-update.php b/includes/admin/notes/class-wc-notes-run-db-update.php index 4d64fc6c7e8..fe54d107a7f 100644 --- a/includes/admin/notes/class-wc-notes-run-db-update.php +++ b/includes/admin/notes/class-wc-notes-run-db-update.php @@ -111,7 +111,7 @@ class WC_Notes_Run_Db_Update { private static function update_needed_notice( $note_id = null ) { $update_url = html_entity_decode( wp_nonce_url( - add_query_arg( 'do_update_woocommerce', 'true', admin_url( 'admin.php?page=wc-settings' ) ), + add_query_arg( 'do_update_woocommerce', 'true', wc_get_current_admin_page() ), 'wc_db_update', 'wc_db_update_nonce' ) @@ -210,7 +210,7 @@ class WC_Notes_Run_Db_Update { add_query_arg( 'wc-hide-notice', 'update', - admin_url( 'admin.php?page=wc-settings' ) + wc_get_current_admin_page() ), 'woocommerce_hide_notices_nonce', '_wc_notice_nonce' From c9f52a45eb37ceb2313fb56fccf31d176534e5aa Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 20:52:36 -0300 Subject: [PATCH 373/440] New wc_get_current_admin_url() function --- includes/admin/notes/class-wc-notes-run-db-update.php | 4 ++-- includes/admin/wc-admin-functions.php | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/includes/admin/notes/class-wc-notes-run-db-update.php b/includes/admin/notes/class-wc-notes-run-db-update.php index fe54d107a7f..8cdbfbe3d83 100644 --- a/includes/admin/notes/class-wc-notes-run-db-update.php +++ b/includes/admin/notes/class-wc-notes-run-db-update.php @@ -111,7 +111,7 @@ class WC_Notes_Run_Db_Update { private static function update_needed_notice( $note_id = null ) { $update_url = html_entity_decode( wp_nonce_url( - add_query_arg( 'do_update_woocommerce', 'true', wc_get_current_admin_page() ), + add_query_arg( 'do_update_woocommerce', 'true', wc_get_current_admin_url() ? wc_get_current_admin_url() : admin_url( 'admin.php?page=wc-settings' ) ), 'wc_db_update', 'wc_db_update_nonce' ) @@ -210,7 +210,7 @@ class WC_Notes_Run_Db_Update { add_query_arg( 'wc-hide-notice', 'update', - wc_get_current_admin_page() + wc_get_current_admin_url() ? wc_get_current_admin_url() : admin_url( 'admin.php?page=wc-settings' ) ), 'woocommerce_hide_notices_nonce', '_wc_notice_nonce' diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index faf7d045637..64505f4d8c6 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -476,18 +476,20 @@ function wc_render_invalid_variation_notice( $product_object ) { } /** - * Get current admin page or WooCommerce settings page. + * Get current admin page URL. + * + * Returns an empty string if it cannot generate a URL. * * @internal * @since 4.4.0 * @return string */ -function wc_get_current_admin_page() { +function wc_get_current_admin_url() { $uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; $uri = str_replace( '/wp-admin', '', $uri ); if ( ! $uri ) { - return admin_url( 'admin.php?page=wc-settings' ); + return ''; } return remove_query_arg( array( '_wpnonce', '_wc_notice_nonce', 'wc_db_update', 'wc_db_update_nonce' ), admin_url( $uri ) ); From a464b7aeabe967d0d5a051378a996e0cb56fc874 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 21:01:39 -0300 Subject: [PATCH 374/440] Improved wc_get_current_admin_url() - Replace "/wp-admin" with regex like on WP core. - Remove "wc-hide-notice" from query args. --- includes/admin/wc-admin-functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index 64505f4d8c6..d5990e40eeb 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -486,11 +486,11 @@ function wc_render_invalid_variation_notice( $product_object ) { */ function wc_get_current_admin_url() { $uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; - $uri = str_replace( '/wp-admin', '', $uri ); + $uri = preg_replace( '|^.*/wp-admin/|i', '', $uri ); if ( ! $uri ) { return ''; } - return remove_query_arg( array( '_wpnonce', '_wc_notice_nonce', 'wc_db_update', 'wc_db_update_nonce' ), admin_url( $uri ) ); + return remove_query_arg( array( '_wpnonce', '_wc_notice_nonce', 'wc_db_update', 'wc_db_update_nonce', 'wc-hide-notice' ), admin_url( $uri ) ); } From 3c1132e274f42e142c9e86213b666b6e11b54745 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 21:02:52 -0300 Subject: [PATCH 375/440] Added unit tests for wc_get_current_admin_url() --- .../admin/wc-admin-functions-test.php | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/php/includes/admin/wc-admin-functions-test.php diff --git a/tests/php/includes/admin/wc-admin-functions-test.php b/tests/php/includes/admin/wc-admin-functions-test.php new file mode 100644 index 00000000000..3910dac8b50 --- /dev/null +++ b/tests/php/includes/admin/wc-admin-functions-test.php @@ -0,0 +1,44 @@ +plugin_dir . '/includes/admin/wc-admin-functions.php'; + } + + /** + * Test wc_get_current_admin_url() function. + */ + public function test_wc_get_current_admin_url() { + // Since REQUEST_URI is empty on unit tests it should return an empty string. + if ( empty( $_SERVER['REQUEST_URI'] ) ) { + $this->assertEquals( '', wc_get_current_admin_url() ); + } + + // Test with REQUEST_URI. + $default_uri = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $_SERVER['REQUEST_URI'] = '/wp-admin/admin.php?page=wc-admin&foo=bar'; + $this->assertEquals( admin_url( 'admin.php?page=wc-admin&foo=bar' ), wc_get_current_admin_url() ); + + // Test if nonce gets removed. + $_SERVER['REQUEST_URI'] = '/wp-admin/admin.php?page=wc-admin&_wpnonce=xxxxxxxxxxxx'; + $this->assertEquals( admin_url( 'admin.php?page=wc-admin' ), wc_get_current_admin_url() ); + + // Restore REQUEST_URI. + $_SERVER['REQUEST_URI'] = $default_uri; + } +} From edaf71b11591912ff6981a4d547abe28957fc1ff Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 22:04:44 -0300 Subject: [PATCH 376/440] Remove new WP 5.5 meta box arrows --- assets/css/admin.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/css/admin.scss b/assets/css/admin.scss index 316f99eafa4..a9388aa057e 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -1062,6 +1062,7 @@ ul.wc_coupon_list_block { #woocommerce-order-data { + .postbox-header, .hndle, .handlediv { display: none; @@ -1466,6 +1467,7 @@ ul.wc_coupon_list_block { display: block !important; } + .postbox-header, .hndle, .handlediv { display: none; From 5b48191eacaab8c5a42a95500d9da882f0571f52 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 23:07:00 -0300 Subject: [PATCH 377/440] Batch update coupons --- includes/class-wc-install.php | 1 + includes/wc-update-functions.php | 56 ++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index 9f36a10493e..a44d97f0afa 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -154,6 +154,7 @@ class WC_Install { 'wc_update_440_db_version', ), '4.5.0' => array( + 'wc_update_450_get_coupons', 'wc_update_450_sanitize_coupons_code', 'wc_update_450_db_version', ), diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 8d13109b43c..ab2500ef384 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2183,27 +2183,57 @@ function wc_update_450_db_version() { WC_Install::update_db_version( '4.5.0' ); } +/** + * Get coupons to update in the DB. + */ +function wc_update_450_get_coupons() { + global $wpdb; + + $coupons = $wpdb->get_results( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_type = 'shop_coupon';", ARRAY_A ); + + update_option( 'woocommerce_update_350_coupons', $coupons ); +} + /** * Sanitize all coupons code. + * + * @return bool True to run again, false if completed. */ function wc_update_450_sanitize_coupons_code() { global $wpdb; - $coupons = $wpdb->get_results( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_type = 'shop_coupon';" ); + $coupons = array_filter( (array) get_option( 'woocommerce_update_350_coupons', array() ) ); - if ( $coupons ) { - foreach ( $coupons as $data ) { - $code = trim( wp_filter_kses( $data->post_title ) ); + if ( empty( $coupons ) ) { + delete_option( 'woocommerce_update_350_coupons' ); + return false; + } - if ( ! empty( $code ) ) { - $wpdb->query( - $wpdb->prepare( - "UPDATE {$wpdb->posts} SET post_title = %s WHERE ID = %d", - $code, - $data->ID - ) - ); - } + // Batch 10 coupons for each run. + $batch_coupons = array_slice( $coupons, 0, 10, true ); + + foreach ( $batch_coupons as $key => $data ) { + $code = trim( wp_filter_kses( $data['post_title'] ) ); + + if ( ! empty( $code ) ) { + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->posts} SET post_title = %s WHERE ID = %d", + $code, + $data['ID'] + ) + ); + + // Remove items from the list. + unset( $coupons[ $key ] ); } } + + // Start the run again if there's still any coupon. + if ( ! empty( $coupons ) ) { + return update_option( 'woocommerce_update_350_coupons', $coupons ); + } + + delete_option( 'woocommerce_update_350_coupons' ); + return false; } From bb131ace69e9f057df25b0647f3f138444a0d252 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 29 Jul 2020 23:14:50 -0300 Subject: [PATCH 378/440] Clean cache --- includes/wc-update-functions.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index ab2500ef384..7e1262847ce 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2224,6 +2224,10 @@ function wc_update_450_sanitize_coupons_code() { ) ); + // Clean cache. + clean_post_cache( intval( $data['ID'] ) ); + wp_cache_delete( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $data['post_title'], 'coupons' ); + // Remove items from the list. unset( $coupons[ $key ] ); } From 86c88f1750e019a76aee2cdf772534eeacf6c325 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Thu, 30 Jul 2020 09:32:28 +0200 Subject: [PATCH 379/440] Fix: incorrect adjustment of post count in WC_Query. PR #26260 introduced a handler for 'found_posts' filter in WC_Query class in order to adjust the count depending on the visibility of variation products. However the handler incorrectly assumed that the filter was triggered only when listing products, when actually it's also triggered for any post type e.g. pages. In these cases the post count was set to zero, which caused bugs. Now the handler starts with the originally supplied posts count, and only decrements it when a post is a product AND is not visible. --- includes/class-wc-query.php | 21 ++++++++------ .../util/class-wc-tests-wc-query.php | 28 +++++++++++++++---- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index d5920d9b868..65e625b7681 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -368,8 +368,9 @@ class WC_Query { } /** - * When the request is filtering by attributes via layered nav plugin we need to adjust the total posts count - * to account for variable products having stock in some variations but not in others. + * When we are listing products and the request is filtering by attributes via layered nav plugin + * we need to adjust the total posts count to account for variable products having stock + * in some variations but not in others. * We do that by just checking if each product is visible. * * We also cache the post visibility so that it isn't checked again when displaying the posts list. @@ -385,18 +386,22 @@ class WC_Query { return $count; } - $count = 0; foreach ( $posts as $post ) { - $id = is_object( $post ) ? $post->ID : $post; - $product = wc_get_product( $id ); + if ( is_object( $post ) && 'product' !== $post->post_type ) { + continue; + } + + $product_id = is_object( $post ) ? $post->ID : $post; + $product = wc_get_product( $product_id ); if ( ! is_object( $product ) ) { continue; } + if ( $product->is_visible() ) { - wc_set_loop_product_visibility( $id, true ); - $count++; + wc_set_loop_product_visibility( $product_id, true ); } else { - wc_set_loop_product_visibility( $id, false ); + wc_set_loop_product_visibility( $product_id, false ); + $count--; } } diff --git a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php index c918e7963a8..9482797c4ab 100644 --- a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php +++ b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php @@ -441,12 +441,13 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { /** * Setup for a test for adjust_posts. * - * @param bool $with_nav_filtering_data Should WC_Query::get_layered_nav_chosen_attributes return filtering data?. - * @param bool $use_objects If true, get_current_posts will return objects with an ID property; if false, it will returns the ids. + * @param bool $with_nav_filtering_data Should WC_Query::get_layered_nav_chosen_attributes return filtering data?. + * @param bool $use_objects If true, get_current_posts will return objects with an ID property; if false, it will returns the ids. + * @param string $post_type The value of the 'post_type' property for the objects generated when $use_objects is true. * * @return array An array where the first element is the instance of WC_Query, and the second is an array of sample products created. */ - private function setup_adjust_posts_test( $with_nav_filtering_data, $use_objects ) { + private function setup_adjust_posts_test( $with_nav_filtering_data, $use_objects, $post_type = 'product' ) { update_option( 'woocommerce_hide_out_of_stock_items', 'yes' ); if ( $with_nav_filtering_data ) { @@ -460,7 +461,10 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { for ( $i = 0; $i < 5; $i++ ) { $product = WC_Helper_Product::create_simple_product(); array_push( $products, $product ); - $post = $use_objects ? (object) array( 'ID' => $product->get_id() ) : $product->get_id(); + $post = $use_objects ? (object) array( + 'ID' => $product->get_id(), + 'post_type' => $post_type, + ) : $product->get_id(); array_push( $posts, $post ); } @@ -495,8 +499,8 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { $products[1]->set_stock_status( 'outofstock' ); $products[1]->save(); - $this->assertEquals( 3, $sut->adjust_posts_count( 34 ) ); - $this->assertEquals( 3, wc_get_loop_prop( 'total' ) ); + $this->assertEquals( 32, $sut->adjust_posts_count( 34 ) ); + $this->assertEquals( 32, wc_get_loop_prop( 'total' ) ); $this->assertEquals( false, wc_get_loop_product_visibility( $products[0]->get_id() ) ); $this->assertEquals( false, wc_get_loop_product_visibility( $products[1]->get_id() ) ); foreach ( array_slice( $products, 2 ) as $product ) { @@ -517,4 +521,16 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { $this->assertEquals( 34, $sut->adjust_posts_count( 34 ) ); } + + /** + * @testdox adjust_posts should return the input unmodified if the posts do not represent products. + */ + public function test_adjust_posts_count_when_the_posts_are_not_products() { + list($sut, $products) = $this->setup_adjust_posts_test( true, true, 'page' ); + + $products[0]->set_stock_status( 'outofstock' ); + $products[0]->save(); + + $this->assertEquals( 34, $sut->adjust_posts_count( 34 ) ); + } } From ba4afe633cd010929ce85de54a0aeb2db7b13bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Thu, 30 Jul 2020 11:07:19 +0200 Subject: [PATCH 380/440] Update woocommerce/woocommerce-blocks to v3.1.0 --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 735f6b31afb..2e6a85b6242 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "pelago/emogrifier": "^3.1", "woocommerce/action-scheduler": "3.1.6", "woocommerce/woocommerce-admin": "1.4.0-beta.2", - "woocommerce/woocommerce-blocks": "3.0.0", + "woocommerce/woocommerce-blocks": "3.1.0", "woocommerce/woocommerce-rest-api": "1.0.11" }, "require-dev": { diff --git a/composer.lock b/composer.lock index e892be8c841..2d66c29f127 100644 --- a/composer.lock +++ b/composer.lock @@ -597,20 +597,20 @@ ], "description": "A modern, javascript-driven WooCommerce Admin experience.", "homepage": "https://github.com/woocommerce/woocommerce-admin", - "time": "2020-07-28T00:28:40+00:00" + "time": "2020-07-28T15:18:55+00:00" }, { "name": "woocommerce/woocommerce-blocks", - "version": "v3.0.0", + "version": "v3.1.0", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git", - "reference": "cc00da60f21a7219e7e5ef5599996c68fee7b2be" + "reference": "d8fdcb4fc90c392e672b0e75bb0b7fd81dac7436" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/cc00da60f21a7219e7e5ef5599996c68fee7b2be", - "reference": "cc00da60f21a7219e7e5ef5599996c68fee7b2be", + "url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/d8fdcb4fc90c392e672b0e75bb0b7fd81dac7436", + "reference": "d8fdcb4fc90c392e672b0e75bb0b7fd81dac7436", "shasum": "" }, "require": { @@ -644,7 +644,7 @@ "gutenberg", "woocommerce" ], - "time": "2020-07-22T13:34:19+00:00" + "time": "2020-07-29T15:45:19+00:00" }, { "name": "woocommerce/woocommerce-rest-api", From e44154bf6eb4306db84baeaabc48affa6e7e20ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor=20Soriano?= Date: Thu, 30 Jul 2020 16:17:05 +0200 Subject: [PATCH 381/440] Update tests/legacy/unit-tests/util/class-wc-tests-wc-query.php Fix small coding standards issue. Co-authored-by: Claudio Sanches --- tests/legacy/unit-tests/util/class-wc-tests-wc-query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php index 9482797c4ab..bfe6025f23d 100644 --- a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php +++ b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php @@ -526,7 +526,7 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { * @testdox adjust_posts should return the input unmodified if the posts do not represent products. */ public function test_adjust_posts_count_when_the_posts_are_not_products() { - list($sut, $products) = $this->setup_adjust_posts_test( true, true, 'page' ); + list( $sut, $products ) = $this->setup_adjust_posts_test( true, true, 'page' ); $products[0]->set_stock_status( 'outofstock' ); $products[0]->save(); From 163e10253a539f956a375f1940e310136e761009 Mon Sep 17 00:00:00 2001 From: Jonathan Sadowski Date: Thu, 30 Jul 2020 10:35:23 -0500 Subject: [PATCH 382/440] Release coupon holds when status it updated to cancelled regardless of recorded coupons --- includes/wc-order-functions.php | 3 ++ .../order/class-wc-tests-order-functions.php | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/includes/wc-order-functions.php b/includes/wc-order-functions.php index 5ec7373deda..b103eaa2861 100644 --- a/includes/wc-order-functions.php +++ b/includes/wc-order-functions.php @@ -861,6 +861,9 @@ function wc_update_coupon_usage_counts( $order_id ) { } elseif ( ! $order->has_status( 'cancelled' ) && ! $has_recorded ) { $action = 'increase'; $order->get_data_store()->set_recorded_coupon_usage_counts( $order, true ); + } elseif ( $order->has_status( 'cancelled' ) ) { + $order->get_data_store()->release_held_coupons( $order, true ); + return; } else { return; } diff --git a/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php b/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php index ce3fba4c728..5001b59305c 100644 --- a/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php +++ b/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php @@ -1476,6 +1476,45 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case { $this->assertEquals( 0, $coupon_data_store->get_tentative_usages_for_user( $coupon->get_id(), array( 'a@b.com' ) ) ); } + /** + * Checks if coupons are released when switching from pending to cancelled state. + * + * Tests the fix for issue #26741 + */ + public function test_wc_cancelled_order_releases_coupon_hold_from_pending_state() { + $coupon_code = 'coupon1'; + $coupon_data_store = WC_Data_Store::load( 'coupon' ); + + $coupon = WC_Helper_Coupon::create_coupon( + $coupon_code, + array( + 'usage_limit' => 1, + 'usage_limit_per_user' => 1, + ) + ); + + $product = WC_Helper_Product::create_simple_product( true ); + WC()->cart->add_to_cart( $product->get_id(), 1 ); + WC()->cart->add_discount( $coupon_code ); + + $order_id = WC_Checkout::instance()->create_order( + array( + 'billing_email' => 'a@b.com', + 'payment_method' => 'dummy', + ) + ); + + $this->assertEquals( 1, $coupon_data_store->get_tentative_usage_count( $coupon->get_id() ) ); + $this->assertEquals( 1, $coupon_data_store->get_tentative_usages_for_user( $coupon->get_id(), array( 'a@b.com' ) ) ); + $this->assertEquals( 1, $coupon_data_store->get_usage_by_email( $coupon, 'a@b.com' ) ); + + $order = new WC_Order( $order_id ); + $order->update_status( 'cancelled' ); + $this->assertEquals( 0, $coupon_data_store->get_tentative_usage_count( $coupon->get_id() ) ); + $this->assertEquals( 0, $coupon_data_store->get_tentative_usages_for_user( $coupon->get_id(), array( 'a@b.com' ) ) ); + $this->assertEquals( 0, $coupon_data_store->get_usage_by_email( $coupon, 'a@b.com' ) ); + } + /** * Test if everything works as expected when coupon hold is disabled using filter. */ From 77f8bb57a6458b11b097d74fd10807706209b742 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 30 Jul 2020 13:05:03 -0300 Subject: [PATCH 383/440] Check if there's a payment method title --- includes/admin/meta-boxes/views/html-order-items.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/admin/meta-boxes/views/html-order-items.php b/includes/admin/meta-boxes/views/html-order-items.php index 034d08eeb87..f5dd34f972e 100644 --- a/includes/admin/meta-boxes/views/html-order-items.php +++ b/includes/admin/meta-boxes/views/html-order-items.php @@ -223,8 +223,12 @@ if ( wc_tax_enabled() ) { get_payment_method_title() ) { /* translators: 1: payment date. 2: payment method */ echo esc_html( sprintf( __( '%1$s via %2$s', 'woocommerce' ), $order->get_date_paid()->date_i18n( get_option( 'date_format' ) ), $order->get_payment_method_title() ) ); + } else { + echo esc_html( $order->get_date_paid()->date_i18n( get_option( 'date_format' ) ) ); + } ?> From 0b45369bff9edfd2c8abff54fc23a4371b3c8eb9 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 30 Jul 2020 16:17:23 -0300 Subject: [PATCH 384/440] Improved migration script to avoid race condition --- includes/class-wc-install.php | 1 - includes/class-woocommerce.php | 2 +- includes/wc-update-functions.php | 41 +++++++++++--------------------- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index a44d97f0afa..9f36a10493e 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -154,7 +154,6 @@ class WC_Install { 'wc_update_440_db_version', ), '4.5.0' => array( - 'wc_update_450_get_coupons', 'wc_update_450_sanitize_coupons_code', 'wc_update_450_db_version', ), diff --git a/includes/class-woocommerce.php b/includes/class-woocommerce.php index eb8e2923ebc..168569f0759 100644 --- a/includes/class-woocommerce.php +++ b/includes/class-woocommerce.php @@ -22,7 +22,7 @@ final class WooCommerce { * * @var string */ - public $version = '4.4.0'; + public $version = '4.5.0'; /** * WooCommerce Schema version. diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 7e1262847ce..d1973ac6c99 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2183,17 +2183,6 @@ function wc_update_450_db_version() { WC_Install::update_db_version( '4.5.0' ); } -/** - * Get coupons to update in the DB. - */ -function wc_update_450_get_coupons() { - global $wpdb; - - $coupons = $wpdb->get_results( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_type = 'shop_coupon';", ARRAY_A ); - - update_option( 'woocommerce_update_350_coupons', $coupons ); -} - /** * Sanitize all coupons code. * @@ -2202,42 +2191,40 @@ function wc_update_450_get_coupons() { function wc_update_450_sanitize_coupons_code() { global $wpdb; - $coupons = array_filter( (array) get_option( 'woocommerce_update_350_coupons', array() ) ); + $coupon_id = 0; + $last_coupon_id = get_option( 'woocommerce_update_350_last_coupon_id', '0' ); + + $coupons = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM $wpdb->posts WHERE ID > %d AND post_type = 'shop_coupon' LIMIT 10", $data['ID'] ), ARRAY_A ); if ( empty( $coupons ) ) { - delete_option( 'woocommerce_update_350_coupons' ); + delete_option( 'woocommerce_update_350_last_coupon_id' ); return false; } - // Batch 10 coupons for each run. - $batch_coupons = array_slice( $coupons, 0, 10, true ); - - foreach ( $batch_coupons as $key => $data ) { - $code = trim( wp_filter_kses( $data['post_title'] ) ); + foreach ( $coupons as $key => $data ) { + $coupon_id = intval( $data['ID'] ); + $code = trim( wp_filter_kses( $data['post_title'] ) ); if ( ! empty( $code ) ) { $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_title = %s WHERE ID = %d", $code, - $data['ID'] + $coupon_id ) ); // Clean cache. - clean_post_cache( intval( $data['ID'] ) ); + clean_post_cache( $coupon_id ); wp_cache_delete( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $data['post_title'], 'coupons' ); - - // Remove items from the list. - unset( $coupons[ $key ] ); } } - // Start the run again if there's still any coupon. - if ( ! empty( $coupons ) ) { - return update_option( 'woocommerce_update_350_coupons', $coupons ); + // Start the run again. + if ( ! $coupon_id ) { + return update_option( 'woocommerce_update_350_last_coupon_id', $coupon_id ); } - delete_option( 'woocommerce_update_350_coupons' ); + delete_option( 'woocommerce_update_350_last_coupon_id' ); return false; } From c574ea3364396d2d7036d4821cd8797fa512fa2c Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 30 Jul 2020 16:23:39 -0300 Subject: [PATCH 385/440] Updated queries and fixed version --- includes/class-woocommerce.php | 2 +- includes/wc-update-functions.php | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/includes/class-woocommerce.php b/includes/class-woocommerce.php index 168569f0759..eb8e2923ebc 100644 --- a/includes/class-woocommerce.php +++ b/includes/class-woocommerce.php @@ -22,7 +22,7 @@ final class WooCommerce { * * @var string */ - public $version = '4.5.0'; + public $version = '4.4.0'; /** * WooCommerce Schema version. diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index d1973ac6c99..a32e1c06c3d 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2194,7 +2194,13 @@ function wc_update_450_sanitize_coupons_code() { $coupon_id = 0; $last_coupon_id = get_option( 'woocommerce_update_350_last_coupon_id', '0' ); - $coupons = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM $wpdb->posts WHERE ID > %d AND post_type = 'shop_coupon' LIMIT 10", $data['ID'] ), ARRAY_A ); + $coupons = $wpdb->get_results( + $wpdb->prepare( + "SELECT ID, post_title FROM $wpdb->posts WHERE ID > %d AND post_type = 'shop_coupon' LIMIT 10", + $data['ID'] + ), + ARRAY_A + ); if ( empty( $coupons ) ) { delete_option( 'woocommerce_update_350_last_coupon_id' ); @@ -2206,11 +2212,19 @@ function wc_update_450_sanitize_coupons_code() { $code = trim( wp_filter_kses( $data['post_title'] ) ); if ( ! empty( $code ) ) { - $wpdb->query( - $wpdb->prepare( - "UPDATE {$wpdb->posts} SET post_title = %s WHERE ID = %d", - $code, - $coupon_id + $wpdb->update( + $wpdb->posts, + array( + 'post_title' => $code, + ), + array( + 'ID' => $coupon_id, + ), + array( + '%s', + ), + array( + '%d', ) ); From aa0b45358a16b59f3ef72c14b95045686f81251f Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 30 Jul 2020 16:36:54 -0300 Subject: [PATCH 386/440] Fixed upgrade routine --- includes/wc-update-functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index a32e1c06c3d..6977c64c3d6 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2197,7 +2197,7 @@ function wc_update_450_sanitize_coupons_code() { $coupons = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM $wpdb->posts WHERE ID > %d AND post_type = 'shop_coupon' LIMIT 10", - $data['ID'] + $last_coupon_id ), ARRAY_A ); @@ -2235,7 +2235,7 @@ function wc_update_450_sanitize_coupons_code() { } // Start the run again. - if ( ! $coupon_id ) { + if ( $coupon_id ) { return update_option( 'woocommerce_update_350_last_coupon_id', $coupon_id ); } From 48974f29f193162503a548ba740f540f3c3faa97 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 30 Jul 2020 17:00:11 -0300 Subject: [PATCH 387/440] Fixed unit tests for WC_Notes_Run_Db_Update --- .../admin/notes/class-wc-tests-notes-run-db-update.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/legacy/unit-tests/admin/notes/class-wc-tests-notes-run-db-update.php b/tests/legacy/unit-tests/admin/notes/class-wc-tests-notes-run-db-update.php index 7b89ea07488..f911cbf5bdd 100644 --- a/tests/legacy/unit-tests/admin/notes/class-wc-tests-notes-run-db-update.php +++ b/tests/legacy/unit-tests/admin/notes/class-wc-tests-notes-run-db-update.php @@ -17,6 +17,7 @@ class WC_Tests_Notes_Run_Db_Update extends WC_Unit_Test_Case { * */ public static function setUpBeforeClass() { + include_once WC_Unit_Tests_Bootstrap::instance()->plugin_dir . '/includes/admin/wc-admin-functions.php'; include_once WC_Unit_Tests_Bootstrap::instance()->plugin_dir . '/includes/admin/notes/class-wc-notes-run-db-update.php'; } From 5e354c451c3fe34234cb30532e5301b9f36f86a7 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Thu, 30 Jul 2020 14:55:14 -0700 Subject: [PATCH 388/440] Removed the define for the `JETPACK_AUTOLOAD_DEV` constant This is likely something that should be part of the `wp-config.php` for development environments of feature plugins as opposed to defined here. --- src/Autoloader.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Autoloader.php b/src/Autoloader.php index b67eafa4f76..f2da75ee72b 100644 --- a/src/Autoloader.php +++ b/src/Autoloader.php @@ -36,20 +36,6 @@ class Autoloader { return false; } - /** - * In order to support local development for feature plugins the autoloader must support dev versions. - * - * - If the checked out branch cannot supply Composer with version information then it - * assigns it a dev version string for the Jetpack Autoloader to use. - * - By default the Jetpack Autoloader will ignore these dev versions in favor of tagged versions. - * - * Due to this interaction, feature plugin files from the included packages will always be loaded instead - * of the versions in the feature plugin when checked out from a repository as a dev version. By setting - * this constant we change the behavior of the autoloader so that dev versions are prioritized over the - * tagged versions included in WooCommerce Core. - */ - define( 'JETPACK_AUTOLOAD_DEV', true ); - $autoloader_result = require $autoloader; if ( ! $autoloader_result ) { return false; From 71fccd6a07b59f523cd087f6a86c7fea3f5f0321 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Fri, 31 Jul 2020 16:21:22 +0200 Subject: [PATCH 389/440] Fix: pagination controls not displaying in products list. This bug was introduced in #26260. The sequence is: 1. WC_Query::adjust_posts_count runs, to handle found_posts filter, this indirectly executes wc_setup_loop. 2. At this point $GLOBALS['wp_query']->max_num_pages hasn't been set yet, and has a value of 0. Thus the loop variable total_pages is set to 0. 3. Later wc_setup_loop runs again and this time $GLOBALS['wp_query']->max_num_pages is already set, but since the loop variable total_pages already exists, it keeps its value of 0. 4. The pagination controls never show if total_pages is less than 2. The fix consists of hooking into the_posts to set the value of total_pages again, at that point $GLOBALS['wp_query']->max_num_pages is already set. --- includes/class-wc-query.php | 31 +++++++++++++++++-- .../util/class-wc-tests-wc-query.php | 30 ++++++++++++++++-- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index 7886a3a9b11..ba787df3b99 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -44,7 +44,7 @@ class WC_Query { add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 ); add_action( 'parse_request', array( $this, 'parse_request' ), 0 ); add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); - add_filter( 'the_posts', array( $this, 'remove_product_query_filters' ) ); + add_filter( 'the_posts', array( $this, 'handle_get_posts' ) ); add_filter( 'found_posts', array( $this, 'adjust_posts_count' ), 10, 2 ); add_filter( 'get_pagenum_link', array( $this, 'remove_add_to_cart_pagination' ), 10, 1 ); } @@ -352,6 +352,32 @@ class WC_Query { $this->product_query( $q ); } + /** + * Handler for the 'the_posts' WP filter. + * + * @param array $posts Posts from WP Query. + * + * @return array + */ + public function handle_get_posts( $posts ) { + $this->adjust_total_pages(); + $this->remove_product_query_filters( $posts ); + return $posts; + } + + /** + * The 'adjust_posts_count' method that handles the 'found_posts' filter indirectly initializes + * the loop properties with a call to 'wc_setup_loop'. This includes setting 'total_pages' to + * '$GLOBALS['wp_query']->max_num_pages', which at that point has a value of zero. + * Thus we need to set the real value from the 'the_posts' filter, where $GLOBALS['wp_query']->max_num_pages' + * will aready have been initialized. + */ + private function adjust_total_pages() { + if ( 0 === wc_get_loop_prop( 'total_pages' ) ) { + wc_set_loop_prop( 'total_pages', $GLOBALS['wp_query']->max_num_pages ); + } + } + /** * Pre_get_posts above may adjust the main query to add WooCommerce logic. When this query is done, we need to ensure * all custom filters are removed. @@ -376,13 +402,12 @@ class WC_Query { * We also cache the post visibility so that it isn't checked again when displaying the posts list. * * @since 4.4.0 - * @param int $count Original posts count, as supplied by the found_posts filter. + * @param int $count Original posts count, as supplied by the found_posts filter. * @param WP_Query $query The current WP_Query object. * * @return int Adjusted posts count. */ public function adjust_posts_count( $count, $query ) { - if ( ! $query->get( 'wc_query' ) ) { return $count; } diff --git a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php index bfe6025f23d..b7202b2115e 100644 --- a/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php +++ b/tests/legacy/unit-tests/util/class-wc-tests-wc-query.php @@ -492,6 +492,8 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { * [false, true] */ public function test_adjust_posts_count_with_nav_filtering_attributes( $with_nav_filtering_data, $use_objects ) { + global $wp_query; + list($sut, $products) = $this->setup_adjust_posts_test( $with_nav_filtering_data, $use_objects ); $products[0]->set_stock_status( 'outofstock' ); @@ -499,7 +501,8 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { $products[1]->set_stock_status( 'outofstock' ); $products[1]->save(); - $this->assertEquals( 32, $sut->adjust_posts_count( 34 ) ); + $wp_query->set( 'wc_query', 'product_query' ); + $this->assertEquals( 32, $sut->adjust_posts_count( 34, $wp_query ) ); $this->assertEquals( 32, wc_get_loop_prop( 'total' ) ); $this->assertEquals( false, wc_get_loop_product_visibility( $products[0]->get_id() ) ); $this->assertEquals( false, wc_get_loop_product_visibility( $products[1]->get_id() ) ); @@ -512,6 +515,8 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { * @testdox adjust_posts should return the input unmodified if get_current_posts returns null. */ public function test_adjust_posts_count_when_there_are_no_posts() { + global $wp_query; + $sut = $this ->getMockBuilder( WC_Query::class ) ->setMethods( array( 'get_current_posts', 'get_layered_nav_chosen_attributes_inst' ) ) @@ -519,18 +524,37 @@ class WC_Tests_WC_Query extends WC_Unit_Test_Case { $sut->method( 'get_current_posts' )->willReturn( null ); - $this->assertEquals( 34, $sut->adjust_posts_count( 34 ) ); + $wp_query->set( 'wc_query', 'product_query' ); + $this->assertEquals( 34, $sut->adjust_posts_count( 34, $wp_query ) ); } /** * @testdox adjust_posts should return the input unmodified if the posts do not represent products. */ public function test_adjust_posts_count_when_the_posts_are_not_products() { + global $wp_query; + list( $sut, $products ) = $this->setup_adjust_posts_test( true, true, 'page' ); $products[0]->set_stock_status( 'outofstock' ); $products[0]->save(); - $this->assertEquals( 34, $sut->adjust_posts_count( 34 ) ); + $wp_query->set( 'wc_query', 'product_query' ); + $this->assertEquals( 34, $sut->adjust_posts_count( 34, $wp_query ) ); + } + + /** + * @testdox adjust_posts should return the input unmodified if not in the main product query. + */ + public function test_adjust_posts_count_when_not_in_the_main_product_query() { + global $wp_query; + + list( $sut, $products ) = $this->setup_adjust_posts_test( true, true ); + + $products[0]->set_stock_status( 'outofstock' ); + $products[0]->save(); + + $wp_query->set( 'wc_query', null ); + $this->assertEquals( 34, $sut->adjust_posts_count( 34, $wp_query ) ); } } From f363604f4ecc9a2ebe020eb9cc96c9988550abd9 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 1 Aug 2020 00:23:49 +0200 Subject: [PATCH 390/440] add locale info for switzerland and liechtenstein --- i18n/locale-info.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/i18n/locale-info.php b/i18n/locale-info.php index 08866ca44b1..f1463b21afb 100644 --- a/i18n/locale-info.php +++ b/i18n/locale-info.php @@ -54,6 +54,15 @@ return array( 'weight_unit' => 'kg', 'dimension_unit' => 'cm', ), + 'CH' => array( + 'currency_code' => 'CHF', + 'currency_pos' => 'left_space', + 'thousand_sep' => "'", + 'decimal_sep' => '.', + 'num_decimals' => 2, + 'weight_unit' => 'kg', + 'dimension_unit' => 'cm', + ), 'DE' => array( 'currency_code' => 'EUR', 'currency_pos' => 'left', @@ -135,6 +144,15 @@ return array( 'weight_unit' => 'kg', 'dimension_unit' => 'cm', ), + 'LI' => array( + 'currency_code' => 'CHF', + 'currency_pos' => 'left_space', + 'thousand_sep' => "'", + 'decimal_sep' => '.', + 'num_decimals' => 2, + 'weight_unit' => 'kg', + 'dimension_unit' => 'cm', + ), 'MD' => array( 'currency_code' => 'MDL', 'currency_pos' => 'right_space', From 1d408a1a179cd9f13eda55470e6976a5b3b46bad Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 1 Aug 2020 00:26:53 +0200 Subject: [PATCH 391/440] Update states.php --- i18n/states.php | 1 - 1 file changed, 1 deletion(-) diff --git a/i18n/states.php b/i18n/states.php index c19136f8b20..a4a0ca5ccfc 100644 --- a/i18n/states.php +++ b/i18n/states.php @@ -837,7 +837,6 @@ return array( 'XS' => __( 'Xaisomboun', 'woocommerce' ), ), 'LB' => array(), - 'LI' => array(), 'LR' => array( // Liberia provinces. 'BM' => __( 'Bomi', 'woocommerce' ), 'BN' => __( 'Bong', 'woocommerce' ), From 2dcfc4248ce04cd2781ff75e92bfcc328226e4dc Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 1 Aug 2020 00:28:08 +0200 Subject: [PATCH 392/440] Update class-wc-countries.php --- includes/class-wc-countries.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-countries.php b/includes/class-wc-countries.php index 749e0df424c..b3e045136f3 100644 --- a/includes/class-wc-countries.php +++ b/includes/class-wc-countries.php @@ -1245,8 +1245,8 @@ class WC_Countries { 'priority' => 65, ), 'state' => array( + 'label' => __( 'Municipality', 'woocommerce' ), 'required' => false, - 'hidden' => true, ), ), 'LK' => array( From 98964ff0b13a5fbd28a25576830e4c267810869a Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 1 Aug 2020 00:37:33 +0200 Subject: [PATCH 393/440] Update locale-info.php --- i18n/locale-info.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/i18n/locale-info.php b/i18n/locale-info.php index 08866ca44b1..a32b3a04e0c 100644 --- a/i18n/locale-info.php +++ b/i18n/locale-info.php @@ -9,6 +9,15 @@ defined( 'ABSPATH' ) || exit; return array( + 'AT' => array( + 'currency_code' => 'EUR', + 'currency_pos' => 'left', + 'thousand_sep' => '.', + 'decimal_sep' => ',', + 'num_decimals' => 2, + 'weight_unit' => 'kg', + 'dimension_unit' => 'cm', + ), 'AU' => array( 'currency_code' => 'AUD', 'currency_pos' => 'left', From 78e099bd6db260f44df9cd1c232a8d3062e581dc Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 1 Aug 2020 00:37:55 +0200 Subject: [PATCH 394/440] Update locale-info.php --- i18n/locale-info.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/i18n/locale-info.php b/i18n/locale-info.php index a32b3a04e0c..08866ca44b1 100644 --- a/i18n/locale-info.php +++ b/i18n/locale-info.php @@ -9,15 +9,6 @@ defined( 'ABSPATH' ) || exit; return array( - 'AT' => array( - 'currency_code' => 'EUR', - 'currency_pos' => 'left', - 'thousand_sep' => '.', - 'decimal_sep' => ',', - 'num_decimals' => 2, - 'weight_unit' => 'kg', - 'dimension_unit' => 'cm', - ), 'AU' => array( 'currency_code' => 'AUD', 'currency_pos' => 'left', From 8ab459686181ebd0970db93d2d7dc54c9b24df37 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 1 Aug 2020 00:38:19 +0200 Subject: [PATCH 395/440] Update locale-info.php --- i18n/locale-info.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/i18n/locale-info.php b/i18n/locale-info.php index f1463b21afb..d2c928eece6 100644 --- a/i18n/locale-info.php +++ b/i18n/locale-info.php @@ -9,6 +9,15 @@ defined( 'ABSPATH' ) || exit; return array( + 'AT' => array( + 'currency_code' => 'EUR', + 'currency_pos' => 'left', + 'thousand_sep' => '.', + 'decimal_sep' => ',', + 'num_decimals' => 2, + 'weight_unit' => 'kg', + 'dimension_unit' => 'cm', + ), 'AU' => array( 'currency_code' => 'AUD', 'currency_pos' => 'left', From 4a4e5c3250706ee3a56d6d457004355af2c53e9c Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 1 Aug 2020 01:39:02 +0000 Subject: [PATCH 396/440] Update dependency autoprefixer to v9.8.6 --- package-lock.json | 1842 +++++++++++++++++---------------------------- package.json | 2 +- 2 files changed, 674 insertions(+), 1170 deletions(-) diff --git a/package-lock.json b/package-lock.json index fa0fad07d0a..59a774e016e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2106,6 +2106,23 @@ } } }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -2140,6 +2157,23 @@ } } }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", @@ -7628,6 +7662,15 @@ "@types/node": "*" } }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@types/is-stream/-/is-stream-1.1.0.tgz", @@ -8032,12 +8075,241 @@ "puppeteer": "^2.1.1" }, "dependencies": { + "@babel/runtime": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.0.tgz", + "integrity": "sha512-qArkXsjJq7H+T86WrIFV0Fnu/tNOkZ4cgXmjkzAu3b/58D5mFIO8JH/y77t7C9q0OdDRdh9s7Ue5GasYssxtXw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@wordpress/jest-console": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.7.0.tgz", + "integrity": "sha512-+PLH0jbY7xuKJckrkbtRk7zfyg4YDHFVulqydEBzSiU+LsZ2f/9hdRbb4/JDUneG7NpROO2smqxmaACxu5o9gw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "jest-matcher-utils": "^25.3.0", + "lodash": "^4.17.15" + } + }, + "@wordpress/jest-preset-default": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-6.2.0.tgz", + "integrity": "sha512-o8Yu+DnBWVXTLrbKYwWMRuF56quMiEK7+A9LSBQNrQ8PejTomhTF7lw8aGsUb7KdPgjbL941tbxVNJ/mKcbaJw==", + "dev": true, + "requires": { + "@jest/reporters": "^25.3.0", + "@wordpress/jest-console": "^3.7.0", + "babel-jest": "^25.3.0", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", + "enzyme-to-json": "^3.4.4" + } + }, "agent-base": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", "dev": true }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "dev": true, + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -8047,6 +8319,41 @@ "ms": "^2.1.1" } }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "https-proxy-agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", @@ -8057,6 +8364,202 @@ "debug": "4" } }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, "mime-db": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", @@ -8078,6 +8581,51 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", + "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, "puppeteer": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-2.1.1.tgz", @@ -8095,6 +8643,101 @@ "rimraf": "^2.6.1", "ws": "^6.1.0" } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -8286,1140 +8929,6 @@ } } }, - "@wordpress/jest-console": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.6.0.tgz", - "integrity": "sha512-0XpvIvgjdmVYYAA0l2XUktq+Z18upDhvaMFDdK8JDxu+vsso0XyFee5VNyHd/PvjInPrTXHoqGj0tx48uUqxhQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "jest-matcher-utils": "^25.3.0", - "lodash": "^4.17.15" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@wordpress/jest-preset-default": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-5.5.0.tgz", - "integrity": "sha512-LlO+cfKLN+insAcd1elXk5WIuXZBnBOeUQ/lnuOsd2cQfH5/y6ZvvBx1B3GSJJII8DM+SxAfi+I9f6HH8Fu3iw==", - "dev": true, - "requires": { - "@jest/reporters": "^24.8.0", - "@wordpress/jest-console": "^3.5.0", - "babel-jest": "^24.9.0", - "enzyme": "^3.9.0", - "enzyme-adapter-react-16": "^1.10.0", - "enzyme-to-json": "^3.3.5" - }, - "dependencies": { - "@jest/console": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", - "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", - "dev": true, - "requires": { - "@jest/source-map": "^24.9.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/environment": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", - "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, - "@jest/fake-timers": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", - "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, - "@jest/reporters": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", - "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.2", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.2.6", - "jest-haste-map": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "node-notifier": "^5.4.2", - "slash": "^2.0.0", - "source-map": "^0.6.0", - "string-length": "^2.0.0" - } - }, - "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", - "dev": true, - "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/test-sequencer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", - "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", - "dev": true, - "requires": { - "@jest/test-result": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0" - } - }, - "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", - "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" - } - }, - "@types/yargs": { - "version": "13.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", - "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "babel-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", - "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", - "dev": true, - "requires": { - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.9.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", - "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.3.0", - "test-exclude": "^5.2.3" - } - }, - "babel-plugin-jest-hoist": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", - "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", - "dev": true, - "requires": { - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", - "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", - "dev": true, - "requires": { - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.9.0" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", - "dev": true, - "requires": { - "cssom": "0.3.x" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "diff-sequences": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", - "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", - "dev": true - }, - "expect": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", - "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.9.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0" - } - }, - "jest-config": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", - "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.9.0", - "@jest/types": "^24.9.0", - "babel-jest": "^24.9.0", - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^24.9.0", - "jest-environment-node": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.9.0", - "realpath-native": "^1.1.0" - } - }, - "jest-diff": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", - "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, - "jest-each": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", - "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-environment-jsdom": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", - "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0", - "jsdom": "^11.5.1" - } - }, - "jest-environment-node": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", - "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0" - } - }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", - "dev": true - }, - "jest-haste-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", - "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.9.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", - "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "co": "^4.6.0", - "expect": "^24.9.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0", - "throat": "^4.0.0" - } - }, - "jest-leak-detector": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", - "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", - "dev": true, - "requires": { - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-matcher-utils": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", - "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-message-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", - "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", - "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0" - } - }, - "jest-regex-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", - "dev": true - }, - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-runner": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", - "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.4.2", - "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-leak-detector": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "source-map-support": "^0.5.6", - "throat": "^4.0.0" - } - }, - "jest-runtime": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", - "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^13.3.0" - } - }, - "jest-serializer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", - "dev": true - }, - "jest-snapshot": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", - "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "expect": "^24.9.0", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^24.9.0", - "semver": "^6.2.0" - } - }, - "jest-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", - "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", - "dev": true, - "requires": { - "@jest/console": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/source-map": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" - } - }, - "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" - } - }, - "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.1", - "escodegen": "^1.9.1", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", - "xml-name-validator": "^3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", - "dev": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", - "shellwords": "^0.1.1", - "which": "^1.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "string-length": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", - "dev": true, - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - } - }, - "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", - "dev": true - }, - "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "write-file-atomic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", - "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, "@wordpress/keycodes": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.13.0.tgz", @@ -10067,48 +9576,24 @@ "dev": true }, "autoprefixer": { - "version": "9.8.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.4.tgz", - "integrity": "sha512-84aYfXlpUe45lvmS+HoAWKCkirI/sw4JK0/bTeeqgHYco3dcsOn0NqdejISjptsYwNji/21dnkDri9PsYKk89A==", + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", "dev": true, "requires": { "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001087", - "colorette": "^1.2.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", "postcss": "^7.0.32", "postcss-value-parser": "^4.1.0" }, "dependencies": { - "browserslist": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.1.tgz", - "integrity": "sha512-WMjXwFtPskSW1pQUDJRxvRKRkeCr7usN0O/Za76N+F4oadaTdQHotSGcX9jT/Hs7mSKPkyMFNvqawB/1HzYDKQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001088", - "electron-to-chromium": "^1.3.481", - "escalade": "^3.0.1", - "node-releases": "^1.1.58" - } - }, "caniuse-lite": { - "version": "1.0.30001088", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001088.tgz", - "integrity": "sha512-6eYUrlShRYveyqKG58HcyOfPgh3zb2xqs7NvT2VVtP3hEUeeWvc3lqhpeMTxYWBBeeaT9A4bKsrtjATm66BTHg==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.483", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.483.tgz", - "integrity": "sha512-+05RF8S9rk8S0G8eBCqBRBaRq7+UN3lDs2DAvnG8SBSgQO3hjy0+qt4CmRk5eiuGbTcaicgXfPmBi31a+BD3lg==", - "dev": true - }, - "node-releases": { - "version": "1.1.58", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", - "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==", + "version": "1.0.30001109", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001109.tgz", + "integrity": "sha512-4JIXRodHzdS3HdK8nSgIqXYLExOvG+D2/EenSvcub2Kp3QEADjo2v2oUn5g0n0D+UNwG9BtwKOyGcSq2qvQXvQ==", "dev": true }, "postcss": { @@ -10831,6 +10316,25 @@ "@types/babel__traverse": "^7.0.6" } }, + "babel-preset-current-node-syntax": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, "babel-preset-jest": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz", @@ -11967,9 +11471,9 @@ "dev": true }, "colorette": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.0.tgz", - "integrity": "sha512-soRSroY+OF/8OdA3PTQXwaDJeMc7TfknKKrxeSCencL2a4+Tx5zhxmmv7hdpCjhKBjehzp8+bwe/T68K0hpIjw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", "dev": true }, "colors": { diff --git a/package.json b/package.json index ee6f28d1548..1b50b6aab1a 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@wordpress/babel-plugin-import-jsx-pragma": "1.1.3", "@wordpress/babel-preset-default": "3.0.2", "@wordpress/e2e-test-utils": "4.6.0", - "autoprefixer": "9.8.4", + "autoprefixer": "9.8.6", "babel-eslint": "10.1.0", "chai": "4.2.0", "chai-as-promised": "7.1.1", From 486b9f3a4d81de38eb4d1772fae6bd5a407a288c Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 1 Aug 2020 02:57:34 +0000 Subject: [PATCH 397/440] Update dependency grunt to v1.2.1 --- package-lock.json | 2253 +++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 1075 insertions(+), 1180 deletions(-) diff --git a/package-lock.json b/package-lock.json index fa0fad07d0a..ee1c50325dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2106,6 +2106,23 @@ } } }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -2140,6 +2157,23 @@ } } }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", @@ -7628,6 +7662,15 @@ "@types/node": "*" } }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@types/is-stream/-/is-stream-1.1.0.tgz", @@ -8032,12 +8075,241 @@ "puppeteer": "^2.1.1" }, "dependencies": { + "@babel/runtime": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.0.tgz", + "integrity": "sha512-qArkXsjJq7H+T86WrIFV0Fnu/tNOkZ4cgXmjkzAu3b/58D5mFIO8JH/y77t7C9q0OdDRdh9s7Ue5GasYssxtXw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@wordpress/jest-console": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.7.0.tgz", + "integrity": "sha512-+PLH0jbY7xuKJckrkbtRk7zfyg4YDHFVulqydEBzSiU+LsZ2f/9hdRbb4/JDUneG7NpROO2smqxmaACxu5o9gw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "jest-matcher-utils": "^25.3.0", + "lodash": "^4.17.15" + } + }, + "@wordpress/jest-preset-default": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-6.2.0.tgz", + "integrity": "sha512-o8Yu+DnBWVXTLrbKYwWMRuF56quMiEK7+A9LSBQNrQ8PejTomhTF7lw8aGsUb7KdPgjbL941tbxVNJ/mKcbaJw==", + "dev": true, + "requires": { + "@jest/reporters": "^25.3.0", + "@wordpress/jest-console": "^3.7.0", + "babel-jest": "^25.3.0", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", + "enzyme-to-json": "^3.4.4" + } + }, "agent-base": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", "dev": true }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "dev": true, + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -8047,6 +8319,41 @@ "ms": "^2.1.1" } }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "https-proxy-agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", @@ -8057,6 +8364,202 @@ "debug": "4" } }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, "mime-db": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", @@ -8078,6 +8581,51 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", + "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, "puppeteer": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-2.1.1.tgz", @@ -8095,6 +8643,101 @@ "rimraf": "^2.6.1", "ws": "^6.1.0" } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -8286,1140 +8929,6 @@ } } }, - "@wordpress/jest-console": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.6.0.tgz", - "integrity": "sha512-0XpvIvgjdmVYYAA0l2XUktq+Z18upDhvaMFDdK8JDxu+vsso0XyFee5VNyHd/PvjInPrTXHoqGj0tx48uUqxhQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "jest-matcher-utils": "^25.3.0", - "lodash": "^4.17.15" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@wordpress/jest-preset-default": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-5.5.0.tgz", - "integrity": "sha512-LlO+cfKLN+insAcd1elXk5WIuXZBnBOeUQ/lnuOsd2cQfH5/y6ZvvBx1B3GSJJII8DM+SxAfi+I9f6HH8Fu3iw==", - "dev": true, - "requires": { - "@jest/reporters": "^24.8.0", - "@wordpress/jest-console": "^3.5.0", - "babel-jest": "^24.9.0", - "enzyme": "^3.9.0", - "enzyme-adapter-react-16": "^1.10.0", - "enzyme-to-json": "^3.3.5" - }, - "dependencies": { - "@jest/console": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", - "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", - "dev": true, - "requires": { - "@jest/source-map": "^24.9.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/environment": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", - "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, - "@jest/fake-timers": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", - "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, - "@jest/reporters": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", - "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.2", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.2.6", - "jest-haste-map": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "node-notifier": "^5.4.2", - "slash": "^2.0.0", - "source-map": "^0.6.0", - "string-length": "^2.0.0" - } - }, - "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", - "dev": true, - "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/test-sequencer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", - "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", - "dev": true, - "requires": { - "@jest/test-result": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0" - } - }, - "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", - "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" - } - }, - "@types/yargs": { - "version": "13.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", - "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "babel-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", - "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", - "dev": true, - "requires": { - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.9.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", - "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.3.0", - "test-exclude": "^5.2.3" - } - }, - "babel-plugin-jest-hoist": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", - "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", - "dev": true, - "requires": { - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", - "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", - "dev": true, - "requires": { - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.9.0" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", - "dev": true, - "requires": { - "cssom": "0.3.x" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "diff-sequences": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", - "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", - "dev": true - }, - "expect": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", - "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.9.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0" - } - }, - "jest-config": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", - "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.9.0", - "@jest/types": "^24.9.0", - "babel-jest": "^24.9.0", - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^24.9.0", - "jest-environment-node": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.9.0", - "realpath-native": "^1.1.0" - } - }, - "jest-diff": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", - "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, - "jest-each": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", - "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-environment-jsdom": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", - "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0", - "jsdom": "^11.5.1" - } - }, - "jest-environment-node": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", - "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0" - } - }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", - "dev": true - }, - "jest-haste-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", - "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.9.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", - "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "co": "^4.6.0", - "expect": "^24.9.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0", - "throat": "^4.0.0" - } - }, - "jest-leak-detector": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", - "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", - "dev": true, - "requires": { - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-matcher-utils": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", - "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-message-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", - "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", - "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0" - } - }, - "jest-regex-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", - "dev": true - }, - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-runner": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", - "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.4.2", - "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-leak-detector": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "source-map-support": "^0.5.6", - "throat": "^4.0.0" - } - }, - "jest-runtime": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", - "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^13.3.0" - } - }, - "jest-serializer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", - "dev": true - }, - "jest-snapshot": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", - "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "expect": "^24.9.0", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^24.9.0", - "semver": "^6.2.0" - } - }, - "jest-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", - "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", - "dev": true, - "requires": { - "@jest/console": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/source-map": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" - } - }, - "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" - } - }, - "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.1", - "escodegen": "^1.9.1", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", - "xml-name-validator": "^3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", - "dev": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", - "shellwords": "^0.1.1", - "which": "^1.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "string-length": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", - "dev": true, - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - } - }, - "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", - "dev": true - }, - "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "write-file-atomic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", - "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, "@wordpress/keycodes": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.13.0.tgz", @@ -9876,6 +9385,12 @@ "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==", "dev": true }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", @@ -9900,6 +9415,12 @@ "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -10831,6 +10352,25 @@ "@types/babel__traverse": "^7.0.6" } }, + "babel-preset-current-node-syntax": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, "babel-preset-jest": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz", @@ -11923,12 +11463,6 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, - "coffeescript": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz", - "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=", - "dev": true - }, "collapse-white-space": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz", @@ -13436,14 +12970,10 @@ "dev": true }, "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" - } + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true }, "deasync": { "version": "0.1.20", @@ -14980,6 +14510,36 @@ } } }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "dependencies": { + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + } + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, "flat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", @@ -16613,67 +16173,97 @@ "dev": true }, "grunt": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.1.0.tgz", - "integrity": "sha512-+NGod0grmviZ7Nzdi9am7vuRS/h76PcWDsV635mEXF0PEQMUV6Kb+OjTdsVxbi0PZmfQOjCMKb3w8CVZcqsn1g==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.2.1.tgz", + "integrity": "sha512-zgJjn9N56tScvRt/y0+1QA+zDBnKTrkpyeSBqQPLcZvbqTD/oyGMrdZQXmm6I3828s+FmPvxc3Xv+lgKFtudOw==", "dev": true, "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", + "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", - "exit": "~0.1.1", + "exit": "~0.1.2", "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", + "glob": "~7.1.6", + "grunt-cli": "~1.3.2", "grunt-known-options": "~1.1.0", "grunt-legacy-log": "~2.0.0", "grunt-legacy-util": "~1.1.1", "iconv-lite": "~0.4.13", - "js-yaml": "~3.13.1", - "minimatch": "~3.0.2", - "mkdirp": "~1.0.3", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" + "rimraf": "~3.0.2" }, "dependencies": { "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.2", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "grunt-cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", - "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz", + "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==", "dev": true, "requires": { - "findup-sync": "~0.3.0", "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" + "interpret": "~1.1.0", + "liftoff": "~2.5.0", + "nopt": "~4.0.1", + "v8flags": "~3.1.1" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "mkdirp": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz", - "integrity": "sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } } } }, @@ -17903,6 +17493,16 @@ "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", "dev": true }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -18153,6 +17753,15 @@ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", "dev": true }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, "is-ssh": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz", @@ -18204,6 +17813,15 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -20652,6 +20270,187 @@ "type-check": "~0.3.2" } }, + "liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + } + } + }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -21321,6 +21120,23 @@ } } }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, "makeerror": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", @@ -22705,6 +22521,29 @@ "object-keys": "^1.0.11" } }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + } + } + }, "object.entries": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", @@ -22739,6 +22578,27 @@ "es-abstract": "^1.17.0-next.1" } }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + } + } + }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -23063,6 +22923,17 @@ "is-hexadecimal": "^1.0.0" } }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, "parse-github-repo-url": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", @@ -25613,6 +25484,15 @@ "util.promisify": "^1.0.0" } }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", @@ -28658,6 +28538,12 @@ "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=", "dev": true }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, "underscore.string": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", @@ -29067,6 +28953,15 @@ } } }, + "v8flags": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/package.json b/package.json index ee6f28d1548..7f9e4c62e30 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "eslint-config-wpcalypso": "5.0.0", "eslint-plugin-jest": "23.19.0", "github-contributors-list": "https://github.com/woocommerce/github-contributors-list/tarball/master", - "grunt": "1.1.0", + "grunt": "1.2.1", "grunt-contrib-clean": "2.0.0", "grunt-contrib-concat": "1.0.1", "grunt-contrib-copy": "1.0.0", From d1c0f7774bad93bcb35b910340aa74c628dbfe22 Mon Sep 17 00:00:00 2001 From: James Allan Date: Mon, 3 Aug 2020 14:01:31 +1000 Subject: [PATCH 398/440] Remove duplicate function argument --- includes/class-wc-product-variable.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index fe9b1e4416c..93c1c237724 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -282,12 +282,11 @@ class WC_Product_Variable extends WC_Product { /** * Get an array of available variations for the current product. * - * @param bool $render_variations Prepares a data array for each variant for output in the add to cart form. Pass `false` to only return the available variations as objects. - * @param bool $return_array_of_data If true, return an array of data for the variation; if false, return a WC_Product_Variation object. + * @param string $return Optional. The format to return the results in. Can be 'array' to return an array of variation data or 'objects' for the product objects. Default 'array'. * - * @return array|WC_Product_Variation + * @return array[]|WC_Product_Variation[] */ - public function get_available_variations( $render_variations = true, $return_array_of_data = true ) { + public function get_available_variations( $return = 'array' ) { $variation_ids = $this->get_children(); $available_variations = array(); @@ -309,14 +308,14 @@ class WC_Product_Variable extends WC_Product { continue; } - if ( $render_variations ) { - $available_variations[] = $return_array_of_data ? $this->get_available_variation( $variation ) : $variation; + if ( 'array' === $return ) { + $available_variations[] = $this->get_available_variation( $variation ); } else { $available_variations[] = $variation; } } - if ( $render_variations ) { + if ( 'array' === $return ) { $available_variations = array_values( array_filter( $available_variations ) ); } @@ -622,7 +621,7 @@ class WC_Product_Variable extends WC_Product { } ); - $variations = $this->get_available_variations( true, false ); + $variations = $this->get_available_variations( 'objects' ); foreach ( $variations as $variation ) { if ( $this->variation_matches_filters( $variation, $attributes_with_terms ) ) { return true; From 93febdca193f2cdacd2c08632d038ebc425dcfb5 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 3 Aug 2020 11:27:38 -0300 Subject: [PATCH 399/440] Fixed option name --- includes/wc-update-functions.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 6977c64c3d6..522e5c43798 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2192,7 +2192,7 @@ function wc_update_450_sanitize_coupons_code() { global $wpdb; $coupon_id = 0; - $last_coupon_id = get_option( 'woocommerce_update_350_last_coupon_id', '0' ); + $last_coupon_id = get_option( 'woocommerce_update_450_last_coupon_id', '0' ); $coupons = $wpdb->get_results( $wpdb->prepare( @@ -2203,7 +2203,7 @@ function wc_update_450_sanitize_coupons_code() { ); if ( empty( $coupons ) ) { - delete_option( 'woocommerce_update_350_last_coupon_id' ); + delete_option( 'woocommerce_update_450_last_coupon_id' ); return false; } @@ -2236,9 +2236,9 @@ function wc_update_450_sanitize_coupons_code() { // Start the run again. if ( $coupon_id ) { - return update_option( 'woocommerce_update_350_last_coupon_id', $coupon_id ); + return update_option( 'woocommerce_update_450_last_coupon_id', $coupon_id ); } - delete_option( 'woocommerce_update_350_last_coupon_id' ); + delete_option( 'woocommerce_update_450_last_coupon_id' ); return false; } From f5e1b4fa5467e1053ad7d52ed6d61faba7a69548 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 3 Aug 2020 11:28:27 -0300 Subject: [PATCH 400/440] Update only if the code got changed --- includes/wc-update-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 522e5c43798..f6f9788925d 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -2211,7 +2211,7 @@ function wc_update_450_sanitize_coupons_code() { $coupon_id = intval( $data['ID'] ); $code = trim( wp_filter_kses( $data['post_title'] ) ); - if ( ! empty( $code ) ) { + if ( ! empty( $code ) && $data['post_title'] !== $code ) { $wpdb->update( $wpdb->posts, array( From 200599f8e0d3802a5b28b7e0233d0b4bc980315f Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Mon, 3 Aug 2020 16:30:54 +0200 Subject: [PATCH 401/440] Add unit tests for the type of the value returned by 'get_available_variations' --- .../class-wc-product-variable-test.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/php/includes/class-wc-product-variable-test.php diff --git a/tests/php/includes/class-wc-product-variable-test.php b/tests/php/includes/class-wc-product-variable-test.php new file mode 100644 index 00000000000..e80b5751a0f --- /dev/null +++ b/tests/php/includes/class-wc-product-variable-test.php @@ -0,0 +1,42 @@ +get_available_variations(); + + $this->assertIsArray( $variations[0] ); + $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]['sku'] ); + } + + /** + * @testdox 'get_available_variations' returns the variations as arrays if the parameter passed is 'array'. + */ + public function test_get_available_variations_returns_array_when_array_parameter_is_passed() { + $product = WC_Helper_Product::create_variation_product(); + + $variations = $product->get_available_variations( 'array' ); + + $this->assertIsArray( $variations[0] ); + $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]['sku'] ); + } + + /** + * @testdox 'get_available_variations' returns the variations as objects if the parameter passed is 'objects'. + */ + public function test_get_available_variations_returns_object_when_objects_parameter_is_passed() { + $product = WC_Helper_Product::create_variation_product(); + + $variations = $product->get_available_variations( 'objects' ); + + $this->assertInstanceOf( WC_Product_Variation::class, $variations[0] ); + $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]->get_sku() ); + } +} From d55fa5ea0ad21409df7c22cdb894eaf25d0eb8be Mon Sep 17 00:00:00 2001 From: Timmy Crawford Date: Mon, 3 Aug 2020 23:35:10 -0700 Subject: [PATCH 402/440] Update woocommerce-admin to 1.4.0-rc.3 --- composer.json | 2 +- composer.lock | 71 +++++++++++++-------------------------------------- 2 files changed, 19 insertions(+), 54 deletions(-) diff --git a/composer.json b/composer.json index 2e6a85b6242..ae23f4905c6 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "maxmind-db/reader": "1.6.0", "pelago/emogrifier": "^3.1", "woocommerce/action-scheduler": "3.1.6", - "woocommerce/woocommerce-admin": "1.4.0-beta.2", + "woocommerce/woocommerce-admin": "1.4.0-beta.3", "woocommerce/woocommerce-blocks": "3.1.0", "woocommerce/woocommerce-rest-api": "1.0.11" }, diff --git a/composer.lock b/composer.lock index 2d66c29f127..483c502abec 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "877625af18978cccd2d02780fbd11842", + "content-hash": "d7df64252352cb3445d827cf204f24b4", "packages": [ { "name": "automattic/jetpack-autoloader", - "version": "v2.0.2", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "4502da4b2443fc1b61389cacc94c34876aca2b3d" + "reference": "802517b3ff3010de89141d9f7c4d56aec1d21527" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/4502da4b2443fc1b61389cacc94c34876aca2b3d", - "reference": "4502da4b2443fc1b61389cacc94c34876aca2b3d", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/802517b3ff3010de89141d9f7c4d56aec1d21527", + "reference": "802517b3ff3010de89141d9f7c4d56aec1d21527", "shasum": "" }, "require": { @@ -40,20 +40,20 @@ "GPL-2.0-or-later" ], "description": "Creates a custom autoloader for a plugin or theme.", - "time": "2020-07-09T13:18:38+00:00" + "time": "2020-07-27T20:37:00+00:00" }, { "name": "automattic/jetpack-constants", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/Automattic/jetpack-constants.git", - "reference": "77e4a85601c63dc98b3dd282090eb8558a61685c" + "reference": "b4210d56948529b43785ce31e0055f435eac1f9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-constants/zipball/77e4a85601c63dc98b3dd282090eb8558a61685c", - "reference": "77e4a85601c63dc98b3dd282090eb8558a61685c", + "url": "https://api.github.com/repos/Automattic/jetpack-constants/zipball/b4210d56948529b43785ce31e0055f435eac1f9f", + "reference": "b4210d56948529b43785ce31e0055f435eac1f9f", "shasum": "" }, "require-dev": { @@ -71,7 +71,7 @@ "GPL-2.0-or-later" ], "description": "A wrapper for defining constants in a more testable way.", - "time": "2020-06-22T11:37:41+00:00" + "time": "2020-07-01T15:55:35+00:00" }, { "name": "composer/installers", @@ -259,12 +259,6 @@ "provider", "service" ], - "funding": [ - { - "url": "https://github.com/philipobenito", - "type": "github" - } - ], "time": "2020-05-18T08:20:23+00:00" }, { @@ -501,20 +495,6 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-03-16T08:31:04+00:00" }, { @@ -554,16 +534,16 @@ }, { "name": "woocommerce/woocommerce-admin", - "version": "v1.4.0-beta.2", + "version": "v1.4.0-beta.3", "source": { "type": "git", "url": "https://github.com/woocommerce/woocommerce-admin.git", - "reference": "d56ac35bbb62bda2c981443932e7f90b0f6dbe99" + "reference": "df2af46a8552cdee15df0030fccbe4cd5a6d270d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/d56ac35bbb62bda2c981443932e7f90b0f6dbe99", - "reference": "d56ac35bbb62bda2c981443932e7f90b0f6dbe99", + "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/df2af46a8552cdee15df0030fccbe4cd5a6d270d", + "reference": "df2af46a8552cdee15df0030fccbe4cd5a6d270d", "shasum": "" }, "require": { @@ -597,7 +577,7 @@ ], "description": "A modern, javascript-driven WooCommerce Admin experience.", "homepage": "https://github.com/woocommerce/woocommerce-admin", - "time": "2020-07-28T15:18:55+00:00" + "time": "2020-08-04T02:21:47+00:00" }, { "name": "woocommerce/woocommerce-blocks", @@ -2594,25 +2574,11 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-02-14T07:34:21+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.18.0", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -3075,6 +3041,5 @@ "platform-dev": [], "platform-overrides": { "php": "7.1" - }, - "plugin-api-version": "1.1.0" + } } From 9e37acff3989bac9fafc739368abfc01c63fec40 Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Tue, 4 Aug 2020 09:53:08 +0200 Subject: [PATCH 403/440] Added missing changelog for 4.3.1 --- CHANGELOG.txt | 8 ++++++++ readme.txt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 68e4ec5132a..91f2ce50b83 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,13 @@ == Changelog == += 4.3.1 - 2020-07-21 = + +**WooCommerce Admin 1.3.1** +* Fix - PHP Fatal errors when columns are missing from the Notes table. #4831 + +**WooCommerce Blocks 2.7.2** +* Enhancement - Move Draft order logic behind feature flag. #2874 + = 4.3.0 - 2020-07-08 = **WooCommerce** diff --git a/readme.txt b/readme.txt index d51e741f691..57a619625b7 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: e-commerce, store, sales, sell, woo, shop, cart, checkout, downloadable, d Requires at least: 5.2 Tested up to: 5.4 Requires PHP: 7.0 -Stable tag: 4.3.0 +Stable tag: 4.3.1 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html From a3a2099315bffc0f0b5ef42fbfedada83e928732 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 28 Jul 2020 10:53:37 +0200 Subject: [PATCH 404/440] Add changelog for v4.4 --- CHANGELOG.txt | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 91f2ce50b83..0c1f435b4ca 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,113 @@ == Changelog == += 4.4.0 - 2020-08-18 = + +**WooCommerce** +* Accessibility: Adds alt attribute to photoswipe gallery images. #26945 +* Enhancement - Remove the privacy page dropdown from the Accounts & Privacy page. #26809 +* Enhancement - Added automatic language pack updates for WooCommerce.com extensions. #26750 +* Enhancement - Improvements for the Hungarian address format. #26697 +* Enhancement - Dropdown arrow width was made smaller. #26202 +* Enhancement - Add a "No change" option to the "Stock status" selector in quick edit, preselect it when the product being edited is a variable product. #26174 +* Localization - Added 14 Namibia regions. #26894 +* Localization - Change default Greek states names to English. #26719 +* Localization - Improved Puerto Rico addresses and improve address formatting. #26698 +* Localization - Wrapped price and currency inside a BDI tag, in order to prevent the bidirectional algorithm to produce confusing results. #26462 +* Localization - Added Algerian provinces. #25687 +* Tweak - Added "order_total" to the wcadmin_orders_edit_status_change tracker event. #26935 +* Tweak - Fixed WooCommerce menu for users that can only manage orders on WooCommerce. #26877 +* Tweak - Limit nocache headers to googleweblight by default. #26858 +* Tweak - Preserve quantity input value when changing variations. #26805 +* Tweak - Confirm before running any tool from the WooCommerce Status settings. #26660 +* Tweak - Limit stock changes for order items to status methods for consistency. #26642 +* Tweak - Custom vendor taxonomy update messages. #26634 +* Tweak - Remove HTML tags from plain text email template for Customer new account. #26613 +* Tweak - Conditionally change the text in My account to reflect if shipping is disabled. #26325 +* Tweak - Show CSV file name in result message when product import is complete. #25240 +* Fix - Remove the dot after the generated password in new account emails. #27073 +* Fix - Delayed the execution of all webhooks until after the request has completed. #27067 +* Fix - [Importer/Exporter] Fixed the value display of "Published" for children of draft variable products. #27046 +* Fix - Removed the extra id parameter added to CLI commands that shouldn't have one. #27017 +* Fix - Added the missing instance_id to the REST CLI command so that shipping zone method commands will work. #27017 +* Fix - Add rating_count to order by rating clause. #26964 +* Fix - Don't show premium support forum link if the store is not connected to WooCommerce.com. #26932 +* Fix - Incorrect capability used on add order note while creating an user note. #26920 +* Fix - Preserve HTML entities from product names in the cart page. #26885 +* Fix - Display warning hen leaving settings page without saving first. #26880 +* Fix - Remove wc_round_tax_total from shipping tax because shipping prices never include tax so rounding down is not needed. #26850 +* Fix - Make the "Please log in" message displayed to users with an existing account a hyperlink. #26837 +* Fix - Typo in composer.json for makepot. #26829 +* Fix - Layout issue on the checkout page when switching countries. #26697 +* Fix - Missing closing select tag to the product exporter category select. #26680 +* Fix - Possible PHP undefined index notice before WooCommerce has been configured. #26658 +* Fix - A deferred product sync is now scheduled when a product having a parent (e.g. a variation product) is deleted, not only when it's saved. #26629 +* Fix - Stock status of variable products that handle stock at the main product level is now appropriately updated when the product is saved. #26611 +* Fix - Discounted prices are no longer underlined in Twenty Twenty. #26609 +* Fix - Email link color clash. #26591 +* Fix - Remove HTML from error message. #26589 +* Fix - Fixed Tooltip flashing. #26558 +* Fix - Correctly displays the instructional option as default in the select box for picking a Country / Region on the checkout page. #26554 +* Fix - Default option "Select a country..." will now display accurately on Country select box in Cart shipping calculator. #26541 +* Fix - Fixed user capability required to view the order count indicator. #26338 +* Fix - The filtering widget now works as expected with variable products, displaying those products for which visible variations are available. #26260 +* Fix - Added a z-index to the remove button (x) to set the z-order of the element. #26202 +* Fix - don' change the stock status of variations when bulk editing a variable product and leaving the "Stock status" selector as "No change". #26174 +* Dev - Update WooCommerce Admin version to v1.4.0-beta.2. #27144 +* Dev - Upgraded to the 2.x Jetpack Autoloader. #27123 +* Dev - Update WooCommerce blocks version to 3.0.0. #27099 +* Dev - Update jest-preset-default version to ^6.2.0. #27090 +* Dev - Added a second $existing_meta_keys parameter to the woocommerce_duplicate_product_exclude_meta filter. #27038 +* Dev - Remove leftover note for translators in customer-completed-order.php. #26989 +* Dev - Allow extend BACS accounts filter with order ID. #26961 +* Dev - Add npm run build:packages to npm run build. #26906 +* Dev - Add woocommerce_order_note_added action. #26846 +* Dev - Add tests for template cache. #26840 +* Dev - Add filter to allow disabling nocache headers. #26802 +* Dev - Introduce a dependency injection framework for the code in the src directory. #26731 +* Dev - Normalized parameters of woocommerce_product_importer_parsed_data filter. #26669 +* Dev - Introduced new WC_Product_CSV_Importer::get_formatting_callback() fixing a typo in the method name. #26668 +* Dev - Allow set "date_created" while creating orders via CRUD. #26567 +* Dev - Allow set a custom as order key using wc_generate_order_key(). #26566 +* Dev - Allow set order_key while creating an order via CRUD. #26565 +* Dev - Introduced woocommerce_product_cross_sells_products_heading filter. #26545 +* Dev - Added the removed_coupon_in_checkout event that is triggered on the Checkout page after a coupon is removed using .woocommerce-remove-coupon button. #26536 +* Dev - Remove no longer used styles from TwentyTwenty. #26516 +* Dev - Fix error message in wc_get_template() function. #26515 +* Dev - Add npm publish script for @woocommerce/e2e-environment. #26432 +* Dev - Make WC_Cart::display_prices_including_tax aware of tax display changes. #26400 +* Dev - Deprecated WC_Legacy_Cart::tax_display_cart in favor of WC_Cart:: get_tax_price_display_mode(). #26400 +* Dev - Add an optional $render_variations argument to in WC_Product_Variable::get_available_variation() in order to allow plugins to avoid performance bottlenecks. #26303 +* Dev - Ensure wc_load_cart loads its own dependencies. #26219 + +**REST API 1.0.11** +* Enhancement - Introduced X-WP-Total header for product attributes GET endpoint listing the number of entries in the response. woocommerce/woocommerce-rest-api#171 +* Enhancement - Introduced X-WP-TotalPages header for product attributes GET endpoint listing the number of pages that can be fetched. woocommerce/woocommerce-rest-api#171 +* Enhancement - Introduced the modified option for orderby fetch requests in post based resources. woocommerce/woocommerce-rest-api#226 +* Fix - Ensured Action Scheduler transients are cleared by "Clear Transients" tool. woocommerce/woocommerce-rest-api#152 +* Fix - Corrected the schema datatype for coupon expiry_date, date_expires, and date_expires_gmt fields. woocommerce/woocommerce-rest-api#176 +* Fix - Query parameters are now passed correctly when using the batch product variation endpoints. woocommerce/woocommerce-rest-api#191 + +**WooCommerce Admin 1.4.0** +* Fix - Installation of child theme zip files from the store setup wizard. #4852 +* Fix - Center the skip link on the theme selection step. #4847 +* Fix - Removed item "profiler" from the menu. #4851 +* Fix - PHP notices when hosts block certain WP scripts. #4856 +* Dev - Add the experimental resolver to WCA data package. #4862 + +**WooCommerce Blocks 3.0.0** +* Build - Updated the automattic/jetpack-autoloader package to the 2.0 branch. #2847 +* Enhancement - Add support for the Bank Transfer (BACS) payment method in the Checkout block. #2821 +* Enhancement - Several improvements to make Credit Card input fields display more consistent across different themes and viewport sizes. #2869 +* Enhancement - Cart and Checkout blocks show a notification for products on backorder. #2833 +* Enhancement - Chip styles of the Filter Products by Attribute and Active Filters have been updated to give a more consistent experience. #2765 +* Enhancement - Add protection for rogue filters on order queries when executing cleanup draft orders logic. #2874 +* Enhancement - Extend payment gateway extension API so gateways (payment methods) can dynamically disable (hide), based on checkout or order data (such as cart items or shipping method). For example, Cash on Delivery can limit availability to specific shipping methods only. #2840 [DN] +* Enhancement - Support Cash on Delivery core payment gateway in the Checkout block. #2831 +* Performance - Don't load shortcode Cart and Checkout scripts when using the blocks. #2842 +* Performance - Scripts only relevant to the frontend side of blocks are no longer loaded in the editor. #2788 +* Performance - Lazy Loading Atomic Components. #2777 +* Pefactor - Remove dashicon classes. #2848 + = 4.3.1 - 2020-07-21 = **WooCommerce Admin 1.3.1** From 4d67ac9201806d2c19d27a5da45a84f2cf6e6b8b Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 28 Jul 2020 11:24:11 +0200 Subject: [PATCH 405/440] Update version in woocommerce.php to 4.4.0-beta.1 --- woocommerce.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/woocommerce.php b/woocommerce.php index 11256fc4494..c974e1ef0c7 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -3,7 +3,7 @@ * Plugin Name: WooCommerce * Plugin URI: https://woocommerce.com/ * Description: An eCommerce toolkit that helps you sell anything. Beautifully. - * Version: 4.4.0-dev + * Version: 4.4.0-beta.1 * Author: Automattic * Author URI: https://woocommerce.com * Text Domain: woocommerce From df527a19dd361e063b55c1dd5f652e9abb5dc99d Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 28 Jul 2020 11:37:29 +0200 Subject: [PATCH 406/440] Add the changelog for v4.4 to readme.txt --- readme.txt | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/readme.txt b/readme.txt index 57a619625b7..6d458fd4db7 100644 --- a/readme.txt +++ b/readme.txt @@ -181,6 +181,112 @@ INTERESTED IN DEVELOPMENT? = 4.4.0 - 2020-08-18 = +**WooCommerce** +* Accessibility: Adds alt attribute to photoswipe gallery images. #26945 +* Enhancement - Remove the privacy page dropdown from the Accounts & Privacy page. #26809 +* Enhancement - Added automatic language pack updates for WooCommerce.com extensions. #26750 +* Enhancement - Improvements for the Hungarian address format. #26697 +* Enhancement - Dropdown arrow width was made smaller. #26202 +* Enhancement - Add a "No change" option to the "Stock status" selector in quick edit, preselect it when the product being edited is a variable product. #26174 +* Localization - Added 14 Namibia regions. #26894 +* Localization - Change default Greek states names to English. #26719 +* Localization - Improved Puerto Rico addresses and improve address formatting. #26698 +* Localization - Wrapped price and currency inside a BDI tag, in order to prevent the bidirectional algorithm to produce confusing results. #26462 +* Localization - Added Algerian provinces. #25687 +* Tweak - Added "order_total" to the wcadmin_orders_edit_status_change tracker event. #26935 +* Tweak - Fixed WooCommerce menu for users that can only manage orders on WooCommerce. #26877 +* Tweak - Limit nocache headers to googleweblight by default. #26858 +* Tweak - Preserve quantity input value when changing variations. #26805 +* Tweak - Confirm before running any tool from the WooCommerce Status settings. #26660 +* Tweak - Limit stock changes for order items to status methods for consistency. #26642 +* Tweak - Custom vendor taxonomy update messages. #26634 +* Tweak - Remove HTML tags from plain text email template for Customer new account. #26613 +* Tweak - Conditionally change the text in My account to reflect if shipping is disabled. #26325 +* Tweak - Show CSV file name in result message when product import is complete. #25240 +* Fix - Remove the dot after the generated password in new account emails. #27073 +* Fix - Delayed the execution of all webhooks until after the request has completed. #27067 +* Fix - [Importer/Exporter] Fixed the value display of "Published" for children of draft variable products. #27046 +* Fix - Removed the extra id parameter added to CLI commands that shouldn't have one. #27017 +* Fix - Added the missing instance_id to the REST CLI command so that shipping zone method commands will work. #27017 +* Fix - Add rating_count to order by rating clause. #26964 +* Fix - Don't show premium support forum link if the store is not connected to WooCommerce.com. #26932 +* Fix - Incorrect capability used on add order note while creating an user note. #26920 +* Fix - Preserve HTML entities from product names in the cart page. #26885 +* Fix - Display warning hen leaving settings page without saving first. #26880 +* Fix - Remove wc_round_tax_total from shipping tax because shipping prices never include tax so rounding down is not needed. #26850 +* Fix - Make the "Please log in" message displayed to users with an existing account a hyperlink. #26837 +* Fix - Typo in composer.json for makepot. #26829 +* Fix - Layout issue on the checkout page when switching countries. #26697 +* Fix - Missing closing select tag to the product exporter category select. #26680 +* Fix - Possible PHP undefined index notice before WooCommerce has been configured. #26658 +* Fix - A deferred product sync is now scheduled when a product having a parent (e.g. a variation product) is deleted, not only when it's saved. #26629 +* Fix - Stock status of variable products that handle stock at the main product level is now appropriately updated when the product is saved. #26611 +* Fix - Discounted prices are no longer underlined in Twenty Twenty. #26609 +* Fix - Email link color clash. #26591 +* Fix - Remove HTML from error message. #26589 +* Fix - Fixed Tooltip flashing. #26558 +* Fix - Correctly displays the instructional option as default in the select box for picking a Country / Region on the checkout page. #26554 +* Fix - Default option "Select a country..." will now display accurately on Country select box in Cart shipping calculator. #26541 +* Fix - Fixed user capability required to view the order count indicator. #26338 +* Fix - The filtering widget now works as expected with variable products, displaying those products for which visible variations are available. #26260 +* Fix - Added a z-index to the remove button (x) to set the z-order of the element. #26202 +* Fix - don' change the stock status of variations when bulk editing a variable product and leaving the "Stock status" selector as "No change". #26174 +* Dev - Update WooCommerce Admin version to v1.4.0-beta.2. #27144 +* Dev - Upgraded to the 2.x Jetpack Autoloader. #27123 +* Dev - Update WooCommerce blocks version to 3.0.0. #27099 +* Dev - Update jest-preset-default version to ^6.2.0. #27090 +* Dev - Added a second $existing_meta_keys parameter to the woocommerce_duplicate_product_exclude_meta filter. #27038 +* Dev - Remove leftover note for translators in customer-completed-order.php. #26989 +* Dev - Allow extend BACS accounts filter with order ID. #26961 +* Dev - Add npm run build:packages to npm run build. #26906 +* Dev - Add woocommerce_order_note_added action. #26846 +* Dev - Add tests for template cache. #26840 +* Dev - Add filter to allow disabling nocache headers. #26802 +* Dev - Introduce a dependency injection framework for the code in the src directory. #26731 +* Dev - Normalized parameters of woocommerce_product_importer_parsed_data filter. #26669 +* Dev - Introduced new WC_Product_CSV_Importer::get_formatting_callback() fixing a typo in the method name. #26668 +* Dev - Allow set "date_created" while creating orders via CRUD. #26567 +* Dev - Allow set a custom as order key using wc_generate_order_key(). #26566 +* Dev - Allow set order_key while creating an order via CRUD. #26565 +* Dev - Introduced woocommerce_product_cross_sells_products_heading filter. #26545 +* Dev - Added the removed_coupon_in_checkout event that is triggered on the Checkout page after a coupon is removed using .woocommerce-remove-coupon button. #26536 +* Dev - Remove no longer used styles from TwentyTwenty. #26516 +* Dev - Fix error message in wc_get_template() function. #26515 +* Dev - Add npm publish script for @woocommerce/e2e-environment. #26432 +* Dev - Make WC_Cart::display_prices_including_tax aware of tax display changes. #26400 +* Dev - Deprecated WC_Legacy_Cart::tax_display_cart in favor of WC_Cart:: get_tax_price_display_mode(). #26400 +* Dev - Add an optional $render_variations argument to in WC_Product_Variable::get_available_variation() in order to allow plugins to avoid performance bottlenecks. #26303 +* Dev - Ensure wc_load_cart loads its own dependencies. #26219 + +**REST API 1.0.11** +* Enhancement - Introduced X-WP-Total header for product attributes GET endpoint listing the number of entries in the response. woocommerce/woocommerce-rest-api#171 +* Enhancement - Introduced X-WP-TotalPages header for product attributes GET endpoint listing the number of pages that can be fetched. woocommerce/woocommerce-rest-api#171 +* Enhancement - Introduced the modified option for orderby fetch requests in post based resources. woocommerce/woocommerce-rest-api#226 +* Fix - Ensured Action Scheduler transients are cleared by "Clear Transients" tool. woocommerce/woocommerce-rest-api#152 +* Fix - Corrected the schema datatype for coupon expiry_date, date_expires, and date_expires_gmt fields. woocommerce/woocommerce-rest-api#176 +* Fix - Query parameters are now passed correctly when using the batch product variation endpoints. woocommerce/woocommerce-rest-api#191 + +**WooCommerce Admin 1.4.0** +* Fix - Installation of child theme zip files from the store setup wizard. #4852 +* Fix - Center the skip link on the theme selection step. #4847 +* Fix - Removed item "profiler" from the menu. #4851 +* Fix - PHP notices when hosts block certain WP scripts. #4856 +* Dev - Add the experimental resolver to WCA data package. #4862 + +**WooCommerce Blocks 3.0.0** +* Build - Updated the automattic/jetpack-autoloader package to the 2.0 branch. #2847 +* Enhancement - Add support for the Bank Transfer (BACS) payment method in the Checkout block. #2821 +* Enhancement - Several improvements to make Credit Card input fields display more consistent across different themes and viewport sizes. #2869 +* Enhancement - Cart and Checkout blocks show a notification for products on backorder. #2833 +* Enhancement - Chip styles of the Filter Products by Attribute and Active Filters have been updated to give a more consistent experience. #2765 +* Enhancement - Add protection for rogue filters on order queries when executing cleanup draft orders logic. #2874 +* Enhancement - Extend payment gateway extension API so gateways (payment methods) can dynamically disable (hide), based on checkout or order data (such as cart items or shipping method). For example, Cash on Delivery can limit availability to specific shipping methods only. #2840 [DN] +* Enhancement - Support Cash on Delivery core payment gateway in the Checkout block. #2831 +* Performance - Don't load shortcode Cart and Checkout scripts when using the blocks. #2842 +* Performance - Scripts only relevant to the frontend side of blocks are no longer loaded in the editor. #2788 +* Performance - Lazy Loading Atomic Components. #2777 +* Pefactor - Remove dashicon classes. #2848 + [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce/master/CHANGELOG.txt). == Upgrade Notice == From 213137bc8cc1552c233cc2f58c0c0f84b7c7c449 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 28 Jul 2020 13:42:56 +0200 Subject: [PATCH 407/440] Add one more changelog entry for Admin --- CHANGELOG.txt | 1 + readme.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 0c1f435b4ca..01cf96fd51d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -88,6 +88,7 @@ * Fix - Query parameters are now passed correctly when using the batch product variation endpoints. woocommerce/woocommerce-rest-api#191 **WooCommerce Admin 1.4.0** +* Enhancement - Move the WooCommerce > Coupons dashboard menu item to Marketing > Coupons. #4786 * Fix - Installation of child theme zip files from the store setup wizard. #4852 * Fix - Center the skip link on the theme selection step. #4847 * Fix - Removed item "profiler" from the menu. #4851 diff --git a/readme.txt b/readme.txt index 6d458fd4db7..cb27d61b7a9 100644 --- a/readme.txt +++ b/readme.txt @@ -267,6 +267,7 @@ INTERESTED IN DEVELOPMENT? * Fix - Query parameters are now passed correctly when using the batch product variation endpoints. woocommerce/woocommerce-rest-api#191 **WooCommerce Admin 1.4.0** +* Enhancement - Move the WooCommerce > Coupons dashboard menu item to Marketing > Coupons. #4786 * Fix - Installation of child theme zip files from the store setup wizard. #4852 * Fix - Center the skip link on the theme selection step. #4847 * Fix - Removed item "profiler" from the menu. #4851 From 56f8cda645f5e67f3a47ae2581710f8a16bd0a04 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Mon, 3 Aug 2020 14:42:33 +0200 Subject: [PATCH 408/440] Add extra changelog entries for 4.4 RC 1 --- CHANGELOG.txt | 16 ++++++++++++++-- readme.txt | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 01cf96fd51d..b63dfc65eef 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -9,6 +9,7 @@ * Enhancement - Improvements for the Hungarian address format. #26697 * Enhancement - Dropdown arrow width was made smaller. #26202 * Enhancement - Add a "No change" option to the "Stock status" selector in quick edit, preselect it when the product being edited is a variable product. #26174 +* Enhancement - Don't request language packs for empty locales list. #27148 * Localization - Added 14 Namibia regions. #26894 * Localization - Change default Greek states names to English. #26719 * Localization - Improved Puerto Rico addresses and improve address formatting. #26698 @@ -24,6 +25,7 @@ * Tweak - Remove HTML tags from plain text email template for Customer new account. #26613 * Tweak - Conditionally change the text in My account to reflect if shipping is disabled. #26325 * Tweak - Show CSV file name in result message when product import is complete. #25240 +* Tweak - Improve order details UI to highlight "Paid" and "Net Payment" sections. #27142 * Fix - Remove the dot after the generated password in new account emails. #27073 * Fix - Delayed the execution of all webhooks until after the request has completed. #27067 * Fix - [Importer/Exporter] Fixed the value display of "Published" for children of draft variable products. #27046 @@ -51,10 +53,13 @@ * Fix - Fixed user capability required to view the order count indicator. #26338 * Fix - The filtering widget now works as expected with variable products, displaying those products for which visible variations are available. #26260 * Fix - Added a z-index to the remove button (x) to set the z-order of the element. #26202 -* Fix - don' change the stock status of variations when bulk editing a variable product and leaving the "Stock status" selector as "No change". #26174 +* Fix - Don't change the stock status of variations when bulk editing a variable product and leaving the "Stock status" selector as "No change". #26174 +* Fix - Remove new WP 5.5 meta box arrows from "Order data" and "Order items" meta boxes. #27173 +* Fix - After clicking to update WooCommerce, the user will stay in the same page instead of being redirected to the "Settings" page. #27172 +* Fix - "Product type" dropdown missing from Product's data meta box on WP 5.5. #27170 +* Fix - Removed the JETPACK_AUTOLOAD_DEV define. #27185 * Dev - Update WooCommerce Admin version to v1.4.0-beta.2. #27144 * Dev - Upgraded to the 2.x Jetpack Autoloader. #27123 -* Dev - Update WooCommerce blocks version to 3.0.0. #27099 * Dev - Update jest-preset-default version to ^6.2.0. #27090 * Dev - Added a second $existing_meta_keys parameter to the woocommerce_duplicate_product_exclude_meta filter. #27038 * Dev - Remove leftover note for translators in customer-completed-order.php. #26989 @@ -78,6 +83,8 @@ * Dev - Deprecated WC_Legacy_Cart::tax_display_cart in favor of WC_Cart:: get_tax_price_display_mode(). #26400 * Dev - Add an optional $render_variations argument to in WC_Product_Variable::get_available_variation() in order to allow plugins to avoid performance bottlenecks. #26303 * Dev - Ensure wc_load_cart loads its own dependencies. #26219 +* Dev - Clean up deprecated documentation. #27054 +* Dev - Update WooCommerce Blocks version to 3.1.0. #27177 **REST API 1.0.11** * Enhancement - Introduced X-WP-Total header for product attributes GET endpoint listing the number of entries in the response. woocommerce/woocommerce-rest-api#171 @@ -109,6 +116,11 @@ * Performance - Lazy Loading Atomic Components. #2777 * Pefactor - Remove dashicon classes. #2848 +**WooCommerce Blocks 3.1.0** +* Fix - Missing permissions_callback arg in StoreApi route definitions. #2926 +* Fix - 'Product Summary' in All Products block is not pulling in the short description of the product. #2913 +* Dev - Add query filter when searching for a table. #2886 + = 4.3.1 - 2020-07-21 = **WooCommerce Admin 1.3.1** diff --git a/readme.txt b/readme.txt index cb27d61b7a9..72e0284c159 100644 --- a/readme.txt +++ b/readme.txt @@ -188,6 +188,7 @@ INTERESTED IN DEVELOPMENT? * Enhancement - Improvements for the Hungarian address format. #26697 * Enhancement - Dropdown arrow width was made smaller. #26202 * Enhancement - Add a "No change" option to the "Stock status" selector in quick edit, preselect it when the product being edited is a variable product. #26174 +* Enhancement - Don't request language packs for empty locales list. #27148 * Localization - Added 14 Namibia regions. #26894 * Localization - Change default Greek states names to English. #26719 * Localization - Improved Puerto Rico addresses and improve address formatting. #26698 @@ -203,6 +204,7 @@ INTERESTED IN DEVELOPMENT? * Tweak - Remove HTML tags from plain text email template for Customer new account. #26613 * Tweak - Conditionally change the text in My account to reflect if shipping is disabled. #26325 * Tweak - Show CSV file name in result message when product import is complete. #25240 +* Tweak - Improve order details UI to highlight "Paid" and "Net Payment" sections. #27142 * Fix - Remove the dot after the generated password in new account emails. #27073 * Fix - Delayed the execution of all webhooks until after the request has completed. #27067 * Fix - [Importer/Exporter] Fixed the value display of "Published" for children of draft variable products. #27046 @@ -230,10 +232,13 @@ INTERESTED IN DEVELOPMENT? * Fix - Fixed user capability required to view the order count indicator. #26338 * Fix - The filtering widget now works as expected with variable products, displaying those products for which visible variations are available. #26260 * Fix - Added a z-index to the remove button (x) to set the z-order of the element. #26202 -* Fix - don' change the stock status of variations when bulk editing a variable product and leaving the "Stock status" selector as "No change". #26174 +* Fix - Don't change the stock status of variations when bulk editing a variable product and leaving the "Stock status" selector as "No change". #26174 +* Fix - Remove new WP 5.5 meta box arrows from "Order data" and "Order items" meta boxes. #27173 +* Fix - After clicking to update WooCommerce, the user will stay in the same page instead of being redirected to the "Settings" page. #27172 +* Fix - "Product type" dropdown missing from Product's data meta box on WP 5.5. #27170 +* Fix - Removed the JETPACK_AUTOLOAD_DEV define. #27185 * Dev - Update WooCommerce Admin version to v1.4.0-beta.2. #27144 * Dev - Upgraded to the 2.x Jetpack Autoloader. #27123 -* Dev - Update WooCommerce blocks version to 3.0.0. #27099 * Dev - Update jest-preset-default version to ^6.2.0. #27090 * Dev - Added a second $existing_meta_keys parameter to the woocommerce_duplicate_product_exclude_meta filter. #27038 * Dev - Remove leftover note for translators in customer-completed-order.php. #26989 @@ -257,6 +262,8 @@ INTERESTED IN DEVELOPMENT? * Dev - Deprecated WC_Legacy_Cart::tax_display_cart in favor of WC_Cart:: get_tax_price_display_mode(). #26400 * Dev - Add an optional $render_variations argument to in WC_Product_Variable::get_available_variation() in order to allow plugins to avoid performance bottlenecks. #26303 * Dev - Ensure wc_load_cart loads its own dependencies. #26219 +* Dev - Clean up deprecated documentation. #27054 +* Dev - Update WooCommerce Blocks version to 3.1.0. #27177 **REST API 1.0.11** * Enhancement - Introduced X-WP-Total header for product attributes GET endpoint listing the number of entries in the response. woocommerce/woocommerce-rest-api#171 @@ -288,6 +295,11 @@ INTERESTED IN DEVELOPMENT? * Performance - Lazy Loading Atomic Components. #2777 * Pefactor - Remove dashicon classes. #2848 +**WooCommerce Blocks 3.1.0** +* Fix - Missing permissions_callback arg in StoreApi route definitions. #2926 +* Fix - 'Product Summary' in All Products block is not pulling in the short description of the product. #2913 +* Dev - Add query filter when searching for a table. #2886 + [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce/master/CHANGELOG.txt). == Upgrade Notice == From 1279b2cc5743d383184f25682fb1530e6a41a6b6 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Mon, 3 Aug 2020 14:43:12 +0200 Subject: [PATCH 409/440] Bump version name in woocommerce.php to 4.5.0-dev --- woocommerce.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/woocommerce.php b/woocommerce.php index c974e1ef0c7..9ece15531c7 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -3,7 +3,7 @@ * Plugin Name: WooCommerce * Plugin URI: https://woocommerce.com/ * Description: An eCommerce toolkit that helps you sell anything. Beautifully. - * Version: 4.4.0-beta.1 + * Version: 4.5.0-dev * Author: Automattic * Author URI: https://woocommerce.com * Text Domain: woocommerce From 7d9f86c8cdfdabcff22003ed57694942b0a44469 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 4 Aug 2020 10:42:41 +0200 Subject: [PATCH 410/440] Add changelog for Admin 1.4.0-beta.3 --- CHANGELOG.txt | 11 ++++++++++- readme.txt | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index b63dfc65eef..d3f1e2a4f3c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -58,7 +58,7 @@ * Fix - After clicking to update WooCommerce, the user will stay in the same page instead of being redirected to the "Settings" page. #27172 * Fix - "Product type" dropdown missing from Product's data meta box on WP 5.5. #27170 * Fix - Removed the JETPACK_AUTOLOAD_DEV define. #27185 -* Dev - Update WooCommerce Admin version to v1.4.0-beta.2. #27144 +* Dev - Update WooCommerce Admin version to v1.4.0-beta.3. #27214 * Dev - Upgraded to the 2.x Jetpack Autoloader. #27123 * Dev - Update jest-preset-default version to ^6.2.0. #27090 * Dev - Added a second $existing_meta_keys parameter to the woocommerce_duplicate_product_exclude_meta filter. #27038 @@ -100,7 +100,16 @@ * Fix - Center the skip link on the theme selection step. #4847 * Fix - Removed item "profiler" from the menu. #4851 * Fix - PHP notices when hosts block certain WP scripts. #4856 +* Fix - Remove new WP 5.5 meta box arrows in the shipping banner. #4914 +* Fix - Allow revisiting of the payments task. #4918 +* Fix - Use of Jetpack autoloader. #4920 +* Fix - Only show WCPay task in US based stores. #4899 +* Fix - Polyfill core-data saveUser() on WP 5.3.x. #4869 +* Fix - Product types step bugs in onboarding wizard. #4900 +* Fix - Center all descriptive text on onboarding wizard steps. #4902 +* Fix - Change account required text on biz step in onboarding wizard. #4909 * Dev - Add the experimental resolver to WCA data package. #4862 +* Dev - Fix linter errors. #4904 **WooCommerce Blocks 3.0.0** * Build - Updated the automattic/jetpack-autoloader package to the 2.0 branch. #2847 diff --git a/readme.txt b/readme.txt index 72e0284c159..45119e0d2fc 100644 --- a/readme.txt +++ b/readme.txt @@ -237,7 +237,7 @@ INTERESTED IN DEVELOPMENT? * Fix - After clicking to update WooCommerce, the user will stay in the same page instead of being redirected to the "Settings" page. #27172 * Fix - "Product type" dropdown missing from Product's data meta box on WP 5.5. #27170 * Fix - Removed the JETPACK_AUTOLOAD_DEV define. #27185 -* Dev - Update WooCommerce Admin version to v1.4.0-beta.2. #27144 +* Dev - Update WooCommerce Admin version to v1.4.0-beta.3. #27214 * Dev - Upgraded to the 2.x Jetpack Autoloader. #27123 * Dev - Update jest-preset-default version to ^6.2.0. #27090 * Dev - Added a second $existing_meta_keys parameter to the woocommerce_duplicate_product_exclude_meta filter. #27038 @@ -279,7 +279,16 @@ INTERESTED IN DEVELOPMENT? * Fix - Center the skip link on the theme selection step. #4847 * Fix - Removed item "profiler" from the menu. #4851 * Fix - PHP notices when hosts block certain WP scripts. #4856 +* Fix - Remove new WP 5.5 meta box arrows in the shipping banner. #4914 +* Fix - Allow revisiting of the payments task. #4918 +* Fix - Use of Jetpack autoloader. #4920 +* Fix - Only show WCPay task in US based stores. #4899 +* Fix - Polyfill core-data saveUser() on WP 5.3.x. #4869 +* Fix - Product types step bugs in onboarding wizard. #4900 +* Fix - Center all descriptive text on onboarding wizard steps. #4902 +* Fix - Change account required text on biz step in onboarding wizard. #4909 * Dev - Add the experimental resolver to WCA data package. #4862 +* Dev - Fix linter errors. #4904 **WooCommerce Blocks 3.0.0** * Build - Updated the automattic/jetpack-autoloader package to the 2.0 branch. #2847 From 7f233951a5bac2147d878e1a91cbef4dcbc0e8d4 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Tue, 4 Aug 2020 22:29:50 -0300 Subject: [PATCH 411/440] Fixed class package tag --- .../data-stores/class-wc-order-item-shipping-data-store.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/data-stores/class-wc-order-item-shipping-data-store.php b/includes/data-stores/class-wc-order-item-shipping-data-store.php index e09545dfa30..0c4f3432e61 100644 --- a/includes/data-stores/class-wc-order-item-shipping-data-store.php +++ b/includes/data-stores/class-wc-order-item-shipping-data-store.php @@ -3,7 +3,7 @@ * WC Order Item Shipping Data Store * * @version 3.0.0 - * @package data-stores + * @package WooCommerce\DataStores */ if ( ! defined( 'ABSPATH' ) ) { From 8ac3fa0bdac238615b2250de95833ea417ec0c2b Mon Sep 17 00:00:00 2001 From: Yuliyan Slavchev Date: Wed, 5 Aug 2020 11:40:22 +0300 Subject: [PATCH 412/440] i18n: Decode HTML entities within countries and states names --- i18n/countries.php | 2 +- i18n/states.php | 344 ++++++++++++++++++++++----------------------- 2 files changed, 173 insertions(+), 173 deletions(-) diff --git a/i18n/countries.php b/i18n/countries.php index 9d2d517fb7f..dda20ec5880 100644 --- a/i18n/countries.php +++ b/i18n/countries.php @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; return array( 'AF' => __( 'Afghanistan', 'woocommerce' ), - 'AX' => __( 'Åland Islands', 'woocommerce' ), + 'AX' => __( 'Åland Islands', 'woocommerce' ), 'AL' => __( 'Albania', 'woocommerce' ), 'DZ' => __( 'Algeria', 'woocommerce' ), 'AS' => __( 'American Samoa', 'woocommerce' ), diff --git a/i18n/states.php b/i18n/states.php index a4a0ca5ccfc..78441bd3dfb 100644 --- a/i18n/states.php +++ b/i18n/states.php @@ -36,22 +36,22 @@ return array( 'ZAI' => __( 'Zaire', 'woocommerce' ), ), 'AR' => array( // Argentinian provinces. - 'C' => __( 'Ciudad Autónoma de Buenos Aires', 'woocommerce' ), + 'C' => __( 'Ciudad Autónoma de Buenos Aires', 'woocommerce' ), 'B' => __( 'Buenos Aires', 'woocommerce' ), 'K' => __( 'Catamarca', 'woocommerce' ), 'H' => __( 'Chaco', 'woocommerce' ), 'U' => __( 'Chubut', 'woocommerce' ), - 'X' => __( 'Córdoba', 'woocommerce' ), + 'X' => __( 'Córdoba', 'woocommerce' ), 'W' => __( 'Corrientes', 'woocommerce' ), - 'E' => __( 'Entre Ríos', 'woocommerce' ), + 'E' => __( 'Entre Ríos', 'woocommerce' ), 'P' => __( 'Formosa', 'woocommerce' ), 'Y' => __( 'Jujuy', 'woocommerce' ), 'L' => __( 'La Pampa', 'woocommerce' ), 'F' => __( 'La Rioja', 'woocommerce' ), 'M' => __( 'Mendoza', 'woocommerce' ), 'N' => __( 'Misiones', 'woocommerce' ), - 'Q' => __( 'Neuquén', 'woocommerce' ), - 'R' => __( 'Río Negro', 'woocommerce' ), + 'Q' => __( 'Neuquén', 'woocommerce' ), + 'R' => __( 'Río Negro', 'woocommerce' ), 'A' => __( 'Salta', 'woocommerce' ), 'J' => __( 'San Juan', 'woocommerce' ), 'D' => __( 'San Luis', 'woocommerce' ), @@ -59,7 +59,7 @@ return array( 'S' => __( 'Santa Fe', 'woocommerce' ), 'G' => __( 'Santiago del Estero', 'woocommerce' ), 'V' => __( 'Tierra del Fuego', 'woocommerce' ), - 'T' => __( 'Tucumán', 'woocommerce' ), + 'T' => __( 'Tucumán', 'woocommerce' ), ), 'AT' => array(), 'AU' => array( // Australian states. @@ -186,29 +186,29 @@ return array( 'BR' => array( // Brazillian states. 'AC' => __( 'Acre', 'woocommerce' ), 'AL' => __( 'Alagoas', 'woocommerce' ), - 'AP' => __( 'Amapá', 'woocommerce' ), + 'AP' => __( 'Amapá', 'woocommerce' ), 'AM' => __( 'Amazonas', 'woocommerce' ), 'BA' => __( 'Bahia', 'woocommerce' ), - 'CE' => __( 'Ceará', 'woocommerce' ), + 'CE' => __( 'Ceará', 'woocommerce' ), 'DF' => __( 'Distrito Federal', 'woocommerce' ), - 'ES' => __( 'Espírito Santo', 'woocommerce' ), - 'GO' => __( 'Goiás', 'woocommerce' ), - 'MA' => __( 'Maranhão', 'woocommerce' ), + 'ES' => __( 'Espírito Santo', 'woocommerce' ), + 'GO' => __( 'Goiás', 'woocommerce' ), + 'MA' => __( 'Maranhão', 'woocommerce' ), 'MT' => __( 'Mato Grosso', 'woocommerce' ), 'MS' => __( 'Mato Grosso do Sul', 'woocommerce' ), 'MG' => __( 'Minas Gerais', 'woocommerce' ), - 'PA' => __( 'Pará', 'woocommerce' ), - 'PB' => __( 'Paraíba', 'woocommerce' ), - 'PR' => __( 'Paraná', 'woocommerce' ), + 'PA' => __( 'Pará', 'woocommerce' ), + 'PB' => __( 'Paraíba', 'woocommerce' ), + 'PR' => __( 'Paraná', 'woocommerce' ), 'PE' => __( 'Pernambuco', 'woocommerce' ), - 'PI' => __( 'Piauí', 'woocommerce' ), + 'PI' => __( 'Piauí', 'woocommerce' ), 'RJ' => __( 'Rio de Janeiro', 'woocommerce' ), 'RN' => __( 'Rio Grande do Norte', 'woocommerce' ), 'RS' => __( 'Rio Grande do Sul', 'woocommerce' ), - 'RO' => __( 'Rondônia', 'woocommerce' ), + 'RO' => __( 'Rondônia', 'woocommerce' ), 'RR' => __( 'Roraima', 'woocommerce' ), 'SC' => __( 'Santa Catarina', 'woocommerce' ), - 'SP' => __( 'São Paulo', 'woocommerce' ), + 'SP' => __( 'São Paulo', 'woocommerce' ), 'SE' => __( 'Sergipe', 'woocommerce' ), 'TO' => __( 'Tocantins', 'woocommerce' ), ), @@ -237,10 +237,10 @@ return array( 'FR' => __( 'Fribourg', 'woocommerce' ), 'GE' => __( 'Geneva', 'woocommerce' ), 'GL' => __( 'Glarus', 'woocommerce' ), - 'GR' => __( 'Graubünden', 'woocommerce' ), + 'GR' => __( 'Graubünden', 'woocommerce' ), 'JU' => __( 'Jura', 'woocommerce' ), 'LU' => __( 'Luzern', 'woocommerce' ), - 'NE' => __( 'Neuchâtel', 'woocommerce' ), + 'NE' => __( 'Neuchâtel', 'woocommerce' ), 'NW' => __( 'Nidwalden', 'woocommerce' ), 'OW' => __( 'Obwalden', 'woocommerce' ), 'SH' => __( 'Schaffhausen', 'woocommerce' ), @@ -253,41 +253,41 @@ return array( 'VS' => __( 'Valais', 'woocommerce' ), 'VD' => __( 'Vaud', 'woocommerce' ), 'ZG' => __( 'Zug', 'woocommerce' ), - 'ZH' => __( 'Zürich', 'woocommerce' ), + 'ZH' => __( 'Zürich', 'woocommerce' ), ), 'CN' => array( // Chinese states. - 'CN1' => __( 'Yunnan / 云南', 'woocommerce' ), - 'CN2' => __( 'Beijing / 北京', 'woocommerce' ), - 'CN3' => __( 'Tianjin / 天津', 'woocommerce' ), - 'CN4' => __( 'Hebei / 河北', 'woocommerce' ), - 'CN5' => __( 'Shanxi / 山西', 'woocommerce' ), - 'CN6' => __( 'Inner Mongolia / 內蒙古', 'woocommerce' ), - 'CN7' => __( 'Liaoning / 辽宁', 'woocommerce' ), - 'CN8' => __( 'Jilin / 吉林', 'woocommerce' ), - 'CN9' => __( 'Heilongjiang / 黑龙江', 'woocommerce' ), - 'CN10' => __( 'Shanghai / 上海', 'woocommerce' ), - 'CN11' => __( 'Jiangsu / 江苏', 'woocommerce' ), - 'CN12' => __( 'Zhejiang / 浙江', 'woocommerce' ), - 'CN13' => __( 'Anhui / 安徽', 'woocommerce' ), - 'CN14' => __( 'Fujian / 福建', 'woocommerce' ), - 'CN15' => __( 'Jiangxi / 江西', 'woocommerce' ), - 'CN16' => __( 'Shandong / 山东', 'woocommerce' ), - 'CN17' => __( 'Henan / 河南', 'woocommerce' ), - 'CN18' => __( 'Hubei / 湖北', 'woocommerce' ), - 'CN19' => __( 'Hunan / 湖南', 'woocommerce' ), - 'CN20' => __( 'Guangdong / 广东', 'woocommerce' ), - 'CN21' => __( 'Guangxi Zhuang / 广西壮族', 'woocommerce' ), - 'CN22' => __( 'Hainan / 海南', 'woocommerce' ), - 'CN23' => __( 'Chongqing / 重庆', 'woocommerce' ), - 'CN24' => __( 'Sichuan / 四川', 'woocommerce' ), - 'CN25' => __( 'Guizhou / 贵州', 'woocommerce' ), - 'CN26' => __( 'Shaanxi / 陕西', 'woocommerce' ), - 'CN27' => __( 'Gansu / 甘肃', 'woocommerce' ), - 'CN28' => __( 'Qinghai / 青海', 'woocommerce' ), - 'CN29' => __( 'Ningxia Hui / 宁夏', 'woocommerce' ), - 'CN30' => __( 'Macao / 澳门', 'woocommerce' ), - 'CN31' => __( 'Tibet / 西藏', 'woocommerce' ), - 'CN32' => __( 'Xinjiang / 新疆', 'woocommerce' ), + 'CN1' => __( 'Yunnan / 云南', 'woocommerce' ), + 'CN2' => __( 'Beijing / 北京', 'woocommerce' ), + 'CN3' => __( 'Tianjin / 天津', 'woocommerce' ), + 'CN4' => __( 'Hebei / 河北', 'woocommerce' ), + 'CN5' => __( 'Shanxi / 山西', 'woocommerce' ), + 'CN6' => __( 'Inner Mongolia / 內蒙古', 'woocommerce' ), + 'CN7' => __( 'Liaoning / 辽宁', 'woocommerce' ), + 'CN8' => __( 'Jilin / 吉林', 'woocommerce' ), + 'CN9' => __( 'Heilongjiang / 黑龙江', 'woocommerce' ), + 'CN10' => __( 'Shanghai / 上海', 'woocommerce' ), + 'CN11' => __( 'Jiangsu / 江苏', 'woocommerce' ), + 'CN12' => __( 'Zhejiang / 浙江', 'woocommerce' ), + 'CN13' => __( 'Anhui / 安徽', 'woocommerce' ), + 'CN14' => __( 'Fujian / 福建', 'woocommerce' ), + 'CN15' => __( 'Jiangxi / 江西', 'woocommerce' ), + 'CN16' => __( 'Shandong / 山东', 'woocommerce' ), + 'CN17' => __( 'Henan / 河南', 'woocommerce' ), + 'CN18' => __( 'Hubei / 湖北', 'woocommerce' ), + 'CN19' => __( 'Hunan / 湖南', 'woocommerce' ), + 'CN20' => __( 'Guangdong / 广东', 'woocommerce' ), + 'CN21' => __( 'Guangxi Zhuang / 广西壮族', 'woocommerce' ), + 'CN22' => __( 'Hainan / 海南', 'woocommerce' ), + 'CN23' => __( 'Chongqing / 重庆', 'woocommerce' ), + 'CN24' => __( 'Sichuan / 四川', 'woocommerce' ), + 'CN25' => __( 'Guizhou / 贵州', 'woocommerce' ), + 'CN26' => __( 'Shaanxi / 陕西', 'woocommerce' ), + 'CN27' => __( 'Gansu / 甘肃', 'woocommerce' ), + 'CN28' => __( 'Qinghai / 青海', 'woocommerce' ), + 'CN29' => __( 'Ningxia Hui / 宁夏', 'woocommerce' ), + 'CN30' => __( 'Macao / 澳门', 'woocommerce' ), + 'CN31' => __( 'Tibet / 西藏', 'woocommerce' ), + 'CN32' => __( 'Xinjiang / 新疆', 'woocommerce' ), ), 'CZ' => array(), 'DE' => array(), @@ -298,36 +298,36 @@ return array( 'DZ-03' => __( 'Laghouat', 'woocommerce' ), 'DZ-04' => __( 'Oum El Bouaghi', 'woocommerce' ), 'DZ-05' => __( 'Batna', 'woocommerce' ), - 'DZ-06' => __( 'Béjaïa', 'woocommerce' ), + 'DZ-06' => __( 'Béjaïa', 'woocommerce' ), 'DZ-07' => __( 'Biskra', 'woocommerce' ), - 'DZ-08' => __( 'Béchar', 'woocommerce' ), + 'DZ-08' => __( 'Béchar', 'woocommerce' ), 'DZ-09' => __( 'Blida', 'woocommerce' ), 'DZ-10' => __( 'Bouira', 'woocommerce' ), 'DZ-11' => __( 'Tamanghasset', 'woocommerce' ), - 'DZ-12' => __( 'Tébessa', 'woocommerce' ), + 'DZ-12' => __( 'Tébessa', 'woocommerce' ), 'DZ-13' => __( 'Tlemcen', 'woocommerce' ), 'DZ-14' => __( 'Tiaret', 'woocommerce' ), 'DZ-15' => __( 'Tizi Ouzou', 'woocommerce' ), 'DZ-16' => __( 'Algiers', 'woocommerce' ), 'DZ-17' => __( 'Djelfa', 'woocommerce' ), 'DZ-18' => __( 'Jijel', 'woocommerce' ), - 'DZ-19' => __( 'Sétif', 'woocommerce' ), - 'DZ-20' => __( 'Saïda', 'woocommerce' ), + 'DZ-19' => __( 'Sétif', 'woocommerce' ), + 'DZ-20' => __( 'Saïda', 'woocommerce' ), 'DZ-21' => __( 'Skikda', 'woocommerce' ), - 'DZ-22' => __( 'Sidi Bel Abbès', 'woocommerce' ), + 'DZ-22' => __( 'Sidi Bel Abbès', 'woocommerce' ), 'DZ-23' => __( 'Annaba', 'woocommerce' ), 'DZ-24' => __( 'Guelma', 'woocommerce' ), 'DZ-25' => __( 'Constantine', 'woocommerce' ), - 'DZ-26' => __( 'Médéa', 'woocommerce' ), + 'DZ-26' => __( 'Médéa', 'woocommerce' ), 'DZ-27' => __( 'Mostaganem', 'woocommerce' ), - 'DZ-28' => __( 'M’Sila', 'woocommerce' ), + 'DZ-28' => __( 'M’Sila', 'woocommerce' ), 'DZ-29' => __( 'Mascara', 'woocommerce' ), 'DZ-30' => __( 'Ouargla', 'woocommerce' ), 'DZ-31' => __( 'Oran', 'woocommerce' ), 'DZ-32' => __( 'El Bayadh', 'woocommerce' ), 'DZ-33' => __( 'Illizi', 'woocommerce' ), - 'DZ-34' => __( 'Bordj Bou Arréridj', 'woocommerce' ), - 'DZ-35' => __( 'Boumerdès', 'woocommerce' ), + 'DZ-34' => __( 'Bordj Bou Arréridj', 'woocommerce' ), + 'DZ-35' => __( 'Boumerdès', 'woocommerce' ), 'DZ-36' => __( 'El Tarf', 'woocommerce' ), 'DZ-37' => __( 'Tindouf', 'woocommerce' ), 'DZ-38' => __( 'Tissemsilt', 'woocommerce' ), @@ -336,32 +336,32 @@ return array( 'DZ-41' => __( 'Souk Ahras', 'woocommerce' ), 'DZ-42' => __( 'Tipasa', 'woocommerce' ), 'DZ-43' => __( 'Mila', 'woocommerce' ), - 'DZ-44' => __( 'Aïn Defla', 'woocommerce' ), + 'DZ-44' => __( 'Aïn Defla', 'woocommerce' ), 'DZ-45' => __( 'Naama', 'woocommerce' ), - 'DZ-46' => __( 'Aïn Témouchent', 'woocommerce' ), - 'DZ-47' => __( 'Ghardaïa', 'woocommerce' ), + 'DZ-46' => __( 'Aïn Témouchent', 'woocommerce' ), + 'DZ-47' => __( 'Ghardaïa', 'woocommerce' ), 'DZ-48' => __( 'Relizane', 'woocommerce' ), ), 'EE' => array(), 'ES' => array( // Spanish states. - 'C' => __( 'A Coruña', 'woocommerce' ), - 'VI' => __( 'Araba/Álava', 'woocommerce' ), + 'C' => __( 'A Coruña', 'woocommerce' ), + 'VI' => __( 'Araba/Álava', 'woocommerce' ), 'AB' => __( 'Albacete', 'woocommerce' ), 'A' => __( 'Alicante', 'woocommerce' ), - 'AL' => __( 'Almería', 'woocommerce' ), + 'AL' => __( 'Almería', 'woocommerce' ), 'O' => __( 'Asturias', 'woocommerce' ), - 'AV' => __( 'Ávila', 'woocommerce' ), + 'AV' => __( 'Ávila', 'woocommerce' ), 'BA' => __( 'Badajoz', 'woocommerce' ), 'PM' => __( 'Baleares', 'woocommerce' ), 'B' => __( 'Barcelona', 'woocommerce' ), 'BU' => __( 'Burgos', 'woocommerce' ), - 'CC' => __( 'Cáceres', 'woocommerce' ), - 'CA' => __( 'Cádiz', 'woocommerce' ), + 'CC' => __( 'Cáceres', 'woocommerce' ), + 'CA' => __( 'Cádiz', 'woocommerce' ), 'S' => __( 'Cantabria', 'woocommerce' ), - 'CS' => __( 'Castellón', 'woocommerce' ), + 'CS' => __( 'Castellón', 'woocommerce' ), 'CE' => __( 'Ceuta', 'woocommerce' ), 'CR' => __( 'Ciudad Real', 'woocommerce' ), - 'CO' => __( 'Córdoba', 'woocommerce' ), + 'CO' => __( 'Córdoba', 'woocommerce' ), 'CU' => __( 'Cuenca', 'woocommerce' ), 'GI' => __( 'Girona', 'woocommerce' ), 'GR' => __( 'Granada', 'woocommerce' ), @@ -369,14 +369,14 @@ return array( 'SS' => __( 'Gipuzkoa', 'woocommerce' ), 'H' => __( 'Huelva', 'woocommerce' ), 'HU' => __( 'Huesca', 'woocommerce' ), - 'J' => __( 'Jaén', 'woocommerce' ), + 'J' => __( 'Jaén', 'woocommerce' ), 'LO' => __( 'La Rioja', 'woocommerce' ), 'GC' => __( 'Las Palmas', 'woocommerce' ), - 'LE' => __( 'León', 'woocommerce' ), + 'LE' => __( 'León', 'woocommerce' ), 'L' => __( 'Lleida', 'woocommerce' ), 'LU' => __( 'Lugo', 'woocommerce' ), 'M' => __( 'Madrid', 'woocommerce' ), - 'MA' => __( 'Málaga', 'woocommerce' ), + 'MA' => __( 'Málaga', 'woocommerce' ), 'ML' => __( 'Melilla', 'woocommerce' ), 'MU' => __( 'Murcia', 'woocommerce' ), 'NA' => __( 'Navarra', 'woocommerce' ), @@ -856,48 +856,48 @@ return array( ), 'LU' => array(), 'MD' => array( // Moldova states. - 'C' => __( 'Chișinău', 'woocommerce' ), - 'BL' => __( 'Bălți', 'woocommerce' ), + 'C' => __( 'Chișinău', 'woocommerce' ), + 'BL' => __( 'Bălți', 'woocommerce' ), 'AN' => __( 'Anenii Noi', 'woocommerce' ), 'BS' => __( 'Basarabeasca', 'woocommerce' ), 'BR' => __( 'Briceni', 'woocommerce' ), 'CH' => __( 'Cahul', 'woocommerce' ), 'CT' => __( 'Cantemir', 'woocommerce' ), - 'CL' => __( 'Călărași', 'woocommerce' ), - 'CS' => __( 'Căușeni', 'woocommerce' ), - 'CM' => __( 'Cimișlia', 'woocommerce' ), + 'CL' => __( 'Călărași', 'woocommerce' ), + 'CS' => __( 'Căușeni', 'woocommerce' ), + 'CM' => __( 'Cimișlia', 'woocommerce' ), 'CR' => __( 'Criuleni', 'woocommerce' ), - 'DN' => __( 'Dondușeni', 'woocommerce' ), + 'DN' => __( 'Dondușeni', 'woocommerce' ), 'DR' => __( 'Drochia', 'woocommerce' ), - 'DB' => __( 'Dubăsari', 'woocommerce' ), - 'ED' => __( 'Edineț', 'woocommerce' ), - 'FL' => __( 'Fălești', 'woocommerce' ), - 'FR' => __( 'Florești', 'woocommerce' ), - 'GE' => __( 'UTA Găgăuzia', 'woocommerce' ), + 'DB' => __( 'Dubăsari', 'woocommerce' ), + 'ED' => __( 'Edineț', 'woocommerce' ), + 'FL' => __( 'Fălești', 'woocommerce' ), + 'FR' => __( 'Florești', 'woocommerce' ), + 'GE' => __( 'UTA Găgăuzia', 'woocommerce' ), 'GL' => __( 'Glodeni', 'woocommerce' ), - 'HN' => __( 'Hîncești', 'woocommerce' ), + 'HN' => __( 'Hîncești', 'woocommerce' ), 'IL' => __( 'Ialoveni', 'woocommerce' ), 'LV' => __( 'Leova', 'woocommerce' ), 'NS' => __( 'Nisporeni', 'woocommerce' ), - 'OC' => __( 'Ocnița', 'woocommerce' ), + 'OC' => __( 'Ocnița', 'woocommerce' ), 'OR' => __( 'Orhei', 'woocommerce' ), 'RZ' => __( 'Rezina', 'woocommerce' ), - 'RS' => __( 'Rîșcani', 'woocommerce' ), - 'SG' => __( 'Sîngerei', 'woocommerce' ), + 'RS' => __( 'Rîșcani', 'woocommerce' ), + 'SG' => __( 'Sîngerei', 'woocommerce' ), 'SR' => __( 'Soroca', 'woocommerce' ), - 'ST' => __( 'Strășeni', 'woocommerce' ), - 'SD' => __( 'Șoldănești', 'woocommerce' ), - 'SV' => __( 'Ștefan Vodă', 'woocommerce' ), + 'ST' => __( 'Strășeni', 'woocommerce' ), + 'SD' => __( 'Șoldănești', 'woocommerce' ), + 'SV' => __( 'Ștefan Vodă', 'woocommerce' ), 'TR' => __( 'Taraclia', 'woocommerce' ), - 'TL' => __( 'Telenești', 'woocommerce' ), + 'TL' => __( 'Telenești', 'woocommerce' ), 'UN' => __( 'Ungheni', 'woocommerce' ), ), 'MQ' => array(), 'MT' => array(), 'MX' => array( // Mexico States. - 'DF' => __( 'Ciudad de México', 'woocommerce' ), + 'DF' => __( 'Ciudad de México', 'woocommerce' ), 'JA' => __( 'Jalisco', 'woocommerce' ), - 'NL' => __( 'Nuevo León', 'woocommerce' ), + 'NL' => __( 'Nuevo León', 'woocommerce' ), 'AG' => __( 'Aguascalientes', 'woocommerce' ), 'BC' => __( 'Baja California', 'woocommerce' ), 'BS' => __( 'Baja California Sur', 'woocommerce' ), @@ -910,22 +910,22 @@ return array( 'GT' => __( 'Guanajuato', 'woocommerce' ), 'GR' => __( 'Guerrero', 'woocommerce' ), 'HG' => __( 'Hidalgo', 'woocommerce' ), - 'MX' => __( 'Estado de México', 'woocommerce' ), - 'MI' => __( 'Michoacán', 'woocommerce' ), + 'MX' => __( 'Estado de México', 'woocommerce' ), + 'MI' => __( 'Michoacán', 'woocommerce' ), 'MO' => __( 'Morelos', 'woocommerce' ), 'NA' => __( 'Nayarit', 'woocommerce' ), 'OA' => __( 'Oaxaca', 'woocommerce' ), 'PU' => __( 'Puebla', 'woocommerce' ), - 'QT' => __( 'Querétaro', 'woocommerce' ), + 'QT' => __( 'Querétaro', 'woocommerce' ), 'QR' => __( 'Quintana Roo', 'woocommerce' ), - 'SL' => __( 'San Luis Potosí', 'woocommerce' ), + 'SL' => __( 'San Luis Potosí', 'woocommerce' ), 'SI' => __( 'Sinaloa', 'woocommerce' ), 'SO' => __( 'Sonora', 'woocommerce' ), 'TB' => __( 'Tabasco', 'woocommerce' ), 'TM' => __( 'Tamaulipas', 'woocommerce' ), 'TL' => __( 'Tlaxcala', 'woocommerce' ), 'VE' => __( 'Veracruz', 'woocommerce' ), - 'YU' => __( 'Yucatán', 'woocommerce' ), + 'YU' => __( 'Yucatán', 'woocommerce' ), 'ZA' => __( 'Zacatecas', 'woocommerce' ), ), 'MY' => array( // Malaysian states. @@ -1039,7 +1039,7 @@ return array( 'BP' => __( 'Bay of Plenty', 'woocommerce' ), 'TK' => __( 'Taranaki', 'woocommerce' ), 'GI' => __( 'Gisborne', 'woocommerce' ), - 'HB' => __( 'Hawke’s Bay', 'woocommerce' ), + 'HB' => __( 'Hawke’s Bay', 'woocommerce' ), 'MW' => __( 'Manawatu-Wanganui', 'woocommerce' ), 'WE' => __( 'Wellington', 'woocommerce' ), 'NS' => __( 'Nelson', 'woocommerce' ), @@ -1055,15 +1055,15 @@ return array( 'LMA' => __( 'Municipalidad Metropolitana de Lima', 'woocommerce' ), 'AMA' => __( 'Amazonas', 'woocommerce' ), 'ANC' => __( 'Ancash', 'woocommerce' ), - 'APU' => __( 'Apurímac', 'woocommerce' ), + 'APU' => __( 'Apurímac', 'woocommerce' ), 'ARE' => __( 'Arequipa', 'woocommerce' ), 'AYA' => __( 'Ayacucho', 'woocommerce' ), 'CAJ' => __( 'Cajamarca', 'woocommerce' ), 'CUS' => __( 'Cusco', 'woocommerce' ), 'HUV' => __( 'Huancavelica', 'woocommerce' ), - 'HUC' => __( 'Huánuco', 'woocommerce' ), + 'HUC' => __( 'Huánuco', 'woocommerce' ), 'ICA' => __( 'Ica', 'woocommerce' ), - 'JUN' => __( 'Junín', 'woocommerce' ), + 'JUN' => __( 'Junín', 'woocommerce' ), 'LAL' => __( 'La Libertad', 'woocommerce' ), 'LAM' => __( 'Lambayeque', 'woocommerce' ), 'LIM' => __( 'Lima', 'woocommerce' ), @@ -1073,7 +1073,7 @@ return array( 'PAS' => __( 'Pasco', 'woocommerce' ), 'PIU' => __( 'Piura', 'woocommerce' ), 'PUN' => __( 'Puno', 'woocommerce' ), - 'SAM' => __( 'San Martín', 'woocommerce' ), + 'SAM' => __( 'San Martín', 'woocommerce' ), 'TAC' => __( 'Tacna', 'woocommerce' ), 'TUM' => __( 'Tumbes', 'woocommerce' ), 'UCA' => __( 'Ucayali', 'woocommerce' ), @@ -1179,67 +1179,67 @@ return array( 'PL' => array(), 'PT' => array(), 'PY' => array( // Paraguay states. - 'PY-ASU' => __( 'Asunción', 'woocommerce' ), - 'PY-1' => __( 'Concepción', 'woocommerce' ), + 'PY-ASU' => __( 'Asunción', 'woocommerce' ), + 'PY-1' => __( 'Concepción', 'woocommerce' ), 'PY-2' => __( 'San Pedro', 'woocommerce' ), 'PY-3' => __( 'Cordillera', 'woocommerce' ), - 'PY-4' => __( 'Guairá', 'woocommerce' ), - 'PY-5' => __( 'Caaguazú', 'woocommerce' ), - 'PY-6' => __( 'Caazapá', 'woocommerce' ), - 'PY-7' => __( 'Itapúa', 'woocommerce' ), + 'PY-4' => __( 'Guairá', 'woocommerce' ), + 'PY-5' => __( 'Caaguazú', 'woocommerce' ), + 'PY-6' => __( 'Caazapá', 'woocommerce' ), + 'PY-7' => __( 'Itapúa', 'woocommerce' ), 'PY-8' => __( 'Misiones', 'woocommerce' ), - 'PY-9' => __( 'Paraguarí', 'woocommerce' ), - 'PY-10' => __( 'Alto Paraná', 'woocommerce' ), + 'PY-9' => __( 'Paraguarí', 'woocommerce' ), + 'PY-10' => __( 'Alto Paraná', 'woocommerce' ), 'PY-11' => __( 'Central', 'woocommerce' ), - 'PY-12' => __( 'Ñeembucú', 'woocommerce' ), + 'PY-12' => __( 'Ñeembucú', 'woocommerce' ), 'PY-13' => __( 'Amambay', 'woocommerce' ), - 'PY-14' => __( 'Canindeyú', 'woocommerce' ), + 'PY-14' => __( 'Canindeyú', 'woocommerce' ), 'PY-15' => __( 'Presidente Hayes', 'woocommerce' ), 'PY-16' => __( 'Alto Paraguay', 'woocommerce' ), - 'PY-17' => __( 'Boquerón', 'woocommerce' ), + 'PY-17' => __( 'Boquerón', 'woocommerce' ), ), 'RE' => array(), 'RO' => array( // Romania states. 'AB' => __( 'Alba', 'woocommerce' ), 'AR' => __( 'Arad', 'woocommerce' ), - 'AG' => __( 'Argeș', 'woocommerce' ), - 'BC' => __( 'Bacău', 'woocommerce' ), + 'AG' => __( 'Argeș', 'woocommerce' ), + 'BC' => __( 'Bacău', 'woocommerce' ), 'BH' => __( 'Bihor', 'woocommerce' ), - 'BN' => __( 'Bistrița-Năsăud', 'woocommerce' ), - 'BT' => __( 'Botoșani', 'woocommerce' ), - 'BR' => __( 'Brăila', 'woocommerce' ), - 'BV' => __( 'Brașov', 'woocommerce' ), - 'B' => __( 'București', 'woocommerce' ), - 'BZ' => __( 'Buzău', 'woocommerce' ), - 'CL' => __( 'Călărași', 'woocommerce' ), - 'CS' => __( 'Caraș-Severin', 'woocommerce' ), + 'BN' => __( 'Bistrița-Năsăud', 'woocommerce' ), + 'BT' => __( 'Botoșani', 'woocommerce' ), + 'BR' => __( 'Brăila', 'woocommerce' ), + 'BV' => __( 'Brașov', 'woocommerce' ), + 'B' => __( 'București', 'woocommerce' ), + 'BZ' => __( 'Buzău', 'woocommerce' ), + 'CL' => __( 'Călărași', 'woocommerce' ), + 'CS' => __( 'Caraș-Severin', 'woocommerce' ), 'CJ' => __( 'Cluj', 'woocommerce' ), - 'CT' => __( 'Constanța', 'woocommerce' ), + 'CT' => __( 'Constanța', 'woocommerce' ), 'CV' => __( 'Covasna', 'woocommerce' ), - 'DB' => __( 'Dâmbovița', 'woocommerce' ), + 'DB' => __( 'Dâmbovița', 'woocommerce' ), 'DJ' => __( 'Dolj', 'woocommerce' ), - 'GL' => __( 'Galați', 'woocommerce' ), + 'GL' => __( 'Galați', 'woocommerce' ), 'GR' => __( 'Giurgiu', 'woocommerce' ), 'GJ' => __( 'Gorj', 'woocommerce' ), 'HR' => __( 'Harghita', 'woocommerce' ), 'HD' => __( 'Hunedoara', 'woocommerce' ), - 'IL' => __( 'Ialomița', 'woocommerce' ), - 'IS' => __( 'Iași', 'woocommerce' ), + 'IL' => __( 'Ialomița', 'woocommerce' ), + 'IS' => __( 'Iași', 'woocommerce' ), 'IF' => __( 'Ilfov', 'woocommerce' ), - 'MM' => __( 'Maramureș', 'woocommerce' ), - 'MH' => __( 'Mehedinți', 'woocommerce' ), - 'MS' => __( 'Mureș', 'woocommerce' ), - 'NT' => __( 'Neamț', 'woocommerce' ), + 'MM' => __( 'Maramureș', 'woocommerce' ), + 'MH' => __( 'Mehedinți', 'woocommerce' ), + 'MS' => __( 'Mureș', 'woocommerce' ), + 'NT' => __( 'Neamț', 'woocommerce' ), 'OT' => __( 'Olt', 'woocommerce' ), 'PH' => __( 'Prahova', 'woocommerce' ), - 'SJ' => __( 'Sălaj', 'woocommerce' ), + 'SJ' => __( 'Sălaj', 'woocommerce' ), 'SM' => __( 'Satu Mare', 'woocommerce' ), 'SB' => __( 'Sibiu', 'woocommerce' ), 'SV' => __( 'Suceava', 'woocommerce' ), 'TR' => __( 'Teleorman', 'woocommerce' ), - 'TM' => __( 'Timiș', 'woocommerce' ), + 'TM' => __( 'Timiș', 'woocommerce' ), 'TL' => __( 'Tulcea', 'woocommerce' ), - 'VL' => __( 'Vâlcea', 'woocommerce' ), + 'VL' => __( 'Vâlcea', 'woocommerce' ), 'VS' => __( 'Vaslui', 'woocommerce' ), 'VN' => __( 'Vrancea', 'woocommerce' ), ), @@ -1328,56 +1328,56 @@ return array( ), 'TR' => array( // Turkey States. 'TR01' => __( 'Adana', 'woocommerce' ), - 'TR02' => __( 'Adıyaman', 'woocommerce' ), + 'TR02' => __( 'Adıyaman', 'woocommerce' ), 'TR03' => __( 'Afyon', 'woocommerce' ), - 'TR04' => __( 'Ağrı', 'woocommerce' ), + 'TR04' => __( 'Ağrı', 'woocommerce' ), 'TR05' => __( 'Amasya', 'woocommerce' ), 'TR06' => __( 'Ankara', 'woocommerce' ), 'TR07' => __( 'Antalya', 'woocommerce' ), 'TR08' => __( 'Artvin', 'woocommerce' ), - 'TR09' => __( 'Aydın', 'woocommerce' ), - 'TR10' => __( 'Balıkesir', 'woocommerce' ), + 'TR09' => __( 'Aydın', 'woocommerce' ), + 'TR10' => __( 'Balıkesir', 'woocommerce' ), 'TR11' => __( 'Bilecik', 'woocommerce' ), - 'TR12' => __( 'Bingöl', 'woocommerce' ), + 'TR12' => __( 'Bingöl', 'woocommerce' ), 'TR13' => __( 'Bitlis', 'woocommerce' ), 'TR14' => __( 'Bolu', 'woocommerce' ), 'TR15' => __( 'Burdur', 'woocommerce' ), 'TR16' => __( 'Bursa', 'woocommerce' ), - 'TR17' => __( 'Çanakkale', 'woocommerce' ), - 'TR18' => __( 'Çankırı', 'woocommerce' ), - 'TR19' => __( 'Çorum', 'woocommerce' ), + 'TR17' => __( 'Çanakkale', 'woocommerce' ), + 'TR18' => __( 'Çankırı', 'woocommerce' ), + 'TR19' => __( 'Çorum', 'woocommerce' ), 'TR20' => __( 'Denizli', 'woocommerce' ), - 'TR21' => __( 'Diyarbakır', 'woocommerce' ), + 'TR21' => __( 'Diyarbakır', 'woocommerce' ), 'TR22' => __( 'Edirne', 'woocommerce' ), - 'TR23' => __( 'Elazığ', 'woocommerce' ), + 'TR23' => __( 'Elazığ', 'woocommerce' ), 'TR24' => __( 'Erzincan', 'woocommerce' ), 'TR25' => __( 'Erzurum', 'woocommerce' ), - 'TR26' => __( 'Eskişehir', 'woocommerce' ), + 'TR26' => __( 'Eskişehir', 'woocommerce' ), 'TR27' => __( 'Gaziantep', 'woocommerce' ), 'TR28' => __( 'Giresun', 'woocommerce' ), - 'TR29' => __( 'Gümüşhane', 'woocommerce' ), + 'TR29' => __( 'Gümüşhane', 'woocommerce' ), 'TR30' => __( 'Hakkari', 'woocommerce' ), 'TR31' => __( 'Hatay', 'woocommerce' ), 'TR32' => __( 'Isparta', 'woocommerce' ), - 'TR33' => __( 'İçel', 'woocommerce' ), - 'TR34' => __( 'İstanbul', 'woocommerce' ), - 'TR35' => __( 'İzmir', 'woocommerce' ), + 'TR33' => __( 'İçel', 'woocommerce' ), + 'TR34' => __( 'İstanbul', 'woocommerce' ), + 'TR35' => __( 'İzmir', 'woocommerce' ), 'TR36' => __( 'Kars', 'woocommerce' ), 'TR37' => __( 'Kastamonu', 'woocommerce' ), 'TR38' => __( 'Kayseri', 'woocommerce' ), - 'TR39' => __( 'Kırklareli', 'woocommerce' ), - 'TR40' => __( 'Kırşehir', 'woocommerce' ), + 'TR39' => __( 'Kırklareli', 'woocommerce' ), + 'TR40' => __( 'Kırşehir', 'woocommerce' ), 'TR41' => __( 'Kocaeli', 'woocommerce' ), 'TR42' => __( 'Konya', 'woocommerce' ), - 'TR43' => __( 'Kütahya', 'woocommerce' ), + 'TR43' => __( 'Kütahya', 'woocommerce' ), 'TR44' => __( 'Malatya', 'woocommerce' ), 'TR45' => __( 'Manisa', 'woocommerce' ), - 'TR46' => __( 'Kahramanmaraş', 'woocommerce' ), + 'TR46' => __( 'Kahramanmaraş', 'woocommerce' ), 'TR47' => __( 'Mardin', 'woocommerce' ), - 'TR48' => __( 'Muğla', 'woocommerce' ), - 'TR49' => __( 'Muş', 'woocommerce' ), - 'TR50' => __( 'Nevşehir', 'woocommerce' ), - 'TR51' => __( 'Niğde', 'woocommerce' ), + 'TR48' => __( 'Muğla', 'woocommerce' ), + 'TR49' => __( 'Muş', 'woocommerce' ), + 'TR50' => __( 'Nevşehir', 'woocommerce' ), + 'TR51' => __( 'Niğde', 'woocommerce' ), 'TR52' => __( 'Ordu', 'woocommerce' ), 'TR53' => __( 'Rize', 'woocommerce' ), 'TR54' => __( 'Sakarya', 'woocommerce' ), @@ -1385,29 +1385,29 @@ return array( 'TR56' => __( 'Siirt', 'woocommerce' ), 'TR57' => __( 'Sinop', 'woocommerce' ), 'TR58' => __( 'Sivas', 'woocommerce' ), - 'TR59' => __( 'Tekirdağ', 'woocommerce' ), + 'TR59' => __( 'Tekirdağ', 'woocommerce' ), 'TR60' => __( 'Tokat', 'woocommerce' ), 'TR61' => __( 'Trabzon', 'woocommerce' ), 'TR62' => __( 'Tunceli', 'woocommerce' ), - 'TR63' => __( 'Şanlıurfa', 'woocommerce' ), - 'TR64' => __( 'Uşak', 'woocommerce' ), + 'TR63' => __( 'Şanlıurfa', 'woocommerce' ), + 'TR64' => __( 'Uşak', 'woocommerce' ), 'TR65' => __( 'Van', 'woocommerce' ), 'TR66' => __( 'Yozgat', 'woocommerce' ), 'TR67' => __( 'Zonguldak', 'woocommerce' ), 'TR68' => __( 'Aksaray', 'woocommerce' ), 'TR69' => __( 'Bayburt', 'woocommerce' ), 'TR70' => __( 'Karaman', 'woocommerce' ), - 'TR71' => __( 'Kırıkkale', 'woocommerce' ), + 'TR71' => __( 'Kırıkkale', 'woocommerce' ), 'TR72' => __( 'Batman', 'woocommerce' ), - 'TR73' => __( 'Şırnak', 'woocommerce' ), - 'TR74' => __( 'Bartın', 'woocommerce' ), + 'TR73' => __( 'Şırnak', 'woocommerce' ), + 'TR74' => __( 'Bartın', 'woocommerce' ), 'TR75' => __( 'Ardahan', 'woocommerce' ), - 'TR76' => __( 'Iğdır', 'woocommerce' ), + 'TR76' => __( 'Iğdır', 'woocommerce' ), 'TR77' => __( 'Yalova', 'woocommerce' ), - 'TR78' => __( 'Karabük', 'woocommerce' ), + 'TR78' => __( 'Karabük', 'woocommerce' ), 'TR79' => __( 'Kilis', 'woocommerce' ), 'TR80' => __( 'Osmaniye', 'woocommerce' ), - 'TR81' => __( 'Düzce', 'woocommerce' ), + 'TR81' => __( 'Düzce', 'woocommerce' ), ), 'TZ' => array( // Tanzania States. 'TZ01' => __( 'Arusha', 'woocommerce' ), From 5a410c02a623829b2f4e113edfccf931710d383d Mon Sep 17 00:00:00 2001 From: Tam Mullen Date: Wed, 5 Aug 2020 12:49:42 +0100 Subject: [PATCH 413/440] Fix e2e OBW test to not untick physical products in product type list --- tests/e2e/utils/components.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/utils/components.js b/tests/e2e/utils/components.js index 0e6e721c4b0..a9bb6602d6e 100644 --- a/tests/e2e/utils/components.js +++ b/tests/e2e/utils/components.js @@ -116,7 +116,7 @@ const completeOnboardingWizard = async () => { expect( productTypesCheckboxes ).toHaveLength( 8 ); // Select Physical and Downloadable products - for ( let i = 0; i < 2; i++ ) { + for ( let i = 1; i < 2; i++ ) { await productTypesCheckboxes[i].click(); } From d48f1d4e2efcfab8206799df2085f021ec273722 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 5 Aug 2020 13:36:24 -0300 Subject: [PATCH 414/440] Fixed package tag usage --- i18n/continents.php | 2 +- i18n/locale-info.php | 2 +- i18n/phone.php | 2 +- includes/abstracts/abstract-wc-data.php | 4 ++-- includes/abstracts/abstract-wc-integration.php | 4 ++-- includes/abstracts/abstract-wc-log-handler.php | 4 ++-- includes/abstracts/abstract-wc-object-query.php | 4 ++-- includes/abstracts/abstract-wc-order.php | 2 +- includes/abstracts/abstract-wc-payment-gateway.php | 4 ++-- includes/abstracts/abstract-wc-payment-token.php | 4 ++-- includes/abstracts/abstract-wc-privacy.php | 4 ++-- includes/abstracts/abstract-wc-product.php | 4 ++-- includes/abstracts/abstract-wc-session.php | 2 +- includes/abstracts/abstract-wc-settings-api.php | 2 +- includes/abstracts/abstract-wc-shipping-method.php | 4 ++-- includes/abstracts/abstract-wc-widget.php | 4 ++-- includes/abstracts/class-wc-background-process.php | 2 +- includes/admin/class-wc-admin-addons.php | 2 +- includes/admin/class-wc-admin-assets.php | 2 +- includes/admin/class-wc-admin-attributes.php | 2 +- includes/admin/class-wc-admin-customize.php | 2 +- includes/admin/class-wc-admin-dashboard.php | 2 +- includes/admin/class-wc-admin-duplicate-product.php | 2 +- includes/admin/class-wc-admin-exporters.php | 2 +- includes/admin/class-wc-admin-help.php | 2 +- includes/admin/class-wc-admin-importers.php | 2 +- includes/admin/class-wc-admin-log-table-list.php | 2 +- includes/admin/class-wc-admin-meta-boxes.php | 2 +- includes/admin/class-wc-admin-permalink-settings.php | 2 +- includes/admin/class-wc-admin-pointers.php | 2 +- includes/admin/class-wc-admin-post-types.php | 2 +- includes/admin/class-wc-admin-profile.php | 2 +- includes/admin/class-wc-admin-reports.php | 2 +- includes/admin/class-wc-admin-settings.php | 2 +- includes/admin/class-wc-admin-setup-wizard.php | 2 +- includes/admin/class-wc-admin-status.php | 2 +- includes/admin/class-wc-admin-taxonomies.php | 2 +- includes/admin/class-wc-admin.php | 2 +- includes/admin/helper/class-wc-helper-api.php | 2 +- includes/admin/helper/class-wc-helper-updater.php | 2 +- includes/admin/helper/class-wc-helper.php | 2 +- includes/admin/helper/views/html-section-nav.php | 2 +- .../importers/class-wc-product-csv-importer-controller.php | 2 +- includes/admin/importers/class-wc-tax-rate-importer.php | 4 ++-- .../admin/importers/views/html-product-csv-import-form.php | 2 +- .../admin/list-tables/abstract-class-wc-admin-list-table.php | 2 +- .../admin/list-tables/class-wc-admin-list-table-coupons.php | 2 +- .../admin/list-tables/class-wc-admin-list-table-products.php | 2 +- includes/admin/marketplace-suggestions/views/container.php | 2 +- includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php | 2 +- includes/admin/meta-boxes/class-wc-meta-box-order-actions.php | 2 +- includes/admin/meta-boxes/class-wc-meta-box-order-data.php | 2 +- .../admin/meta-boxes/class-wc-meta-box-order-downloads.php | 2 +- includes/admin/meta-boxes/class-wc-meta-box-order-items.php | 2 +- includes/admin/meta-boxes/class-wc-meta-box-order-notes.php | 2 +- includes/admin/meta-boxes/class-wc-meta-box-product-data.php | 2 +- .../admin/meta-boxes/class-wc-meta-box-product-images.php | 2 +- .../admin/meta-boxes/class-wc-meta-box-product-reviews.php | 2 +- .../class-wc-meta-box-product-short-description.php | 2 +- includes/admin/meta-boxes/views/html-order-item.php | 2 +- includes/admin/meta-boxes/views/html-order-items.php | 2 +- includes/admin/meta-boxes/views/html-order-notes.php | 2 +- includes/admin/meta-boxes/views/html-order-shipping.php | 4 ++-- includes/admin/meta-boxes/views/html-product-data-general.php | 2 +- .../meta-boxes/views/html-product-data-linked-products.php | 2 +- includes/admin/meta-boxes/views/html-product-data-panel.php | 2 +- includes/admin/plugin-updates/class-wc-plugin-updates.php | 2 +- .../admin/plugin-updates/class-wc-plugins-screen-updates.php | 2 +- .../admin/plugin-updates/class-wc-updates-screen-updates.php | 2 +- includes/admin/reports/class-wc-admin-report.php | 2 +- includes/admin/reports/class-wc-report-coupon-usage.php | 4 ++-- includes/admin/reports/class-wc-report-customer-list.php | 2 +- includes/admin/reports/class-wc-report-customers.php | 2 +- includes/admin/reports/class-wc-report-downloads.php | 2 +- includes/admin/reports/class-wc-report-low-in-stock.php | 2 +- includes/admin/reports/class-wc-report-most-stocked.php | 2 +- includes/admin/reports/class-wc-report-out-of-stock.php | 2 +- includes/admin/reports/class-wc-report-sales-by-category.php | 4 ++-- includes/admin/reports/class-wc-report-sales-by-date.php | 2 +- includes/admin/reports/class-wc-report-sales-by-product.php | 4 ++-- includes/admin/reports/class-wc-report-stock.php | 2 +- includes/admin/reports/class-wc-report-taxes-by-code.php | 4 ++-- includes/admin/reports/class-wc-report-taxes-by-date.php | 2 +- includes/admin/settings/class-wc-settings-accounts.php | 2 +- includes/admin/settings/class-wc-settings-advanced.php | 2 +- includes/admin/settings/class-wc-settings-emails.php | 2 +- includes/admin/settings/class-wc-settings-general.php | 2 +- includes/admin/settings/class-wc-settings-integrations.php | 2 +- includes/admin/settings/class-wc-settings-page.php | 2 +- .../admin/settings/class-wc-settings-payment-gateways.php | 2 +- includes/admin/settings/class-wc-settings-products.php | 2 +- includes/admin/settings/class-wc-settings-shipping.php | 2 +- includes/admin/settings/class-wc-settings-tax.php | 2 +- .../admin/settings/views/html-admin-page-shipping-classes.php | 2 +- .../settings/views/html-admin-page-shipping-zone-methods.php | 2 +- includes/admin/settings/views/html-keys-edit.php | 2 +- includes/admin/settings/views/html-webhooks-edit.php | 2 +- includes/admin/views/html-admin-page-addons.php | 2 +- includes/admin/views/html-admin-page-product-export.php | 2 +- includes/admin/views/html-admin-page-status-logs-db.php | 2 +- includes/admin/views/html-admin-page-status-logs.php | 2 +- .../admin/views/html-notice-regenerating-lookup-table.php | 2 +- includes/admin/views/html-notice-template-check.php | 2 +- includes/admin/views/html-report-by-date.php | 2 +- includes/admin/wc-admin-functions.php | 2 +- includes/admin/wc-meta-box-functions.php | 2 +- includes/class-wc-ajax.php | 2 +- includes/class-wc-api.php | 2 +- includes/class-wc-auth.php | 2 +- includes/class-wc-autoloader.php | 2 +- includes/class-wc-background-emailer.php | 2 +- includes/class-wc-background-updater.php | 2 +- includes/class-wc-breadcrumb.php | 2 +- includes/class-wc-cache-helper.php | 2 +- includes/class-wc-cart-fees.php | 2 +- includes/class-wc-cart-session.php | 2 +- includes/class-wc-cart-totals.php | 2 +- includes/class-wc-cart.php | 2 +- includes/class-wc-checkout.php | 2 +- includes/class-wc-comments.php | 2 +- includes/class-wc-coupon.php | 2 +- includes/class-wc-customer-download-log.php | 2 +- includes/class-wc-customer-download.php | 2 +- includes/class-wc-customer.php | 2 +- includes/class-wc-datetime.php | 2 +- includes/class-wc-discounts.php | 2 +- includes/class-wc-download-handler.php | 2 +- includes/class-wc-emails.php | 2 +- includes/class-wc-embed.php | 2 +- includes/class-wc-form-handler.php | 2 +- includes/class-wc-frontend-scripts.php | 2 +- includes/class-wc-geo-ip.php | 2 +- includes/class-wc-geolocation.php | 2 +- includes/class-wc-https.php | 2 +- includes/class-wc-install.php | 2 +- includes/class-wc-integrations.php | 2 +- includes/class-wc-log-levels.php | 2 +- includes/class-wc-logger.php | 2 +- includes/class-wc-order-factory.php | 2 +- includes/class-wc-order-item-coupon.php | 2 +- includes/class-wc-order-item-fee.php | 2 +- includes/class-wc-order-item-meta.php | 2 +- includes/class-wc-order-item-product.php | 2 +- includes/class-wc-order-item-shipping.php | 2 +- includes/class-wc-order-item-tax.php | 2 +- includes/class-wc-order-item.php | 2 +- includes/class-wc-order-query.php | 2 +- includes/class-wc-order-refund.php | 2 +- includes/class-wc-payment-gateways.php | 2 +- includes/class-wc-payment-tokens.php | 2 +- includes/class-wc-post-data.php | 2 +- includes/class-wc-post-types.php | 2 +- includes/class-wc-privacy-background-process.php | 2 +- includes/class-wc-product-attribute.php | 2 +- includes/class-wc-product-download.php | 2 +- includes/class-wc-product-external.php | 2 +- includes/class-wc-product-factory.php | 2 +- includes/class-wc-product-query.php | 2 +- includes/class-wc-product-simple.php | 2 +- includes/class-wc-product-variable.php | 2 +- includes/class-wc-product-variation.php | 2 +- includes/class-wc-rate-limiter.php | 2 +- includes/class-wc-regenerate-images-request.php | 2 +- includes/class-wc-regenerate-images.php | 2 +- includes/class-wc-register-wp-admin-settings.php | 2 +- includes/class-wc-rest-authentication.php | 2 +- includes/class-wc-rest-exception.php | 2 +- includes/class-wc-session-handler.php | 2 +- includes/class-wc-shipping-rate.php | 2 +- includes/class-wc-shipping-zone.php | 2 +- includes/class-wc-shipping-zones.php | 2 +- includes/class-wc-shipping.php | 2 +- includes/class-wc-shortcodes.php | 2 +- includes/class-wc-structured-data.php | 2 +- includes/class-wc-tax.php | 2 +- includes/class-wc-template-loader.php | 2 +- includes/class-wc-tracker.php | 2 +- includes/class-wc-webhook.php | 2 +- includes/data-stores/abstract-wc-order-data-store-cpt.php | 2 +- includes/data-stores/class-wc-data-store-wp.php | 2 +- includes/data-stores/class-wc-order-data-store-cpt.php | 2 +- includes/data-stores/class-wc-product-data-store-cpt.php | 2 +- .../data-stores/class-wc-product-variable-data-store-cpt.php | 2 +- includes/data-stores/class-wc-webhook-data-store.php | 2 +- includes/emails/class-wc-email-cancelled-order.php | 2 +- includes/emails/class-wc-email-customer-completed-order.php | 2 +- includes/emails/class-wc-email-customer-invoice.php | 2 +- includes/emails/class-wc-email-customer-new-account.php | 2 +- includes/emails/class-wc-email-customer-note.php | 2 +- includes/emails/class-wc-email-customer-on-hold-order.php | 2 +- includes/emails/class-wc-email-customer-processing-order.php | 2 +- includes/emails/class-wc-email-customer-refunded-order.php | 2 +- includes/emails/class-wc-email-customer-reset-password.php | 2 +- includes/emails/class-wc-email-failed-order.php | 2 +- includes/emails/class-wc-email-new-order.php | 2 +- includes/emails/class-wc-email.php | 2 +- includes/export/abstract-wc-csv-batch-exporter.php | 2 +- includes/export/abstract-wc-csv-exporter.php | 2 +- includes/export/class-wc-product-csv-exporter.php | 2 +- includes/gateways/bacs/class-wc-gateway-bacs.php | 2 +- includes/gateways/cheque/class-wc-gateway-cheque.php | 2 +- includes/gateways/class-wc-payment-gateway-cc.php | 2 +- includes/gateways/class-wc-payment-gateway-echeck.php | 2 +- includes/gateways/cod/class-wc-gateway-cod.php | 2 +- includes/gateways/paypal/class-wc-gateway-paypal.php | 2 +- .../paypal/includes/class-wc-gateway-paypal-ipn-handler.php | 2 +- includes/gateways/paypal/includes/settings-paypal.php | 2 +- includes/import/abstract-wc-product-importer.php | 2 +- includes/import/class-wc-product-csv-importer.php | 2 +- .../class-wc-integration-maxmind-database-service.php | 2 +- .../class-wc-integration-maxmind-geolocation.php | 2 +- .../class-wc-abstract-order-data-store-interface.php | 2 +- includes/interfaces/class-wc-coupon-data-store-interface.php | 2 +- .../interfaces/class-wc-customer-data-store-interface.php | 2 +- .../class-wc-customer-download-data-store-interface.php | 2 +- .../class-wc-customer-download-log-data-store-interface.php | 2 +- includes/interfaces/class-wc-importer-interface.php | 2 +- includes/interfaces/class-wc-log-handler-interface.php | 2 +- includes/interfaces/class-wc-logger-interface.php | 2 +- includes/interfaces/class-wc-object-data-store-interface.php | 2 +- includes/interfaces/class-wc-order-data-store-interface.php | 2 +- .../interfaces/class-wc-order-item-data-store-interface.php | 2 +- .../class-wc-order-item-product-data-store-interface.php | 2 +- .../class-wc-order-item-type-data-store-interface.php | 2 +- .../interfaces/class-wc-order-refund-data-store-interface.php | 2 +- .../class-wc-payment-token-data-store-interface.php | 2 +- includes/interfaces/class-wc-product-data-store-interface.php | 2 +- .../class-wc-product-variable-data-store-interface.php | 2 +- includes/interfaces/class-wc-queue-interface.php | 2 +- .../class-wc-shipping-zone-data-store-interface.php | 2 +- .../interfaces/class-wc-webhooks-data-store-interface.php | 2 +- includes/legacy/abstract-wc-legacy-order.php | 2 +- includes/legacy/abstract-wc-legacy-payment-token.php | 2 +- includes/legacy/abstract-wc-legacy-product.php | 2 +- .../legacy/api/class-wc-rest-legacy-coupons-controller.php | 4 ++-- .../legacy/api/class-wc-rest-legacy-orders-controller.php | 4 ++-- .../legacy/api/class-wc-rest-legacy-products-controller.php | 4 ++-- includes/legacy/api/v1/class-wc-api-authentication.php | 2 +- includes/legacy/api/v1/class-wc-api-coupons.php | 2 +- includes/legacy/api/v1/class-wc-api-customers.php | 2 +- includes/legacy/api/v1/class-wc-api-json-handler.php | 2 +- includes/legacy/api/v1/class-wc-api-orders.php | 2 +- includes/legacy/api/v1/class-wc-api-products.php | 2 +- includes/legacy/api/v1/class-wc-api-reports.php | 2 +- includes/legacy/api/v1/class-wc-api-resource.php | 2 +- includes/legacy/api/v1/class-wc-api-server.php | 2 +- includes/legacy/api/v1/class-wc-api-xml-handler.php | 2 +- includes/legacy/api/v1/interface-wc-api-handler.php | 2 +- includes/legacy/api/v2/class-wc-api-authentication.php | 2 +- includes/legacy/api/v2/class-wc-api-coupons.php | 2 +- includes/legacy/api/v2/class-wc-api-customers.php | 2 +- includes/legacy/api/v2/class-wc-api-exception.php | 2 +- includes/legacy/api/v2/class-wc-api-json-handler.php | 2 +- includes/legacy/api/v2/class-wc-api-orders.php | 2 +- includes/legacy/api/v2/class-wc-api-products.php | 2 +- includes/legacy/api/v2/class-wc-api-reports.php | 2 +- includes/legacy/api/v2/class-wc-api-resource.php | 2 +- includes/legacy/api/v2/class-wc-api-server.php | 2 +- includes/legacy/api/v2/class-wc-api-webhooks.php | 2 +- includes/legacy/api/v2/interface-wc-api-handler.php | 2 +- includes/legacy/api/v3/class-wc-api-authentication.php | 2 +- includes/legacy/api/v3/class-wc-api-coupons.php | 2 +- includes/legacy/api/v3/class-wc-api-customers.php | 2 +- includes/legacy/api/v3/class-wc-api-exception.php | 2 +- includes/legacy/api/v3/class-wc-api-json-handler.php | 2 +- includes/legacy/api/v3/class-wc-api-orders.php | 2 +- includes/legacy/api/v3/class-wc-api-products.php | 2 +- includes/legacy/api/v3/class-wc-api-reports.php | 2 +- includes/legacy/api/v3/class-wc-api-resource.php | 2 +- includes/legacy/api/v3/class-wc-api-server.php | 2 +- includes/legacy/api/v3/class-wc-api-taxes.php | 2 +- includes/legacy/api/v3/class-wc-api-webhooks.php | 2 +- includes/legacy/api/v3/interface-wc-api-handler.php | 2 +- includes/legacy/class-wc-legacy-api.php | 2 +- includes/legacy/class-wc-legacy-cart.php | 2 +- includes/legacy/class-wc-legacy-coupon.php | 2 +- includes/legacy/class-wc-legacy-customer.php | 2 +- includes/legacy/class-wc-legacy-shipping-zone.php | 2 +- includes/legacy/class-wc-legacy-webhook.php | 2 +- includes/log-handlers/class-wc-log-handler-db.php | 2 +- includes/log-handlers/class-wc-log-handler-email.php | 2 +- includes/log-handlers/class-wc-log-handler-file.php | 2 +- includes/payment-tokens/class-wc-payment-token-cc.php | 2 +- includes/payment-tokens/class-wc-payment-token-echeck.php | 2 +- includes/queue/class-wc-action-queue.php | 2 +- includes/queue/class-wc-queue.php | 2 +- includes/shipping/flat-rate/class-wc-shipping-flat-rate.php | 2 +- includes/shipping/flat-rate/includes/settings-flat-rate.php | 2 +- .../free-shipping/class-wc-shipping-free-shipping.php | 2 +- .../legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php | 2 +- .../class-wc-shipping-legacy-free-shipping.php | 2 +- .../class-wc-shipping-legacy-international-delivery.php | 2 +- .../class-wc-shipping-legacy-local-delivery.php | 2 +- .../class-wc-shipping-legacy-local-pickup.php | 2 +- .../shipping/local-pickup/class-wc-shipping-local-pickup.php | 2 +- includes/shortcodes/class-wc-shortcode-cart.php | 2 +- includes/shortcodes/class-wc-shortcode-checkout.php | 2 +- includes/shortcodes/class-wc-shortcode-my-account.php | 2 +- includes/shortcodes/class-wc-shortcode-order-tracking.php | 2 +- includes/shortcodes/class-wc-shortcode-products.php | 2 +- includes/theme-support/class-wc-twenty-eleven.php | 2 +- includes/theme-support/class-wc-twenty-fifteen.php | 2 +- includes/theme-support/class-wc-twenty-fourteen.php | 2 +- includes/theme-support/class-wc-twenty-nineteen.php | 2 +- includes/theme-support/class-wc-twenty-seventeen.php | 2 +- includes/theme-support/class-wc-twenty-sixteen.php | 2 +- includes/theme-support/class-wc-twenty-ten.php | 2 +- includes/theme-support/class-wc-twenty-thirteen.php | 2 +- includes/theme-support/class-wc-twenty-twelve.php | 2 +- includes/theme-support/class-wc-twenty-twenty.php | 2 +- includes/traits/trait-wc-item-totals.php | 2 +- includes/walkers/class-product-cat-dropdown-walker.php | 2 +- includes/walkers/class-product-cat-list-walker.php | 2 +- includes/walkers/class-wc-product-cat-dropdown-walker.php | 2 +- includes/walkers/class-wc-product-cat-list-walker.php | 2 +- includes/wc-account-functions.php | 2 +- includes/wc-attribute-functions.php | 2 +- includes/wc-cart-functions.php | 2 +- includes/wc-conditional-functions.php | 2 +- includes/wc-coupon-functions.php | 2 +- includes/wc-formatting-functions.php | 2 +- includes/wc-notice-functions.php | 2 +- includes/wc-order-functions.php | 2 +- includes/wc-order-item-functions.php | 2 +- includes/wc-product-functions.php | 2 +- includes/wc-rest-functions.php | 2 +- includes/wc-stock-functions.php | 2 +- includes/wc-template-hooks.php | 2 +- includes/wc-term-functions.php | 2 +- includes/wc-update-functions.php | 2 +- includes/wc-user-functions.php | 2 +- includes/wc-webhook-functions.php | 2 +- includes/wc-widget-functions.php | 2 +- .../class-wc-rest-wccom-site-installer-controller.php | 2 +- includes/widgets/class-wc-widget-cart.php | 2 +- includes/widgets/class-wc-widget-layered-nav-filters.php | 2 +- includes/widgets/class-wc-widget-layered-nav.php | 2 +- includes/widgets/class-wc-widget-price-filter.php | 2 +- includes/widgets/class-wc-widget-product-categories.php | 2 +- includes/widgets/class-wc-widget-product-search.php | 2 +- includes/widgets/class-wc-widget-product-tag-cloud.php | 2 +- includes/widgets/class-wc-widget-products.php | 2 +- includes/widgets/class-wc-widget-rating-filter.php | 2 +- includes/widgets/class-wc-widget-recent-reviews.php | 2 +- includes/widgets/class-wc-widget-recently-viewed.php | 2 +- includes/widgets/class-wc-widget-top-rated-products.php | 2 +- templates/archive-product.php | 2 +- templates/auth/footer.php | 2 +- templates/auth/form-grant-access.php | 2 +- templates/auth/form-login.php | 2 +- templates/auth/header.php | 2 +- templates/cart/cart-empty.php | 2 +- templates/cart/cart-item-data.php | 2 +- templates/cart/cart-shipping.php | 2 +- templates/cart/cart-totals.php | 2 +- templates/cart/cross-sells.php | 2 +- templates/cart/mini-cart.php | 2 +- templates/cart/proceed-to-checkout-button.php | 2 +- templates/cart/shipping-calculator.php | 2 +- templates/checkout/cart-errors.php | 2 +- templates/checkout/form-billing.php | 2 +- templates/checkout/form-checkout.php | 2 +- templates/checkout/form-coupon.php | 2 +- templates/checkout/form-login.php | 2 +- templates/checkout/form-pay.php | 2 +- templates/checkout/form-shipping.php | 2 +- templates/checkout/order-receipt.php | 2 +- templates/checkout/payment-method.php | 2 +- templates/checkout/payment.php | 2 +- templates/checkout/review-order.php | 2 +- templates/checkout/terms.php | 2 +- templates/checkout/thankyou.php | 2 +- templates/content-product.php | 2 +- templates/content-product_cat.php | 2 +- templates/content-single-product.php | 2 +- templates/content-widget-price-filter.php | 2 +- templates/content-widget-product.php | 2 +- templates/content-widget-reviews.php | 2 +- templates/emails/admin-cancelled-order.php | 2 +- templates/emails/admin-failed-order.php | 2 +- templates/emails/admin-new-order.php | 2 +- templates/emails/customer-completed-order.php | 2 +- templates/emails/customer-invoice.php | 2 +- templates/emails/customer-new-account.php | 2 +- templates/emails/customer-note.php | 2 +- templates/emails/customer-on-hold-order.php | 2 +- templates/emails/customer-processing-order.php | 2 +- templates/emails/customer-refunded-order.php | 2 +- templates/emails/customer-reset-password.php | 2 +- templates/emails/email-addresses.php | 2 +- templates/emails/email-customer-details.php | 2 +- templates/emails/email-downloads.php | 2 +- templates/emails/email-footer.php | 2 +- templates/emails/email-header.php | 2 +- templates/emails/email-order-details.php | 2 +- templates/emails/email-order-items.php | 2 +- templates/emails/email-styles.php | 2 +- templates/emails/plain/admin-cancelled-order.php | 2 +- templates/emails/plain/admin-failed-order.php | 2 +- templates/emails/plain/admin-new-order.php | 2 +- templates/emails/plain/customer-completed-order.php | 2 +- templates/emails/plain/customer-invoice.php | 2 +- templates/emails/plain/customer-new-account.php | 2 +- templates/emails/plain/customer-note.php | 2 +- templates/emails/plain/customer-on-hold-order.php | 2 +- templates/emails/plain/customer-processing-order.php | 2 +- templates/emails/plain/customer-refunded-order.php | 2 +- templates/emails/plain/customer-reset-password.php | 2 +- templates/emails/plain/email-addresses.php | 2 +- templates/emails/plain/email-customer-details.php | 2 +- templates/emails/plain/email-downloads.php | 2 +- templates/emails/plain/email-order-details.php | 2 +- templates/emails/plain/email-order-items.php | 2 +- templates/global/breadcrumb.php | 2 +- templates/global/form-login.php | 2 +- templates/global/quantity-input.php | 2 +- templates/global/sidebar.php | 2 +- templates/global/wrapper-end.php | 2 +- templates/global/wrapper-start.php | 2 +- templates/loop/add-to-cart.php | 2 +- templates/loop/loop-end.php | 2 +- templates/loop/loop-start.php | 2 +- templates/loop/no-products-found.php | 2 +- templates/loop/orderby.php | 2 +- templates/loop/pagination.php | 2 +- templates/loop/price.php | 2 +- templates/loop/rating.php | 2 +- templates/loop/result-count.php | 2 +- templates/loop/sale-flash.php | 2 +- templates/myaccount/dashboard.php | 2 +- templates/myaccount/downloads.php | 2 +- templates/myaccount/form-add-payment-method.php | 2 +- templates/myaccount/form-edit-account.php | 2 +- templates/myaccount/form-edit-address.php | 2 +- templates/myaccount/form-login.php | 2 +- templates/myaccount/form-lost-password.php | 2 +- templates/myaccount/form-reset-password.php | 2 +- templates/myaccount/lost-password-confirmation.php | 2 +- templates/myaccount/my-account.php | 2 +- templates/myaccount/my-address.php | 2 +- templates/myaccount/my-downloads.php | 2 +- templates/myaccount/my-orders.php | 2 +- templates/myaccount/navigation.php | 2 +- templates/myaccount/orders.php | 2 +- templates/myaccount/payment-methods.php | 2 +- templates/myaccount/view-order.php | 2 +- templates/notices/error.php | 2 +- templates/notices/notice.php | 2 +- templates/notices/success.php | 2 +- templates/order/form-tracking.php | 2 +- templates/order/order-again.php | 2 +- templates/order/order-details-customer.php | 2 +- templates/order/order-details-item.php | 2 +- templates/order/order-details.php | 2 +- templates/order/order-downloads.php | 2 +- templates/order/tracking.php | 2 +- templates/product-searchform.php | 2 +- templates/single-product-reviews.php | 2 +- templates/single-product.php | 2 +- templates/single-product/add-to-cart/external.php | 2 +- templates/single-product/add-to-cart/grouped.php | 2 +- templates/single-product/add-to-cart/simple.php | 2 +- templates/single-product/add-to-cart/variable.php | 2 +- .../add-to-cart/variation-add-to-cart-button.php | 2 +- templates/single-product/add-to-cart/variation.php | 2 +- templates/single-product/meta.php | 2 +- templates/single-product/photoswipe.php | 2 +- templates/single-product/price.php | 2 +- templates/single-product/product-attributes.php | 2 +- templates/single-product/product-image.php | 2 +- templates/single-product/product-thumbnails.php | 2 +- templates/single-product/rating.php | 2 +- templates/single-product/related.php | 2 +- templates/single-product/review-meta.php | 2 +- templates/single-product/review-rating.php | 2 +- templates/single-product/review.php | 2 +- templates/single-product/sale-flash.php | 2 +- templates/single-product/share.php | 2 +- templates/single-product/short-description.php | 2 +- templates/single-product/stock.php | 2 +- templates/single-product/tabs/additional-information.php | 2 +- templates/single-product/tabs/description.php | 2 +- templates/single-product/tabs/tabs.php | 2 +- templates/single-product/up-sells.php | 2 +- templates/taxonomy-product_cat.php | 2 +- templates/taxonomy-product_tag.php | 2 +- tests/Tools/CodeHacking/CodeHacker.php | 2 +- tests/Tools/CodeHacking/CodeHackerTestHook.php | 2 +- tests/Tools/CodeHacking/Hacks/BypassFinalsHack.php | 2 +- tests/Tools/CodeHacking/Hacks/CodeHack.php | 2 +- tests/Tools/CodeHacking/Hacks/FunctionsMockerHack.php | 2 +- tests/Tools/CodeHacking/Hacks/StaticMockerHack.php | 2 +- tests/legacy/framework/helpers/class-wc-helper-order.php | 2 +- .../unit-tests/order/class-wc-tests-order-functions.php | 2 +- tests/legacy/unit-tests/payment-gateways/cod.php | 2 +- tests/legacy/unit-tests/payment-gateways/payment-gateways.php | 2 +- tests/legacy/unit-tests/templates/functions.php | 2 +- tests/legacy/unit-tests/widgets/class-wc-tests-widget.php | 2 +- .../unit-tests/widgets/class-wc-tests-widget-layered-nav.php | 2 +- 499 files changed, 518 insertions(+), 518 deletions(-) diff --git a/i18n/continents.php b/i18n/continents.php index da519983b17..13f743c9c68 100644 --- a/i18n/continents.php +++ b/i18n/continents.php @@ -4,7 +4,7 @@ * * Returns an array of continents. * - * @package WooCommerce/i18n + * @package WooCommerce\i18n * @version 2.5.0 */ diff --git a/i18n/locale-info.php b/i18n/locale-info.php index d2c928eece6..458b17f95d8 100644 --- a/i18n/locale-info.php +++ b/i18n/locale-info.php @@ -2,7 +2,7 @@ /** * Locales information * - * @package WooCommerce/i18n + * @package WooCommerce\i18n * @version 3.5.0 */ diff --git a/i18n/phone.php b/i18n/phone.php index 3f118c971ea..4856e7421b7 100644 --- a/i18n/phone.php +++ b/i18n/phone.php @@ -4,7 +4,7 @@ * * Returns an array of calling codes. * - * @package WooCommerce/i18n + * @package WooCommerce\i18n */ defined( 'ABSPATH' ) || exit; diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index ea54e7085df..383d6d19547 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -7,7 +7,7 @@ * * @class WC_Data * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ if ( ! defined( 'ABSPATH' ) ) { @@ -20,7 +20,7 @@ if ( ! defined( 'ABSPATH' ) ) { * Implemented by classes using the same CRUD(s) pattern. * * @version 2.6.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ abstract class WC_Data { diff --git a/includes/abstracts/abstract-wc-integration.php b/includes/abstracts/abstract-wc-integration.php index 8ad46759b09..98dd28486f5 100644 --- a/includes/abstracts/abstract-wc-integration.php +++ b/includes/abstracts/abstract-wc-integration.php @@ -7,7 +7,7 @@ * * @class WC_Settings_API * @version 2.6.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ if ( ! defined( 'ABSPATH' ) ) { @@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WC_Integration * @extends WC_Settings_API * @version 2.6.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ abstract class WC_Integration extends WC_Settings_API { diff --git a/includes/abstracts/abstract-wc-log-handler.php b/includes/abstracts/abstract-wc-log-handler.php index 64d6e0a6c50..4cf148d172e 100644 --- a/includes/abstracts/abstract-wc-log-handler.php +++ b/includes/abstracts/abstract-wc-log-handler.php @@ -3,7 +3,7 @@ * Log handling functionality. * * @class WC_Log_Handler - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ if ( ! defined( 'ABSPATH' ) ) { @@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) { * Abstract WC Log Handler Class * * @version 1.0.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ abstract class WC_Log_Handler implements WC_Log_Handler_Interface { diff --git a/includes/abstracts/abstract-wc-object-query.php b/includes/abstracts/abstract-wc-object-query.php index 7e232462a6a..0d1542056cd 100644 --- a/includes/abstracts/abstract-wc-object-query.php +++ b/includes/abstracts/abstract-wc-object-query.php @@ -2,7 +2,7 @@ /** * Query abstraction layer functionality. * - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ if ( ! defined( 'ABSPATH' ) ) { @@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) { * Extended by classes to provide a query abstraction layer for safe object searching. * * @version 3.1.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ abstract class WC_Object_Query { diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index 5efd4b0c9e6..3cca0abefb2 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -7,7 +7,7 @@ * * @class WC_Abstract_Order * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/abstracts/abstract-wc-payment-gateway.php b/includes/abstracts/abstract-wc-payment-gateway.php index 180c3f05adf..dcfb7614ff8 100644 --- a/includes/abstracts/abstract-wc-payment-gateway.php +++ b/includes/abstracts/abstract-wc-payment-gateway.php @@ -6,7 +6,7 @@ * * @class WC_Payment_Gateway * @version 2.1.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ use Automattic\Jetpack\Constants; @@ -23,7 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WC_Payment_Gateway * @extends WC_Settings_API * @version 2.1.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ abstract class WC_Payment_Gateway extends WC_Settings_API { diff --git a/includes/abstracts/abstract-wc-payment-token.php b/includes/abstracts/abstract-wc-payment-token.php index 60635bad6d7..ad958991981 100644 --- a/includes/abstracts/abstract-wc-payment-token.php +++ b/includes/abstracts/abstract-wc-payment-token.php @@ -5,7 +5,7 @@ * Generic payment tokens functionality which can be extended by idividual types of payment tokens. * * @class WC_Payment_Token - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ if ( ! defined( 'ABSPATH' ) ) { @@ -23,7 +23,7 @@ require_once WC_ABSPATH . 'includes/legacy/abstract-wc-legacy-payment-token.php' * @class WC_Payment_Token * @version 3.0.0 * @since 2.6.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ abstract class WC_Payment_Token extends WC_Legacy_Payment_Token { diff --git a/includes/abstracts/abstract-wc-privacy.php b/includes/abstracts/abstract-wc-privacy.php index 5908915e6de..1f181481ee8 100644 --- a/includes/abstracts/abstract-wc-privacy.php +++ b/includes/abstracts/abstract-wc-privacy.php @@ -3,7 +3,7 @@ * WooCommerce abstract privacy class. * * @since 3.4.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ defined( 'ABSPATH' ) || exit; @@ -15,7 +15,7 @@ defined( 'ABSPATH' ) || exit; * privacy data to be exported and privacy data to be deleted. * * @version 3.4.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ abstract class WC_Abstract_Privacy { /** diff --git a/includes/abstracts/abstract-wc-product.php b/includes/abstracts/abstract-wc-product.php index 6109689ab33..f45d1449ebb 100644 --- a/includes/abstracts/abstract-wc-product.php +++ b/includes/abstracts/abstract-wc-product.php @@ -2,7 +2,7 @@ /** * WooCommerce product base class. * - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ if ( ! defined( 'ABSPATH' ) ) { @@ -21,7 +21,7 @@ require_once WC_ABSPATH . 'includes/legacy/abstract-wc-legacy-product.php'; * The WooCommerce product class handles individual product data. * * @version 3.0.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ class WC_Product extends WC_Abstract_Legacy_Product { diff --git a/includes/abstracts/abstract-wc-session.php b/includes/abstracts/abstract-wc-session.php index fb4fc5b0e03..bec2ac223ba 100644 --- a/includes/abstracts/abstract-wc-session.php +++ b/includes/abstracts/abstract-wc-session.php @@ -4,7 +4,7 @@ * * @class WC_Session * @version 2.0.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/abstracts/abstract-wc-settings-api.php b/includes/abstracts/abstract-wc-settings-api.php index 4fd19ca7041..f33a62365fc 100644 --- a/includes/abstracts/abstract-wc-settings-api.php +++ b/includes/abstracts/abstract-wc-settings-api.php @@ -4,7 +4,7 @@ * * Admin Settings API used by Integrations, Shipping Methods, and Payment Gateways. * - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ defined( 'ABSPATH' ) || exit; diff --git a/includes/abstracts/abstract-wc-shipping-method.php b/includes/abstracts/abstract-wc-shipping-method.php index c5922a75627..c27b0ae961a 100644 --- a/includes/abstracts/abstract-wc-shipping-method.php +++ b/includes/abstracts/abstract-wc-shipping-method.php @@ -3,7 +3,7 @@ * Abstract shipping method * * @class WC_Shipping_Method - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ if ( ! defined( 'ABSPATH' ) ) { @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WC_Shipping_Method * @version 3.0.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ abstract class WC_Shipping_Method extends WC_Settings_API { diff --git a/includes/abstracts/abstract-wc-widget.php b/includes/abstracts/abstract-wc-widget.php index c2f6f1bf298..10ac9e4cec6 100644 --- a/includes/abstracts/abstract-wc-widget.php +++ b/includes/abstracts/abstract-wc-widget.php @@ -3,7 +3,7 @@ * Abstract widget class * * @class WC_Widget - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts */ use Automattic\Jetpack\Constants; @@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * WC_Widget * - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts * @version 2.5.0 * @extends WP_Widget */ diff --git a/includes/abstracts/class-wc-background-process.php b/includes/abstracts/class-wc-background-process.php index 6d9662208fc..a48fa589240 100644 --- a/includes/abstracts/class-wc-background-process.php +++ b/includes/abstracts/class-wc-background-process.php @@ -5,7 +5,7 @@ * Uses https://github.com/A5hleyRich/wp-background-processing to handle DB * updates in the background. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/class-wc-admin-addons.php b/includes/admin/class-wc-admin-addons.php index 42faab0fb19..6d24bf71db4 100644 --- a/includes/admin/class-wc-admin-addons.php +++ b/includes/admin/class-wc-admin-addons.php @@ -2,7 +2,7 @@ /** * Addons Page * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.5.0 */ diff --git a/includes/admin/class-wc-admin-assets.php b/includes/admin/class-wc-admin-assets.php index a7760148a84..567e2efe7ca 100644 --- a/includes/admin/class-wc-admin-assets.php +++ b/includes/admin/class-wc-admin-assets.php @@ -2,7 +2,7 @@ /** * Load assets * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.7.0 */ diff --git a/includes/admin/class-wc-admin-attributes.php b/includes/admin/class-wc-admin-attributes.php index db152ac45ca..9dc884fe9e9 100644 --- a/includes/admin/class-wc-admin-attributes.php +++ b/includes/admin/class-wc-admin-attributes.php @@ -4,7 +4,7 @@ * * The attributes section lets users add custom attributes to assign to products - they can also be used in the "Filter Products by Attribute" widget. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.3.0 */ diff --git a/includes/admin/class-wc-admin-customize.php b/includes/admin/class-wc-admin-customize.php index 20834846126..cba3f2b4e68 100644 --- a/includes/admin/class-wc-admin-customize.php +++ b/includes/admin/class-wc-admin-customize.php @@ -4,7 +4,7 @@ * * @author WooCommerce * @category Admin - * @package WooCommerce/Admin/Customize + * @package WooCommerce\Admin\Customize * @version 3.1.0 */ diff --git a/includes/admin/class-wc-admin-dashboard.php b/includes/admin/class-wc-admin-dashboard.php index 28d1c6b0fe2..8f1a8348405 100644 --- a/includes/admin/class-wc-admin-dashboard.php +++ b/includes/admin/class-wc-admin-dashboard.php @@ -2,7 +2,7 @@ /** * Admin Dashboard * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.1.0 */ diff --git a/includes/admin/class-wc-admin-duplicate-product.php b/includes/admin/class-wc-admin-duplicate-product.php index 4a11254e524..05c67028ac3 100644 --- a/includes/admin/class-wc-admin-duplicate-product.php +++ b/includes/admin/class-wc-admin-duplicate-product.php @@ -2,7 +2,7 @@ /** * Duplicate product functionality * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.0.0 */ diff --git a/includes/admin/class-wc-admin-exporters.php b/includes/admin/class-wc-admin-exporters.php index 011d2e1429e..c6dbc48632c 100644 --- a/includes/admin/class-wc-admin-exporters.php +++ b/includes/admin/class-wc-admin-exporters.php @@ -2,7 +2,7 @@ /** * Init WooCommerce data exporters. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.1.0 */ diff --git a/includes/admin/class-wc-admin-help.php b/includes/admin/class-wc-admin-help.php index 334055900b0..aa5bc03a7bf 100644 --- a/includes/admin/class-wc-admin-help.php +++ b/includes/admin/class-wc-admin-help.php @@ -2,7 +2,7 @@ /** * Add some content to the help tab * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.1.0 */ diff --git a/includes/admin/class-wc-admin-importers.php b/includes/admin/class-wc-admin-importers.php index 8f85ad27b60..95f9e3bbca7 100644 --- a/includes/admin/class-wc-admin-importers.php +++ b/includes/admin/class-wc-admin-importers.php @@ -2,7 +2,7 @@ /** * Init WooCommerce data importers. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ use Automattic\Jetpack\Constants; diff --git a/includes/admin/class-wc-admin-log-table-list.php b/includes/admin/class-wc-admin-log-table-list.php index 48e51f9bffc..2d9b9225632 100644 --- a/includes/admin/class-wc-admin-log-table-list.php +++ b/includes/admin/class-wc-admin-log-table-list.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 1.0.0 */ diff --git a/includes/admin/class-wc-admin-meta-boxes.php b/includes/admin/class-wc-admin-meta-boxes.php index 32e03797591..df1db141968 100644 --- a/includes/admin/class-wc-admin-meta-boxes.php +++ b/includes/admin/class-wc-admin-meta-boxes.php @@ -4,7 +4,7 @@ * * Sets up the write panels used by products and orders (custom post types). * - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes */ use Automattic\Jetpack\Constants; diff --git a/includes/admin/class-wc-admin-permalink-settings.php b/includes/admin/class-wc-admin-permalink-settings.php index ec6534cc142..abcd784d721 100644 --- a/includes/admin/class-wc-admin-permalink-settings.php +++ b/includes/admin/class-wc-admin-permalink-settings.php @@ -5,7 +5,7 @@ * @class WC_Admin_Permalink_Settings * @author WooThemes * @category Admin - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.3.0 */ diff --git a/includes/admin/class-wc-admin-pointers.php b/includes/admin/class-wc-admin-pointers.php index c4020b7f928..23242fe3f8d 100644 --- a/includes/admin/class-wc-admin-pointers.php +++ b/includes/admin/class-wc-admin-pointers.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.4.0 */ diff --git a/includes/admin/class-wc-admin-post-types.php b/includes/admin/class-wc-admin-post-types.php index 41fa6a3c4df..5ebfcd55659 100644 --- a/includes/admin/class-wc-admin-post-types.php +++ b/includes/admin/class-wc-admin-post-types.php @@ -2,7 +2,7 @@ /** * Post Types Admin * - * @package WooCommerce/admin + * @package WooCommerce\admin * @version 3.3.0 */ diff --git a/includes/admin/class-wc-admin-profile.php b/includes/admin/class-wc-admin-profile.php index 9aafac10e2d..94180722001 100644 --- a/includes/admin/class-wc-admin-profile.php +++ b/includes/admin/class-wc-admin-profile.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.4.0 */ diff --git a/includes/admin/class-wc-admin-reports.php b/includes/admin/class-wc-admin-reports.php index 541fe67cd1b..0d5dc4372e5 100644 --- a/includes/admin/class-wc-admin-reports.php +++ b/includes/admin/class-wc-admin-reports.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.0.0 */ diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index 1d1a49b8311..20d3d1c1ddc 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -2,7 +2,7 @@ /** * WooCommerce Admin Settings Class * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.4.0 */ diff --git a/includes/admin/class-wc-admin-setup-wizard.php b/includes/admin/class-wc-admin-setup-wizard.php index 1976596f6df..d5402a4bb12 100644 --- a/includes/admin/class-wc-admin-setup-wizard.php +++ b/includes/admin/class-wc-admin-setup-wizard.php @@ -4,7 +4,7 @@ * * Takes new users through some basic steps to setup their store. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.6.0 */ diff --git a/includes/admin/class-wc-admin-status.php b/includes/admin/class-wc-admin-status.php index 23e670ec8d7..cb7b9387482 100644 --- a/includes/admin/class-wc-admin-status.php +++ b/includes/admin/class-wc-admin-status.php @@ -2,7 +2,7 @@ /** * Debug/Status page * - * @package WooCommerce/Admin/System Status + * @package WooCommerce\Admin\System Status * @version 2.2.0 */ diff --git a/includes/admin/class-wc-admin-taxonomies.php b/includes/admin/class-wc-admin-taxonomies.php index b5a32d7eb87..bb212d69ff3 100644 --- a/includes/admin/class-wc-admin-taxonomies.php +++ b/includes/admin/class-wc-admin-taxonomies.php @@ -4,7 +4,7 @@ * * @class WC_Admin_Taxonomies * @version 2.3.10 - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/class-wc-admin.php b/includes/admin/class-wc-admin.php index 8a9d6e8bd43..e864cd80e1f 100644 --- a/includes/admin/class-wc-admin.php +++ b/includes/admin/class-wc-admin.php @@ -3,7 +3,7 @@ * WooCommerce Admin * * @class WC_Admin - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.6.0 */ diff --git a/includes/admin/helper/class-wc-helper-api.php b/includes/admin/helper/class-wc-helper-api.php index e1baf489000..9e7c241ccde 100644 --- a/includes/admin/helper/class-wc-helper-api.php +++ b/includes/admin/helper/class-wc-helper-api.php @@ -3,7 +3,7 @@ * WooCommerce Admin * * @class WC_Helper_API - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/helper/class-wc-helper-updater.php b/includes/admin/helper/class-wc-helper-updater.php index 62941f3f734..3feccb16ac4 100644 --- a/includes/admin/helper/class-wc-helper-updater.php +++ b/includes/admin/helper/class-wc-helper-updater.php @@ -3,7 +3,7 @@ * The update helper for WooCommerce.com plugins. * * @class WC_Helper_Updater - * @package WooCommerce/Admin. + * @package WooCommerce\Admin. */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/helper/class-wc-helper.php b/includes/admin/helper/class-wc-helper.php index 40beb7e9493..6ee44dc8e3e 100644 --- a/includes/admin/helper/class-wc-helper.php +++ b/includes/admin/helper/class-wc-helper.php @@ -3,7 +3,7 @@ * WooCommerce Admin * * @class WC_Helper - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ use Automattic\Jetpack\Constants; diff --git a/includes/admin/helper/views/html-section-nav.php b/includes/admin/helper/views/html-section-nav.php index 6b6dcf389a5..9af76fe32a0 100644 --- a/includes/admin/helper/views/html-section-nav.php +++ b/includes/admin/helper/views/html-section-nav.php @@ -2,7 +2,7 @@ /** * Helper admin navigation. * - * @package WooCommerce/Helper + * @package WooCommerce\Helper */ defined( 'ABSPATH' ) || exit(); ?> diff --git a/includes/admin/importers/class-wc-product-csv-importer-controller.php b/includes/admin/importers/class-wc-product-csv-importer-controller.php index 0d4afc75eed..0de82507fdc 100644 --- a/includes/admin/importers/class-wc-product-csv-importer-controller.php +++ b/includes/admin/importers/class-wc-product-csv-importer-controller.php @@ -16,7 +16,7 @@ if ( ! class_exists( 'WP_Importer' ) ) { /** * Product importer controller - handles file upload and forms in admin. * - * @package WooCommerce/Admin/Importers + * @package WooCommerce\Admin\Importers * @version 3.1.0 */ class WC_Product_CSV_Importer_Controller { diff --git a/includes/admin/importers/class-wc-tax-rate-importer.php b/includes/admin/importers/class-wc-tax-rate-importer.php index c0693872d8d..79f9cd10c09 100644 --- a/includes/admin/importers/class-wc-tax-rate-importer.php +++ b/includes/admin/importers/class-wc-tax-rate-importer.php @@ -3,7 +3,7 @@ * Tax importer class file * * @version 2.3.0 - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ if ( ! defined( 'ABSPATH' ) ) { @@ -17,7 +17,7 @@ if ( ! class_exists( 'WP_Importer' ) ) { /** * Tax Rates importer - import tax rates and local tax rates into WooCommerce. * - * @package WooCommerce/Admin/Importers + * @package WooCommerce\Admin\Importers * @version 2.3.0 */ class WC_Tax_Rate_Importer extends WP_Importer { diff --git a/includes/admin/importers/views/html-product-csv-import-form.php b/includes/admin/importers/views/html-product-csv-import-form.php index f7e44815c11..3b96ec64f47 100644 --- a/includes/admin/importers/views/html-product-csv-import-form.php +++ b/includes/admin/importers/views/html-product-csv-import-form.php @@ -2,7 +2,7 @@ /** * Admin View: Product import form * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/list-tables/abstract-class-wc-admin-list-table.php b/includes/admin/list-tables/abstract-class-wc-admin-list-table.php index f985a80185b..4a0c93d6274 100644 --- a/includes/admin/list-tables/abstract-class-wc-admin-list-table.php +++ b/includes/admin/list-tables/abstract-class-wc-admin-list-table.php @@ -2,7 +2,7 @@ /** * List tables. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.3.0 */ diff --git a/includes/admin/list-tables/class-wc-admin-list-table-coupons.php b/includes/admin/list-tables/class-wc-admin-list-table-coupons.php index dd9cab75a45..5a8ea00c78e 100644 --- a/includes/admin/list-tables/class-wc-admin-list-table-coupons.php +++ b/includes/admin/list-tables/class-wc-admin-list-table-coupons.php @@ -2,7 +2,7 @@ /** * List tables: coupons. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.3.0 */ diff --git a/includes/admin/list-tables/class-wc-admin-list-table-products.php b/includes/admin/list-tables/class-wc-admin-list-table-products.php index 6bc4ba30eed..05520130bc7 100644 --- a/includes/admin/list-tables/class-wc-admin-list-table-products.php +++ b/includes/admin/list-tables/class-wc-admin-list-table-products.php @@ -2,7 +2,7 @@ /** * List tables: products. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.3.0 */ diff --git a/includes/admin/marketplace-suggestions/views/container.php b/includes/admin/marketplace-suggestions/views/container.php index 4799d457990..85071f3106b 100644 --- a/includes/admin/marketplace-suggestions/views/container.php +++ b/includes/admin/marketplace-suggestions/views/container.php @@ -2,7 +2,7 @@ /** * Marketplace suggestions container * - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php b/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php index c8b92d10e2a..5a855e33cec 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-coupon-data.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes * @version 2.1.0 */ diff --git a/includes/admin/meta-boxes/class-wc-meta-box-order-actions.php b/includes/admin/meta-boxes/class-wc-meta-box-order-actions.php index 303bdaad9d3..6e68d641740 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-order-actions.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-order-actions.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes * @version 2.1.0 */ diff --git a/includes/admin/meta-boxes/class-wc-meta-box-order-data.php b/includes/admin/meta-boxes/class-wc-meta-box-order-data.php index f5568ddb2d1..4c30257d3dd 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-order-data.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-order-data.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes * @version 2.2.0 */ diff --git a/includes/admin/meta-boxes/class-wc-meta-box-order-downloads.php b/includes/admin/meta-boxes/class-wc-meta-box-order-downloads.php index 897842500c0..c519dd78324 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-order-downloads.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-order-downloads.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes * @version 2.1.0 */ diff --git a/includes/admin/meta-boxes/class-wc-meta-box-order-items.php b/includes/admin/meta-boxes/class-wc-meta-box-order-items.php index a70bea86889..0f5bf54eb74 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-order-items.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-order-items.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes * @version 2.1.0 */ diff --git a/includes/admin/meta-boxes/class-wc-meta-box-order-notes.php b/includes/admin/meta-boxes/class-wc-meta-box-order-notes.php index ba34495607e..936a647a1e0 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-order-notes.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-order-notes.php @@ -2,7 +2,7 @@ /** * Order Notes * - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php index 7bbbab50ab2..c1275acf073 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php @@ -4,7 +4,7 @@ * * Displays the product data box, tabbed, with several panels covering price, stock etc. * - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes * @version 3.0.0 */ diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-images.php b/includes/admin/meta-boxes/class-wc-meta-box-product-images.php index e2553785234..d4a0b5f04dd 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-product-images.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-product-images.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes * @version 2.1.0 */ diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-reviews.php b/includes/admin/meta-boxes/class-wc-meta-box-product-reviews.php index 2b845692997..28e6a11435b 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-product-reviews.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-product-reviews.php @@ -4,7 +4,7 @@ * * Functions for displaying product reviews data meta box. * - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-short-description.php b/includes/admin/meta-boxes/class-wc-meta-box-product-short-description.php index 736ffcb717a..ab762be2929 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-product-short-description.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-product-short-description.php @@ -4,7 +4,7 @@ * * Replaces the standard excerpt box. * - * @package WooCommerce/Admin/Meta Boxes + * @package WooCommerce\Admin\Meta Boxes * @version 2.1.0 */ diff --git a/includes/admin/meta-boxes/views/html-order-item.php b/includes/admin/meta-boxes/views/html-order-item.php index 7bee65e2d05..355b9b28a1b 100644 --- a/includes/admin/meta-boxes/views/html-order-item.php +++ b/includes/admin/meta-boxes/views/html-order-item.php @@ -2,7 +2,7 @@ /** * Shows an order item * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @var object $item The item being displayed * @var int $item_id The id of the item being displayed */ diff --git a/includes/admin/meta-boxes/views/html-order-items.php b/includes/admin/meta-boxes/views/html-order-items.php index f5dd34f972e..d300e782745 100644 --- a/includes/admin/meta-boxes/views/html-order-items.php +++ b/includes/admin/meta-boxes/views/html-order-items.php @@ -2,7 +2,7 @@ /** * Order items HTML for meta box. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/meta-boxes/views/html-order-notes.php b/includes/admin/meta-boxes/views/html-order-notes.php index 87015bfa3a4..50db87bcea2 100644 --- a/includes/admin/meta-boxes/views/html-order-notes.php +++ b/includes/admin/meta-boxes/views/html-order-notes.php @@ -2,7 +2,7 @@ /** * Order notes HTML for meta box. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/meta-boxes/views/html-order-shipping.php b/includes/admin/meta-boxes/views/html-order-shipping.php index 38bc004b5e8..6350fb1f9f1 100644 --- a/includes/admin/meta-boxes/views/html-order-shipping.php +++ b/includes/admin/meta-boxes/views/html-order-shipping.php @@ -2,12 +2,12 @@ /** * Shows a shipping line * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * * @var object $item The item being displayed * @var int $item_id The id of the item being displayed * - * @package WooCommerce/Admin/Views + * @package WooCommerce\Admin\Views */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/meta-boxes/views/html-product-data-general.php b/includes/admin/meta-boxes/views/html-product-data-general.php index 3b2e476c538..281a3c573d9 100644 --- a/includes/admin/meta-boxes/views/html-product-data-general.php +++ b/includes/admin/meta-boxes/views/html-product-data-general.php @@ -2,7 +2,7 @@ /** * Product general data panel. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/meta-boxes/views/html-product-data-linked-products.php b/includes/admin/meta-boxes/views/html-product-data-linked-products.php index 2a7a0938db9..8233b27d4b9 100644 --- a/includes/admin/meta-boxes/views/html-product-data-linked-products.php +++ b/includes/admin/meta-boxes/views/html-product-data-linked-products.php @@ -2,7 +2,7 @@ /** * Linked product options. * - * @package WooCommerce/admin + * @package WooCommerce\admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/meta-boxes/views/html-product-data-panel.php b/includes/admin/meta-boxes/views/html-product-data-panel.php index 5fd93719b65..5393f85d464 100644 --- a/includes/admin/meta-boxes/views/html-product-data-panel.php +++ b/includes/admin/meta-boxes/views/html-product-data-panel.php @@ -2,7 +2,7 @@ /** * Product data meta box. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/plugin-updates/class-wc-plugin-updates.php b/includes/admin/plugin-updates/class-wc-plugin-updates.php index fa64bcce0b4..dd7ce5c1d5b 100644 --- a/includes/admin/plugin-updates/class-wc-plugin-updates.php +++ b/includes/admin/plugin-updates/class-wc-plugin-updates.php @@ -2,7 +2,7 @@ /** * Class for displaying plugin warning notifications and determining 3rd party plugin compatibility. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.2.0 */ diff --git a/includes/admin/plugin-updates/class-wc-plugins-screen-updates.php b/includes/admin/plugin-updates/class-wc-plugins-screen-updates.php index a7a048db15a..ad24e66848e 100644 --- a/includes/admin/plugin-updates/class-wc-plugins-screen-updates.php +++ b/includes/admin/plugin-updates/class-wc-plugins-screen-updates.php @@ -2,7 +2,7 @@ /** * Manages WooCommerce plugin updating on the Plugins screen. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.2.0 */ diff --git a/includes/admin/plugin-updates/class-wc-updates-screen-updates.php b/includes/admin/plugin-updates/class-wc-updates-screen-updates.php index 5e55da51488..60510100610 100644 --- a/includes/admin/plugin-updates/class-wc-updates-screen-updates.php +++ b/includes/admin/plugin-updates/class-wc-updates-screen-updates.php @@ -2,7 +2,7 @@ /** * Manages WooCommerce plugin updating on the Updates screen. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 3.2.0 */ diff --git a/includes/admin/reports/class-wc-admin-report.php b/includes/admin/reports/class-wc-admin-report.php index ca634b47c6e..d6dceb681f5 100644 --- a/includes/admin/reports/class-wc-admin-report.php +++ b/includes/admin/reports/class-wc-admin-report.php @@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Admin_Report { diff --git a/includes/admin/reports/class-wc-report-coupon-usage.php b/includes/admin/reports/class-wc-report-coupon-usage.php index c04be027c7f..c2bddf2fd26 100644 --- a/includes/admin/reports/class-wc-report-coupon-usage.php +++ b/includes/admin/reports/class-wc-report-coupon-usage.php @@ -2,7 +2,7 @@ /** * Coupon usage report functionality * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports */ if ( ! defined( 'ABSPATH' ) ) { @@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Report_Coupon_Usage extends WC_Admin_Report { diff --git a/includes/admin/reports/class-wc-report-customer-list.php b/includes/admin/reports/class-wc-report-customer-list.php index 36f47c9b24d..e223570b7b9 100644 --- a/includes/admin/reports/class-wc-report-customer-list.php +++ b/includes/admin/reports/class-wc-report-customer-list.php @@ -16,7 +16,7 @@ if ( ! class_exists( 'WP_List_Table' ) ) { /** * WC_Report_Customer_List. * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Report_Customer_List extends WP_List_Table { diff --git a/includes/admin/reports/class-wc-report-customers.php b/includes/admin/reports/class-wc-report-customers.php index 4b949d2180d..0096a73f993 100644 --- a/includes/admin/reports/class-wc-report-customers.php +++ b/includes/admin/reports/class-wc-report-customers.php @@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * WC_Report_Customers * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Report_Customers extends WC_Admin_Report { diff --git a/includes/admin/reports/class-wc-report-downloads.php b/includes/admin/reports/class-wc-report-downloads.php index ff326ab01df..fcedb69eecf 100644 --- a/includes/admin/reports/class-wc-report-downloads.php +++ b/includes/admin/reports/class-wc-report-downloads.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 3.3.0 */ diff --git a/includes/admin/reports/class-wc-report-low-in-stock.php b/includes/admin/reports/class-wc-report-low-in-stock.php index 80ade878d4a..ed69b074bd6 100644 --- a/includes/admin/reports/class-wc-report-low-in-stock.php +++ b/includes/admin/reports/class-wc-report-low-in-stock.php @@ -2,7 +2,7 @@ /** * WC_Report_Low_In_Stock. * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/reports/class-wc-report-most-stocked.php b/includes/admin/reports/class-wc-report-most-stocked.php index 5d018f9df86..26058d43cf4 100644 --- a/includes/admin/reports/class-wc-report-most-stocked.php +++ b/includes/admin/reports/class-wc-report-most-stocked.php @@ -2,7 +2,7 @@ /** * WC_Report_Most_Stocked. * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/reports/class-wc-report-out-of-stock.php b/includes/admin/reports/class-wc-report-out-of-stock.php index 1e4a9940250..9eb594ad9a0 100644 --- a/includes/admin/reports/class-wc-report-out-of-stock.php +++ b/includes/admin/reports/class-wc-report-out-of-stock.php @@ -2,7 +2,7 @@ /** * WC_Report_Out_Of_Stock. * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/reports/class-wc-report-sales-by-category.php b/includes/admin/reports/class-wc-report-sales-by-category.php index 2a445eedea2..390e9de2c24 100644 --- a/includes/admin/reports/class-wc-report-sales-by-category.php +++ b/includes/admin/reports/class-wc-report-sales-by-category.php @@ -2,7 +2,7 @@ /** * Sales by category report functionality * - * @package WooCommerce/Admin/Reporting + * @package WooCommerce\Admin\Reporting */ if ( ! defined( 'ABSPATH' ) ) { @@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Report_Sales_By_Category extends WC_Admin_Report { diff --git a/includes/admin/reports/class-wc-report-sales-by-date.php b/includes/admin/reports/class-wc-report-sales-by-date.php index ae0b41146c7..10938ee633d 100644 --- a/includes/admin/reports/class-wc-report-sales-by-date.php +++ b/includes/admin/reports/class-wc-report-sales-by-date.php @@ -2,7 +2,7 @@ /** * WC_Report_Sales_By_Date * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ diff --git a/includes/admin/reports/class-wc-report-sales-by-product.php b/includes/admin/reports/class-wc-report-sales-by-product.php index f8f666252d6..69ae0b4c4a7 100644 --- a/includes/admin/reports/class-wc-report-sales-by-product.php +++ b/includes/admin/reports/class-wc-report-sales-by-product.php @@ -2,7 +2,7 @@ /** * Sales By Product Reporting * - * @package WooCommerce/Admin/Reporting + * @package WooCommerce\Admin\Reporting */ if ( ! defined( 'ABSPATH' ) ) { @@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * WC_Report_Sales_By_Product * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Report_Sales_By_Product extends WC_Admin_Report { diff --git a/includes/admin/reports/class-wc-report-stock.php b/includes/admin/reports/class-wc-report-stock.php index e9b6a4c93cd..e656ae0156c 100644 --- a/includes/admin/reports/class-wc-report-stock.php +++ b/includes/admin/reports/class-wc-report-stock.php @@ -13,7 +13,7 @@ if ( ! class_exists( 'WP_List_Table' ) ) { * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Report_Stock extends WP_List_Table { diff --git a/includes/admin/reports/class-wc-report-taxes-by-code.php b/includes/admin/reports/class-wc-report-taxes-by-code.php index 024b4c3c383..a76375904e1 100644 --- a/includes/admin/reports/class-wc-report-taxes-by-code.php +++ b/includes/admin/reports/class-wc-report-taxes-by-code.php @@ -2,7 +2,7 @@ /** * Taxes by tax code report. * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports */ if ( ! defined( 'ABSPATH' ) ) { @@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * WC_Report_Taxes_By_Code * - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Report_Taxes_By_Code extends WC_Admin_Report { diff --git a/includes/admin/reports/class-wc-report-taxes-by-date.php b/includes/admin/reports/class-wc-report-taxes-by-date.php index cd52454c982..37328325bda 100644 --- a/includes/admin/reports/class-wc-report-taxes-by-date.php +++ b/includes/admin/reports/class-wc-report-taxes-by-date.php @@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @author WooThemes * @category Admin - * @package WooCommerce/Admin/Reports + * @package WooCommerce\Admin\Reports * @version 2.1.0 */ class WC_Report_Taxes_By_Date extends WC_Admin_Report { diff --git a/includes/admin/settings/class-wc-settings-accounts.php b/includes/admin/settings/class-wc-settings-accounts.php index 3ecf58c01b1..73802e61bdb 100644 --- a/includes/admin/settings/class-wc-settings-accounts.php +++ b/includes/admin/settings/class-wc-settings-accounts.php @@ -2,7 +2,7 @@ /** * WooCommerce Account Settings. * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/settings/class-wc-settings-advanced.php b/includes/admin/settings/class-wc-settings-advanced.php index 5056d4fdba8..13896e8a27c 100644 --- a/includes/admin/settings/class-wc-settings-advanced.php +++ b/includes/admin/settings/class-wc-settings-advanced.php @@ -2,7 +2,7 @@ /** * WooCommerce advanced settings * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/settings/class-wc-settings-emails.php b/includes/admin/settings/class-wc-settings-emails.php index 00df3150196..9b4c524ebc5 100644 --- a/includes/admin/settings/class-wc-settings-emails.php +++ b/includes/admin/settings/class-wc-settings-emails.php @@ -2,7 +2,7 @@ /** * WooCommerce Email Settings * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.1.0 */ diff --git a/includes/admin/settings/class-wc-settings-general.php b/includes/admin/settings/class-wc-settings-general.php index 6e0126b00da..8535dd7f956 100644 --- a/includes/admin/settings/class-wc-settings-general.php +++ b/includes/admin/settings/class-wc-settings-general.php @@ -2,7 +2,7 @@ /** * WooCommerce General Settings * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/settings/class-wc-settings-integrations.php b/includes/admin/settings/class-wc-settings-integrations.php index 248287f059f..b5859b6d155 100644 --- a/includes/admin/settings/class-wc-settings-integrations.php +++ b/includes/admin/settings/class-wc-settings-integrations.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.1.0 */ diff --git a/includes/admin/settings/class-wc-settings-page.php b/includes/admin/settings/class-wc-settings-page.php index 90b8cc8090a..b652182da23 100644 --- a/includes/admin/settings/class-wc-settings-page.php +++ b/includes/admin/settings/class-wc-settings-page.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.1.0 */ diff --git a/includes/admin/settings/class-wc-settings-payment-gateways.php b/includes/admin/settings/class-wc-settings-payment-gateways.php index 48c67e90a87..463f7ad9154 100644 --- a/includes/admin/settings/class-wc-settings-payment-gateways.php +++ b/includes/admin/settings/class-wc-settings-payment-gateways.php @@ -2,7 +2,7 @@ /** * WooCommerce Checkout Settings * - * @package WooCommerce/Admin + * @package WooCommerce\Admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/settings/class-wc-settings-products.php b/includes/admin/settings/class-wc-settings-products.php index 6c7d885a1db..35a63f78b02 100644 --- a/includes/admin/settings/class-wc-settings-products.php +++ b/includes/admin/settings/class-wc-settings-products.php @@ -2,7 +2,7 @@ /** * WooCommerce Product Settings * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.4.0 */ diff --git a/includes/admin/settings/class-wc-settings-shipping.php b/includes/admin/settings/class-wc-settings-shipping.php index 11e66d59a5d..79183328c30 100644 --- a/includes/admin/settings/class-wc-settings-shipping.php +++ b/includes/admin/settings/class-wc-settings-shipping.php @@ -2,7 +2,7 @@ /** * WooCommerce Shipping Settings * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.6.0 */ diff --git a/includes/admin/settings/class-wc-settings-tax.php b/includes/admin/settings/class-wc-settings-tax.php index 739674e7092..8f489ffd6cd 100644 --- a/includes/admin/settings/class-wc-settings-tax.php +++ b/includes/admin/settings/class-wc-settings-tax.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Admin - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @version 2.1.0 */ diff --git a/includes/admin/settings/views/html-admin-page-shipping-classes.php b/includes/admin/settings/views/html-admin-page-shipping-classes.php index 33d8f471201..ed2c906409a 100644 --- a/includes/admin/settings/views/html-admin-page-shipping-classes.php +++ b/includes/admin/settings/views/html-admin-page-shipping-classes.php @@ -2,7 +2,7 @@ /** * Shipping classes admin * - * @package WooCommerce/Admin/Shipping + * @package WooCommerce\Admin\Shipping */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/settings/views/html-admin-page-shipping-zone-methods.php b/includes/admin/settings/views/html-admin-page-shipping-zone-methods.php index 8bc70e58312..d2af3e72481 100644 --- a/includes/admin/settings/views/html-admin-page-shipping-zone-methods.php +++ b/includes/admin/settings/views/html-admin-page-shipping-zone-methods.php @@ -2,7 +2,7 @@ /** * Shipping zone admin * - * @package WooCommerce/Admin/Shipping + * @package WooCommerce\Admin\Shipping */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/settings/views/html-keys-edit.php b/includes/admin/settings/views/html-keys-edit.php index 7f317a7ced9..04da58e51cf 100644 --- a/includes/admin/settings/views/html-keys-edit.php +++ b/includes/admin/settings/views/html-keys-edit.php @@ -2,7 +2,7 @@ /** * Admin view: Edit API keys * - * @package WooCommerce/Admin/Settings + * @package WooCommerce\Admin\Settings */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/settings/views/html-webhooks-edit.php b/includes/admin/settings/views/html-webhooks-edit.php index 831bfec2a33..eaaf56dd984 100644 --- a/includes/admin/settings/views/html-webhooks-edit.php +++ b/includes/admin/settings/views/html-webhooks-edit.php @@ -2,7 +2,7 @@ /** * Admin View: Edit Webhooks * - * @package WooCommerce/Admin/Webhooks/Views + * @package WooCommerce\Admin\Webhooks\Views */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/views/html-admin-page-addons.php b/includes/admin/views/html-admin-page-addons.php index c2ac052b7e3..fcb0a1d8dd4 100644 --- a/includes/admin/views/html-admin-page-addons.php +++ b/includes/admin/views/html-admin-page-addons.php @@ -2,7 +2,7 @@ /** * Admin View: Page - Addons * - * @package WooCommerce/Admin + * @package WooCommerce\Admin * @var string $view * @var object $addons */ diff --git a/includes/admin/views/html-admin-page-product-export.php b/includes/admin/views/html-admin-page-product-export.php index 4f1c1c5b687..6ea370f9ec8 100644 --- a/includes/admin/views/html-admin-page-product-export.php +++ b/includes/admin/views/html-admin-page-product-export.php @@ -2,7 +2,7 @@ /** * Admin View: Product Export * - * @package WooCommerce/Admin/Export + * @package WooCommerce\Admin\Export */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/views/html-admin-page-status-logs-db.php b/includes/admin/views/html-admin-page-status-logs-db.php index 38013c0e571..317fe5c1896 100644 --- a/includes/admin/views/html-admin-page-status-logs-db.php +++ b/includes/admin/views/html-admin-page-status-logs-db.php @@ -2,7 +2,7 @@ /** * Admin View: Page - Status Database Logs * - * @package WooCommerce/Admin/Logs + * @package WooCommerce\Admin\Logs */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/views/html-admin-page-status-logs.php b/includes/admin/views/html-admin-page-status-logs.php index 0f5810e79b4..8bb41503a21 100644 --- a/includes/admin/views/html-admin-page-status-logs.php +++ b/includes/admin/views/html-admin-page-status-logs.php @@ -2,7 +2,7 @@ /** * Admin View: Page - Status Logs * - * @package WooCommerce/Admin/Logs + * @package WooCommerce\Admin\Logs */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/views/html-notice-regenerating-lookup-table.php b/includes/admin/views/html-notice-regenerating-lookup-table.php index 8cf8bceb887..7b30a853ee2 100644 --- a/includes/admin/views/html-notice-regenerating-lookup-table.php +++ b/includes/admin/views/html-notice-regenerating-lookup-table.php @@ -2,7 +2,7 @@ /** * Admin View: Notice - Regenerating product lookup table. * - * @package WooCommerce/admin + * @package WooCommerce\admin */ use Automattic\Jetpack\Constants; diff --git a/includes/admin/views/html-notice-template-check.php b/includes/admin/views/html-notice-template-check.php index 64742018040..50e2f3131b6 100644 --- a/includes/admin/views/html-notice-template-check.php +++ b/includes/admin/views/html-notice-template-check.php @@ -2,7 +2,7 @@ /** * Admin View: Notice - Template Check * - * @package WooCommerce/Views + * @package WooCommerce\Views */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/views/html-report-by-date.php b/includes/admin/views/html-report-by-date.php index c01da6f3b5d..860226a9ccc 100644 --- a/includes/admin/views/html-report-by-date.php +++ b/includes/admin/views/html-report-by-date.php @@ -2,7 +2,7 @@ /** * Admin View: Report by Date (with date filters) * - * @package WooCommerce/Admin/Reporting + * @package WooCommerce\Admin\Reporting */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index d5990e40eeb..bc9ae3c3ce9 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -2,7 +2,7 @@ /** * WooCommerce Admin Functions * - * @package WooCommerce/Admin/Functions + * @package WooCommerce\Admin\Functions * @version 2.4.0 */ diff --git a/includes/admin/wc-meta-box-functions.php b/includes/admin/wc-meta-box-functions.php index 61c451b3484..4c513a48179 100644 --- a/includes/admin/wc-meta-box-functions.php +++ b/includes/admin/wc-meta-box-functions.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category Core - * @package WooCommerce/Admin/Functions + * @package WooCommerce\Admin\Functions * @version 2.3.0 */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/class-wc-ajax.php b/includes/class-wc-ajax.php index 1ca5a3129a4..cd66f49d167 100644 --- a/includes/class-wc-ajax.php +++ b/includes/class-wc-ajax.php @@ -3,7 +3,7 @@ * WooCommerce WC_AJAX. AJAX Event Handlers. * * @class WC_AJAX - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 37356a34330..9f9001da9c2 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -7,7 +7,7 @@ * - Legacy REST API - Deprecated in 2.6.0. @see class-wc-legacy-api.php * - WP REST API - The main REST API in WooCommerce which is built on top of the WP REST API. * - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.0.0 */ diff --git a/includes/class-wc-auth.php b/includes/class-wc-auth.php index b6754497b69..6afa9bfa392 100644 --- a/includes/class-wc-auth.php +++ b/includes/class-wc-auth.php @@ -4,7 +4,7 @@ * * Handles wc-auth endpoint requests. * - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.4.0 */ diff --git a/includes/class-wc-autoloader.php b/includes/class-wc-autoloader.php index 480eddc3f5d..03153518d2c 100644 --- a/includes/class-wc-autoloader.php +++ b/includes/class-wc-autoloader.php @@ -2,7 +2,7 @@ /** * WooCommerce Autoloader. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 2.3.0 */ diff --git a/includes/class-wc-background-emailer.php b/includes/class-wc-background-emailer.php index 331fa87a27f..5c9d751e07f 100644 --- a/includes/class-wc-background-emailer.php +++ b/includes/class-wc-background-emailer.php @@ -3,7 +3,7 @@ * Background Emailer * * @version 3.0.1 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/class-wc-background-updater.php b/includes/class-wc-background-updater.php index a1253f6c4a2..424bb93262f 100644 --- a/includes/class-wc-background-updater.php +++ b/includes/class-wc-background-updater.php @@ -4,7 +4,7 @@ * * @version 2.6.0 * @deprecated 3.6.0 Replaced with queue. - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-breadcrumb.php b/includes/class-wc-breadcrumb.php index 1a3aa6dc909..592fe86c53f 100644 --- a/includes/class-wc-breadcrumb.php +++ b/includes/class-wc-breadcrumb.php @@ -2,7 +2,7 @@ /** * WC_Breadcrumb class. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 2.3.0 */ diff --git a/includes/class-wc-cache-helper.php b/includes/class-wc-cache-helper.php index e526659cbea..781fd735bea 100644 --- a/includes/class-wc-cache-helper.php +++ b/includes/class-wc-cache-helper.php @@ -2,7 +2,7 @@ /** * WC_Cache_Helper class. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-cart-fees.php b/includes/class-wc-cart-fees.php index 6f5a29f5203..f80376f996a 100644 --- a/includes/class-wc-cart-fees.php +++ b/includes/class-wc-cart-fees.php @@ -6,7 +6,7 @@ * * We suggest using the action woocommerce_cart_calculate_fees hook for adding fees. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.2.0 */ diff --git a/includes/class-wc-cart-session.php b/includes/class-wc-cart-session.php index 2bb0db176f6..d8eb30ca8e9 100644 --- a/includes/class-wc-cart-session.php +++ b/includes/class-wc-cart-session.php @@ -2,7 +2,7 @@ /** * Cart session handling class. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.2.0 */ diff --git a/includes/class-wc-cart-totals.php b/includes/class-wc-cart-totals.php index 1ab3a15f5a9..a08c1847416 100644 --- a/includes/class-wc-cart-totals.php +++ b/includes/class-wc-cart-totals.php @@ -9,7 +9,7 @@ * - if something is being stored e.g. item total, store unrounded. This is so taxes can be recalculated later accurately. * - if calculating a total, round (if settings allow). * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.2.0 */ diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index 3b086137acd..91e62da962f 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -5,7 +5,7 @@ * The WooCommerce cart class stores cart data and active coupons as well as handling customer sessions and some cart related urls. * The cart class also has a price calculation function which calls upon other classes to calculate totals. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 2.1.0 */ diff --git a/includes/class-wc-checkout.php b/includes/class-wc-checkout.php index 955efb49726..195c8c2d7e5 100644 --- a/includes/class-wc-checkout.php +++ b/includes/class-wc-checkout.php @@ -4,7 +4,7 @@ * * The WooCommerce checkout class handles the checkout process, collecting user data and processing the payment. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.4.0 */ diff --git a/includes/class-wc-comments.php b/includes/class-wc-comments.php index ab4e6945f01..2900e97d5e2 100644 --- a/includes/class-wc-comments.php +++ b/includes/class-wc-comments.php @@ -4,7 +4,7 @@ * * Handle comments (reviews and order notes). * - * @package WooCommerce/Classes/Products + * @package WooCommerce\Classes\Products * @version 2.3.0 */ diff --git a/includes/class-wc-coupon.php b/includes/class-wc-coupon.php index 5ca6867a5a8..9ef9e02319a 100644 --- a/includes/class-wc-coupon.php +++ b/includes/class-wc-coupon.php @@ -4,7 +4,7 @@ * * The WooCommerce coupons class gets coupon data from storage and checks coupon validity. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 */ diff --git a/includes/class-wc-customer-download-log.php b/includes/class-wc-customer-download-log.php index 37d6e1ea23f..cec6c05095a 100644 --- a/includes/class-wc-customer-download-log.php +++ b/includes/class-wc-customer-download-log.php @@ -2,7 +2,7 @@ /** * Class for customer download logs. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.3.0 * @since 3.3.0 */ diff --git a/includes/class-wc-customer-download.php b/includes/class-wc-customer-download.php index 26dadb0f46d..1e1a6d35323 100644 --- a/includes/class-wc-customer-download.php +++ b/includes/class-wc-customer-download.php @@ -2,7 +2,7 @@ /** * Class for customer download permissions. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-customer.php b/includes/class-wc-customer.php index 4f338a9dd40..cb648fc83da 100644 --- a/includes/class-wc-customer.php +++ b/includes/class-wc-customer.php @@ -2,7 +2,7 @@ /** * The WooCommerce customer class handles storage of the current customer's data, such as location. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 */ diff --git a/includes/class-wc-datetime.php b/includes/class-wc-datetime.php index 233f7953aba..1778503d5d1 100644 --- a/includes/class-wc-datetime.php +++ b/includes/class-wc-datetime.php @@ -4,7 +4,7 @@ * timezone is absent * * @since 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-discounts.php b/includes/class-wc-discounts.php index 2a11b517510..f1086810f78 100644 --- a/includes/class-wc-discounts.php +++ b/includes/class-wc-discounts.php @@ -2,7 +2,7 @@ /** * Discount calculation * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @since 3.2.0 */ diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index 1d4ae53abe5..a2826527f43 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -4,7 +4,7 @@ * * Handle digital downloads. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 2.2.0 */ diff --git a/includes/class-wc-emails.php b/includes/class-wc-emails.php index 2d2f4d24c8d..a097a629e75 100644 --- a/includes/class-wc-emails.php +++ b/includes/class-wc-emails.php @@ -4,7 +4,7 @@ * * WooCommerce Emails Class which handles the sending on transactional emails and email templates. This class loads in available emails. * - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @version 2.3.0 */ diff --git a/includes/class-wc-embed.php b/includes/class-wc-embed.php index 296e89c7040..da14279a749 100644 --- a/includes/class-wc-embed.php +++ b/includes/class-wc-embed.php @@ -3,7 +3,7 @@ * WooCommerce product embed * * @version 2.4.11 - * @package WooCommerce/Classes/Embed + * @package WooCommerce\Classes\Embed */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/class-wc-form-handler.php b/includes/class-wc-form-handler.php index 80a4336aba5..e64a0b3fcb6 100644 --- a/includes/class-wc-form-handler.php +++ b/includes/class-wc-form-handler.php @@ -2,7 +2,7 @@ /** * Handle frontend forms. * - * @package WooCommerce/Classes/ + * @package WooCommerce\Classes\ */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-frontend-scripts.php b/includes/class-wc-frontend-scripts.php index 935f0696803..ffd18d99dea 100644 --- a/includes/class-wc-frontend-scripts.php +++ b/includes/class-wc-frontend-scripts.php @@ -2,7 +2,7 @@ /** * Handle frontend scripts * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 2.3.0 */ diff --git a/includes/class-wc-geo-ip.php b/includes/class-wc-geo-ip.php index 9aeb5afc1c2..c79be25b985 100644 --- a/includes/class-wc-geo-ip.php +++ b/includes/class-wc-geo-ip.php @@ -4,7 +4,7 @@ * * This class is a fork of GeoIP class from MaxMind LLC. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 2.4.0 * @deprecated 3.4.0 */ diff --git a/includes/class-wc-geolocation.php b/includes/class-wc-geolocation.php index 64cf628f956..97d918404ab 100644 --- a/includes/class-wc-geolocation.php +++ b/includes/class-wc-geolocation.php @@ -6,7 +6,7 @@ * * This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.9.0 */ diff --git a/includes/class-wc-https.php b/includes/class-wc-https.php index de3e6f4ce85..84e3aeddd7b 100644 --- a/includes/class-wc-https.php +++ b/includes/class-wc-https.php @@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WC_HTTPS * @version 2.2.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @category Class * @author WooThemes */ diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index 9a58422fbaa..51dff34dea2 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -2,7 +2,7 @@ /** * Installation related functions and actions. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 */ diff --git a/includes/class-wc-integrations.php b/includes/class-wc-integrations.php index 13d906060a2..f29360b011b 100644 --- a/includes/class-wc-integrations.php +++ b/includes/class-wc-integrations.php @@ -5,7 +5,7 @@ * Loads Integrations into WooCommerce. * * @version 3.9.0 - * @package WooCommerce/Classes/Integrations + * @package WooCommerce\Classes\Integrations */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-log-levels.php b/includes/class-wc-log-levels.php index 0f635de92bd..f577b55c4c6 100644 --- a/includes/class-wc-log-levels.php +++ b/includes/class-wc-log-levels.php @@ -3,7 +3,7 @@ * Standard log levels * * @version 3.2.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-logger.php b/includes/class-wc-logger.php index 41bb7f6db2e..040dd580529 100644 --- a/includes/class-wc-logger.php +++ b/includes/class-wc-logger.php @@ -4,7 +4,7 @@ * * @class WC_Logger * @version 2.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/class-wc-order-factory.php b/includes/class-wc-order-factory.php index bc67f4b8a03..a3077871813 100644 --- a/includes/class-wc-order-factory.php +++ b/includes/class-wc-order-factory.php @@ -5,7 +5,7 @@ * The WooCommerce order factory creating the right order objects. * * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-order-item-coupon.php b/includes/class-wc-order-item-coupon.php index 5aada6cb307..1a8aa50702a 100644 --- a/includes/class-wc-order-item-coupon.php +++ b/includes/class-wc-order-item-coupon.php @@ -2,7 +2,7 @@ /** * Order Line Item (coupon) * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-order-item-fee.php b/includes/class-wc-order-item-fee.php index 7b280f05795..44e1ee12d2c 100644 --- a/includes/class-wc-order-item-fee.php +++ b/includes/class-wc-order-item-fee.php @@ -5,7 +5,7 @@ * Fee is an amount of money charged for a particular piece of work * or for a particular right or service, and not supposed to be negative. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-order-item-meta.php b/includes/class-wc-order-item-meta.php index 2d2f72f03f9..693be232328 100644 --- a/includes/class-wc-order-item-meta.php +++ b/includes/class-wc-order-item-meta.php @@ -4,7 +4,7 @@ * * A Simple class for managing order item meta so plugins add it in the correct format. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @deprecated 3.0.0 wc_display_item_meta function is used instead. * @version 2.4 */ diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php index 24e8aab66ce..a32a6268357 100644 --- a/includes/class-wc-order-item-product.php +++ b/includes/class-wc-order-item-product.php @@ -2,7 +2,7 @@ /** * Order Line Item (product) * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-order-item-shipping.php b/includes/class-wc-order-item-shipping.php index c5ca078127d..6602e87ae24 100644 --- a/includes/class-wc-order-item-shipping.php +++ b/includes/class-wc-order-item-shipping.php @@ -2,7 +2,7 @@ /** * Order Line Item (shipping) * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-order-item-tax.php b/includes/class-wc-order-item-tax.php index ac34b61eccb..c41e3881f9f 100644 --- a/includes/class-wc-order-item-tax.php +++ b/includes/class-wc-order-item-tax.php @@ -2,7 +2,7 @@ /** * Order Line Item (tax) * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-order-item.php b/includes/class-wc-order-item.php index 6bc4df36c23..e7c916157cb 100644 --- a/includes/class-wc-order-item.php +++ b/includes/class-wc-order-item.php @@ -5,7 +5,7 @@ * A class which represents an item within an order and handles CRUD. * Uses ArrayAccess to be BW compatible with WC_Orders::get_items(). * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-order-query.php b/includes/class-wc-order-query.php index 8069ddd5e4d..4f481c8d0ef 100644 --- a/includes/class-wc-order-query.php +++ b/includes/class-wc-order-query.php @@ -3,7 +3,7 @@ * Parameter-based Order querying * Args and usage: https://github.com/woocommerce/woocommerce/wiki/wc_get_orders-and-WC_Order_Query * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.1.0 * @since 3.1.0 */ diff --git a/includes/class-wc-order-refund.php b/includes/class-wc-order-refund.php index d5a8518e5be..c384d044d65 100644 --- a/includes/class-wc-order-refund.php +++ b/includes/class-wc-order-refund.php @@ -4,7 +4,7 @@ * contain much of the same data. * * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-payment-gateways.php b/includes/class-wc-payment-gateways.php index b7701cc758f..c6114ef68c7 100644 --- a/includes/class-wc-payment-gateways.php +++ b/includes/class-wc-payment-gateways.php @@ -5,7 +5,7 @@ * Loads payment gateways via hooks for use in the store. * * @version 2.2.0 - * @package WooCommerce/Classes/Payment + * @package WooCommerce\Classes\Payment */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-payment-tokens.php b/includes/class-wc-payment-tokens.php index 8b56f5b4a87..85625d02acc 100644 --- a/includes/class-wc-payment-tokens.php +++ b/includes/class-wc-payment-tokens.php @@ -4,7 +4,7 @@ * * An API for storing and managing tokens for gateways and customers. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 2.6.0 */ diff --git a/includes/class-wc-post-data.php b/includes/class-wc-post-data.php index cffabae2f38..4e8d61fb85a 100644 --- a/includes/class-wc-post-data.php +++ b/includes/class-wc-post-data.php @@ -4,7 +4,7 @@ * * Standardises certain post data on save. * - * @package WooCommerce/Classes/Data + * @package WooCommerce\Classes\Data * @version 2.2.0 */ diff --git a/includes/class-wc-post-types.php b/includes/class-wc-post-types.php index 36382e5fae3..79c65823ccc 100644 --- a/includes/class-wc-post-types.php +++ b/includes/class-wc-post-types.php @@ -4,7 +4,7 @@ * * Registers post types and taxonomies. * - * @package WooCommerce/Classes/Products + * @package WooCommerce\Classes\Products * @version 2.5.0 */ diff --git a/includes/class-wc-privacy-background-process.php b/includes/class-wc-privacy-background-process.php index 468b214bce0..f75fa4261da 100644 --- a/includes/class-wc-privacy-background-process.php +++ b/includes/class-wc-privacy-background-process.php @@ -2,7 +2,7 @@ /** * Order cleanup background process. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.4.0 * @since 3.4.0 */ diff --git a/includes/class-wc-product-attribute.php b/includes/class-wc-product-attribute.php index 228dae1a319..14f1901c7aa 100644 --- a/includes/class-wc-product-attribute.php +++ b/includes/class-wc-product-attribute.php @@ -5,7 +5,7 @@ * Attributes can be global (taxonomy based) or local to the product itself. * Uses ArrayAccess to be BW compatible with previous ways of reading attributes. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-product-download.php b/includes/class-wc-product-download.php index 96711bc4807..1c13bf1b3b4 100644 --- a/includes/class-wc-product-download.php +++ b/includes/class-wc-product-download.php @@ -2,7 +2,7 @@ /** * Represents a file which can be downloaded. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-product-external.php b/includes/class-wc-product-external.php index b99f10b90bc..f88d45fb5c6 100644 --- a/includes/class-wc-product-external.php +++ b/includes/class-wc-product-external.php @@ -4,7 +4,7 @@ * * External products cannot be bought; they link offsite. Extends simple products. * - * @package WooCommerce/Classes/Products + * @package WooCommerce\Classes\Products * @version 3.0.0 */ diff --git a/includes/class-wc-product-factory.php b/includes/class-wc-product-factory.php index 02bd8d1cd5a..9344f675310 100644 --- a/includes/class-wc-product-factory.php +++ b/includes/class-wc-product-factory.php @@ -4,7 +4,7 @@ * * The WooCommerce product factory creating the right product object. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 */ diff --git a/includes/class-wc-product-query.php b/includes/class-wc-product-query.php index 1de8bf210d5..8562a1fc1e9 100644 --- a/includes/class-wc-product-query.php +++ b/includes/class-wc-product-query.php @@ -4,7 +4,7 @@ * * Args and usage: https://github.com/woocommerce/woocommerce/wiki/wc_get_products-and-WC_Product_Query * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.2.0 * @since 3.2.0 */ diff --git a/includes/class-wc-product-simple.php b/includes/class-wc-product-simple.php index 5a828ec0d17..6dfebfc5191 100644 --- a/includes/class-wc-product-simple.php +++ b/includes/class-wc-product-simple.php @@ -4,7 +4,7 @@ * * The default product type kinda product. * - * @package WooCommerce/Classes/Products + * @package WooCommerce\Classes\Products */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index 93c1c237724..135705e81d5 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -5,7 +5,7 @@ * The WooCommerce product class handles individual product data. * * @version 3.0.0 - * @package WooCommerce/Classes/Products + * @package WooCommerce\Classes\Products */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-product-variation.php b/includes/class-wc-product-variation.php index f574ba1fd01..2204f85d963 100644 --- a/includes/class-wc-product-variation.php +++ b/includes/class-wc-product-variation.php @@ -4,7 +4,7 @@ * * The WooCommerce product variation class handles product variation data. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 */ diff --git a/includes/class-wc-rate-limiter.php b/includes/class-wc-rate-limiter.php index f50bd229b52..aba4fb01489 100644 --- a/includes/class-wc-rate-limiter.php +++ b/includes/class-wc-rate-limiter.php @@ -19,7 +19,7 @@ * add_notice( 'Sorry, too soon!' ); * } * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.9.0 * @since 3.9.0 */ diff --git a/includes/class-wc-regenerate-images-request.php b/includes/class-wc-regenerate-images-request.php index 0d0d90dbf33..0fc08a18c0f 100644 --- a/includes/class-wc-regenerate-images-request.php +++ b/includes/class-wc-regenerate-images-request.php @@ -2,7 +2,7 @@ /** * All functionality to regenerate images in the background when settings change. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.3.0 * @since 3.3.0 */ diff --git a/includes/class-wc-regenerate-images.php b/includes/class-wc-regenerate-images.php index a26590a1cb9..023deabfd83 100644 --- a/includes/class-wc-regenerate-images.php +++ b/includes/class-wc-regenerate-images.php @@ -4,7 +4,7 @@ * * All functionality pertaining to regenerating product images in realtime. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.5.0 * @since 3.3.0 */ diff --git a/includes/class-wc-register-wp-admin-settings.php b/includes/class-wc-register-wp-admin-settings.php index 822972f6985..9dbefe84b46 100644 --- a/includes/class-wc-register-wp-admin-settings.php +++ b/includes/class-wc-register-wp-admin-settings.php @@ -2,7 +2,7 @@ /** * Take settings registered for WP-Admin and hooks them up to the REST API * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.0.0 * @since 3.0.0 */ diff --git a/includes/class-wc-rest-authentication.php b/includes/class-wc-rest-authentication.php index e58108f69d4..12014593ce7 100644 --- a/includes/class-wc-rest-authentication.php +++ b/includes/class-wc-rest-authentication.php @@ -2,7 +2,7 @@ /** * REST API Authentication * - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.6.0 */ diff --git a/includes/class-wc-rest-exception.php b/includes/class-wc-rest-exception.php index 8d7fd704a08..d22a183ee45 100644 --- a/includes/class-wc-rest-exception.php +++ b/includes/class-wc-rest-exception.php @@ -4,7 +4,7 @@ * * Extends Exception to provide additional data. * - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.6.0 */ diff --git a/includes/class-wc-session-handler.php b/includes/class-wc-session-handler.php index 689e61e083e..cacda9e59a2 100644 --- a/includes/class-wc-session-handler.php +++ b/includes/class-wc-session-handler.php @@ -7,7 +7,7 @@ * * @class WC_Session_Handler * @version 2.5.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/class-wc-shipping-rate.php b/includes/class-wc-shipping-rate.php index 06dc919123c..1248a70a423 100644 --- a/includes/class-wc-shipping-rate.php +++ b/includes/class-wc-shipping-rate.php @@ -4,7 +4,7 @@ * * Simple Class for storing rates. * - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping * @since 2.6.0 */ diff --git a/includes/class-wc-shipping-zone.php b/includes/class-wc-shipping-zone.php index 3accf0a1d74..c52b5cf79fe 100644 --- a/includes/class-wc-shipping-zone.php +++ b/includes/class-wc-shipping-zone.php @@ -4,7 +4,7 @@ * * @since 2.6.0 * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-shipping-zones.php b/includes/class-wc-shipping-zones.php index cb71dcd1abd..4acff8b8991 100644 --- a/includes/class-wc-shipping-zones.php +++ b/includes/class-wc-shipping-zones.php @@ -2,7 +2,7 @@ /** * Handles storage and retrieval of shipping zones * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.3.0 * @since 2.6.0 */ diff --git a/includes/class-wc-shipping.php b/includes/class-wc-shipping.php index a803c400f2f..91a9ab6a774 100644 --- a/includes/class-wc-shipping.php +++ b/includes/class-wc-shipping.php @@ -5,7 +5,7 @@ * Handles shipping and loads shipping methods via hooks. * * @version 2.6.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ use Automattic\Jetpack\Constants; diff --git a/includes/class-wc-shortcodes.php b/includes/class-wc-shortcodes.php index a26419ae89e..705b57d3e92 100644 --- a/includes/class-wc-shortcodes.php +++ b/includes/class-wc-shortcodes.php @@ -2,7 +2,7 @@ /** * Shortcodes * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @version 3.2.0 */ diff --git a/includes/class-wc-structured-data.php b/includes/class-wc-structured-data.php index 3c2354c5a5b..070bea646b0 100644 --- a/includes/class-wc-structured-data.php +++ b/includes/class-wc-structured-data.php @@ -2,7 +2,7 @@ /** * Structured data's handler and generator using JSON-LD format. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @since 3.0.0 * @version 3.0.0 */ diff --git a/includes/class-wc-tax.php b/includes/class-wc-tax.php index a7784c3e702..70a34ab6c0c 100644 --- a/includes/class-wc-tax.php +++ b/includes/class-wc-tax.php @@ -2,7 +2,7 @@ /** * Tax calculation and rate finding class. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-template-loader.php b/includes/class-wc-template-loader.php index 28e0606f6b4..cfbda8c8b0f 100644 --- a/includes/class-wc-template-loader.php +++ b/includes/class-wc-template-loader.php @@ -2,7 +2,7 @@ /** * Template Loader * - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/class-wc-tracker.php b/includes/class-wc-tracker.php index 02f8a169a8b..ca197d87bbe 100644 --- a/includes/class-wc-tracker.php +++ b/includes/class-wc-tracker.php @@ -7,7 +7,7 @@ * * @class WC_Tracker * @since 2.3.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/class-wc-webhook.php b/includes/class-wc-webhook.php index c32f585cba4..b20766536fb 100644 --- a/includes/class-wc-webhook.php +++ b/includes/class-wc-webhook.php @@ -7,7 +7,7 @@ * Webhooks are enqueued to their associated actions, delivered, and logged. * * @version 3.2.0 - * @package WooCommerce/Webhooks + * @package WooCommerce\Webhooks * @since 2.2.0 */ diff --git a/includes/data-stores/abstract-wc-order-data-store-cpt.php b/includes/data-stores/abstract-wc-order-data-store-cpt.php index 20b77b00797..fe8233e8bcf 100644 --- a/includes/data-stores/abstract-wc-order-data-store-cpt.php +++ b/includes/data-stores/abstract-wc-order-data-store-cpt.php @@ -2,7 +2,7 @@ /** * Abstract_WC_Order_Data_Store_CPT class file. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/data-stores/class-wc-data-store-wp.php b/includes/data-stores/class-wc-data-store-wp.php index fad8a1a3271..10222a73a27 100644 --- a/includes/data-stores/class-wc-data-store-wp.php +++ b/includes/data-stores/class-wc-data-store-wp.php @@ -6,7 +6,7 @@ * your own meta handling functions. * * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/data-stores/class-wc-order-data-store-cpt.php b/includes/data-stores/class-wc-order-data-store-cpt.php index bc8c2961f0d..0e19ecd4370 100644 --- a/includes/data-stores/class-wc-order-data-store-cpt.php +++ b/includes/data-stores/class-wc-order-data-store-cpt.php @@ -2,7 +2,7 @@ /** * WC_Order_Data_Store_CPT class file. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php index e417c1d9c6a..9e17fb52869 100644 --- a/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-data-store-cpt.php @@ -2,7 +2,7 @@ /** * WC_Product_Data_Store_CPT class file. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/includes/data-stores/class-wc-product-variable-data-store-cpt.php index dd2c2b16bbe..0f09da96679 100644 --- a/includes/data-stores/class-wc-product-variable-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variable-data-store-cpt.php @@ -2,7 +2,7 @@ /** * File for WC Variable Product Data Store class. * - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/data-stores/class-wc-webhook-data-store.php b/includes/data-stores/class-wc-webhook-data-store.php index a684981238b..947e89edb13 100644 --- a/includes/data-stores/class-wc-webhook-data-store.php +++ b/includes/data-stores/class-wc-webhook-data-store.php @@ -3,7 +3,7 @@ * Webhook Data Store * * @version 3.3.0 - * @package WooCommerce/Classes/Data_Store + * @package WooCommerce\Classes\Data_Store */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/emails/class-wc-email-cancelled-order.php b/includes/emails/class-wc-email-cancelled-order.php index d245a9d4f91..eeb4d34c73e 100644 --- a/includes/emails/class-wc-email-cancelled-order.php +++ b/includes/emails/class-wc-email-cancelled-order.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Cancelled_Order', false ) ) : * * @class WC_Email_Cancelled_Order * @version 2.2.7 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Cancelled_Order extends WC_Email { diff --git a/includes/emails/class-wc-email-customer-completed-order.php b/includes/emails/class-wc-email-customer-completed-order.php index 91c1fe884ca..17958670e8c 100644 --- a/includes/emails/class-wc-email-customer-completed-order.php +++ b/includes/emails/class-wc-email-customer-completed-order.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Customer_Completed_Order', false ) ) : * * @class WC_Email_Customer_Completed_Order * @version 2.0.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Customer_Completed_Order extends WC_Email { diff --git a/includes/emails/class-wc-email-customer-invoice.php b/includes/emails/class-wc-email-customer-invoice.php index a1973bfbc3e..0a2592cacf5 100644 --- a/includes/emails/class-wc-email-customer-invoice.php +++ b/includes/emails/class-wc-email-customer-invoice.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Customer_Invoice', false ) ) : * * @class WC_Email_Customer_Invoice * @version 3.5.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Customer_Invoice extends WC_Email { diff --git a/includes/emails/class-wc-email-customer-new-account.php b/includes/emails/class-wc-email-customer-new-account.php index 674d18b3890..3cd0a825b58 100644 --- a/includes/emails/class-wc-email-customer-new-account.php +++ b/includes/emails/class-wc-email-customer-new-account.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Customer_New_Account', false ) ) : * * @class WC_Email_Customer_New_Account * @version 3.5.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Customer_New_Account extends WC_Email { diff --git a/includes/emails/class-wc-email-customer-note.php b/includes/emails/class-wc-email-customer-note.php index 33e8aa6e8c1..cf1b2651901 100644 --- a/includes/emails/class-wc-email-customer-note.php +++ b/includes/emails/class-wc-email-customer-note.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Customer_Note', false ) ) : * * @class WC_Email_Customer_Note * @version 3.5.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Customer_Note extends WC_Email { diff --git a/includes/emails/class-wc-email-customer-on-hold-order.php b/includes/emails/class-wc-email-customer-on-hold-order.php index 2985c40a0fc..080abb92395 100644 --- a/includes/emails/class-wc-email-customer-on-hold-order.php +++ b/includes/emails/class-wc-email-customer-on-hold-order.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Customer_On_Hold_Order', false ) ) : * * @class WC_Email_Customer_On_Hold_Order * @version 2.6.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Customer_On_Hold_Order extends WC_Email { diff --git a/includes/emails/class-wc-email-customer-processing-order.php b/includes/emails/class-wc-email-customer-processing-order.php index 42fc858c038..18b8c95ac51 100644 --- a/includes/emails/class-wc-email-customer-processing-order.php +++ b/includes/emails/class-wc-email-customer-processing-order.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Customer_Processing_Order', false ) ) : * * @class WC_Email_Customer_Processing_Order * @version 3.5.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Customer_Processing_Order extends WC_Email { diff --git a/includes/emails/class-wc-email-customer-refunded-order.php b/includes/emails/class-wc-email-customer-refunded-order.php index c70373759d9..1536ba33131 100644 --- a/includes/emails/class-wc-email-customer-refunded-order.php +++ b/includes/emails/class-wc-email-customer-refunded-order.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Customer_Refunded_Order', false ) ) : * * @class WC_Email_Customer_Refunded_Order * @version 3.5.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Customer_Refunded_Order extends WC_Email { diff --git a/includes/emails/class-wc-email-customer-reset-password.php b/includes/emails/class-wc-email-customer-reset-password.php index 9392e1f26fd..7603097e4de 100644 --- a/includes/emails/class-wc-email-customer-reset-password.php +++ b/includes/emails/class-wc-email-customer-reset-password.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Customer_Reset_Password', false ) ) : * * @class WC_Email_Customer_Reset_Password * @version 3.5.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Customer_Reset_Password extends WC_Email { diff --git a/includes/emails/class-wc-email-failed-order.php b/includes/emails/class-wc-email-failed-order.php index bf7c43fdf15..0766d9ac9b4 100644 --- a/includes/emails/class-wc-email-failed-order.php +++ b/includes/emails/class-wc-email-failed-order.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_Failed_Order', false ) ) : * * @class WC_Email_Failed_Order * @version 2.5.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_Failed_Order extends WC_Email { diff --git a/includes/emails/class-wc-email-new-order.php b/includes/emails/class-wc-email-new-order.php index 159c6e45b30..0c063d61e76 100644 --- a/includes/emails/class-wc-email-new-order.php +++ b/includes/emails/class-wc-email-new-order.php @@ -18,7 +18,7 @@ if ( ! class_exists( 'WC_Email_New_Order' ) ) : * * @class WC_Email_New_Order * @version 2.0.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Email */ class WC_Email_New_Order extends WC_Email { diff --git a/includes/emails/class-wc-email.php b/includes/emails/class-wc-email.php index a16abe1a252..a47736ff75f 100644 --- a/includes/emails/class-wc-email.php +++ b/includes/emails/class-wc-email.php @@ -20,7 +20,7 @@ if ( class_exists( 'WC_Email', false ) ) { * * @class WC_Email * @version 2.5.0 - * @package WooCommerce/Classes/Emails + * @package WooCommerce\Classes\Emails * @extends WC_Settings_API */ class WC_Email extends WC_Settings_API { diff --git a/includes/export/abstract-wc-csv-batch-exporter.php b/includes/export/abstract-wc-csv-batch-exporter.php index 17e97aa7f53..b48fd53a4ae 100644 --- a/includes/export/abstract-wc-csv-batch-exporter.php +++ b/includes/export/abstract-wc-csv-batch-exporter.php @@ -4,7 +4,7 @@ * * Based on https://pippinsplugins.com/batch-processing-for-big-data/ * - * @package WooCommerce/Export + * @package WooCommerce\Export * @version 3.1.0 */ diff --git a/includes/export/abstract-wc-csv-exporter.php b/includes/export/abstract-wc-csv-exporter.php index cda963538db..e5631b9a5a3 100644 --- a/includes/export/abstract-wc-csv-exporter.php +++ b/includes/export/abstract-wc-csv-exporter.php @@ -2,7 +2,7 @@ /** * Handles CSV export. * - * @package WooCommerce/Export + * @package WooCommerce\Export * @version 3.1.0 */ diff --git a/includes/export/class-wc-product-csv-exporter.php b/includes/export/class-wc-product-csv-exporter.php index 394353bd6e4..23264604176 100644 --- a/includes/export/class-wc-product-csv-exporter.php +++ b/includes/export/class-wc-product-csv-exporter.php @@ -2,7 +2,7 @@ /** * Handles product CSV export. * - * @package WooCommerce/Export + * @package WooCommerce\Export * @version 3.1.0 */ diff --git a/includes/gateways/bacs/class-wc-gateway-bacs.php b/includes/gateways/bacs/class-wc-gateway-bacs.php index 83f43639e01..3ec175dfd59 100644 --- a/includes/gateways/bacs/class-wc-gateway-bacs.php +++ b/includes/gateways/bacs/class-wc-gateway-bacs.php @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WC_Gateway_BACS * @extends WC_Payment_Gateway * @version 2.1.0 - * @package WooCommerce/Classes/Payment + * @package WooCommerce\Classes\Payment */ class WC_Gateway_BACS extends WC_Payment_Gateway { diff --git a/includes/gateways/cheque/class-wc-gateway-cheque.php b/includes/gateways/cheque/class-wc-gateway-cheque.php index 40f2599438f..7f5d003b72e 100644 --- a/includes/gateways/cheque/class-wc-gateway-cheque.php +++ b/includes/gateways/cheque/class-wc-gateway-cheque.php @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WC_Gateway_Cheque * @extends WC_Payment_Gateway * @version 2.1.0 - * @package WooCommerce/Classes/Payment + * @package WooCommerce\Classes\Payment */ class WC_Gateway_Cheque extends WC_Payment_Gateway { diff --git a/includes/gateways/class-wc-payment-gateway-cc.php b/includes/gateways/class-wc-payment-gateway-cc.php index 22fe83bee3f..0ddd4621697 100644 --- a/includes/gateways/class-wc-payment-gateway-cc.php +++ b/includes/gateways/class-wc-payment-gateway-cc.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * Credit Card Payment Gateway * * @since 2.6.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ class WC_Payment_Gateway_CC extends WC_Payment_Gateway { diff --git a/includes/gateways/class-wc-payment-gateway-echeck.php b/includes/gateways/class-wc-payment-gateway-echeck.php index 69a564816df..c7754b664f9 100644 --- a/includes/gateways/class-wc-payment-gateway-echeck.php +++ b/includes/gateways/class-wc-payment-gateway-echeck.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * Class for eCheck Payment Gateway * * @since 2.6.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ class WC_Payment_Gateway_ECheck extends WC_Payment_Gateway { diff --git a/includes/gateways/cod/class-wc-gateway-cod.php b/includes/gateways/cod/class-wc-gateway-cod.php index a77bbede872..33c17643bf0 100644 --- a/includes/gateways/cod/class-wc-gateway-cod.php +++ b/includes/gateways/cod/class-wc-gateway-cod.php @@ -19,7 +19,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WC_Gateway_COD * @extends WC_Payment_Gateway * @version 2.1.0 - * @package WooCommerce/Classes/Payment + * @package WooCommerce\Classes\Payment */ class WC_Gateway_COD extends WC_Payment_Gateway { diff --git a/includes/gateways/paypal/class-wc-gateway-paypal.php b/includes/gateways/paypal/class-wc-gateway-paypal.php index 03d7972e7bd..6cd1a03dd83 100644 --- a/includes/gateways/paypal/class-wc-gateway-paypal.php +++ b/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -7,7 +7,7 @@ * @class WC_Gateway_Paypal * @extends WC_Payment_Gateway * @version 2.3.0 - * @package WooCommerce/Classes/Payment + * @package WooCommerce\Classes\Payment */ use Automattic\Jetpack\Constants; diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php index ca15f4a74d6..b98b8eee30b 100644 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php @@ -2,7 +2,7 @@ /** * Handles responses from PayPal IPN. * - * @package WooCommerce/PayPal + * @package WooCommerce\PayPal * @version 3.3.0 */ diff --git a/includes/gateways/paypal/includes/settings-paypal.php b/includes/gateways/paypal/includes/settings-paypal.php index 00bad8a706e..199c56ea758 100644 --- a/includes/gateways/paypal/includes/settings-paypal.php +++ b/includes/gateways/paypal/includes/settings-paypal.php @@ -2,7 +2,7 @@ /** * Settings for PayPal Gateway. * - * @package WooCommerce/Classes/Payment + * @package WooCommerce\Classes\Payment */ defined( 'ABSPATH' ) || exit; diff --git a/includes/import/abstract-wc-product-importer.php b/includes/import/abstract-wc-product-importer.php index 9cdd55af0f0..aa65051e0fe 100644 --- a/includes/import/abstract-wc-product-importer.php +++ b/includes/import/abstract-wc-product-importer.php @@ -2,7 +2,7 @@ /** * Abstract Product importer * - * @package WooCommerce/Import + * @package WooCommerce\Import * @version 3.1.0 */ diff --git a/includes/import/class-wc-product-csv-importer.php b/includes/import/class-wc-product-csv-importer.php index c361f95faea..c9c11f44684 100644 --- a/includes/import/class-wc-product-csv-importer.php +++ b/includes/import/class-wc-product-csv-importer.php @@ -2,7 +2,7 @@ /** * WooCommerce Product CSV importer * - * @package WooCommerce/Import + * @package WooCommerce\Import * @version 3.1.0 */ diff --git a/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-database-service.php b/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-database-service.php index 0778276626e..8a78efb4fbb 100644 --- a/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-database-service.php +++ b/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-database-service.php @@ -3,7 +3,7 @@ * The database service class file. * * @version 3.9.0 - * @package WooCommerce/Integrations + * @package WooCommerce\Integrations */ defined( 'ABSPATH' ) || exit; diff --git a/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-geolocation.php b/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-geolocation.php index 80a338ea2b8..1b84f3f06a9 100644 --- a/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-geolocation.php +++ b/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-geolocation.php @@ -3,7 +3,7 @@ * MaxMind Geolocation Integration * * @version 3.9.0 - * @package WooCommerce/Integrations + * @package WooCommerce\Integrations */ defined( 'ABSPATH' ) || exit; diff --git a/includes/interfaces/class-wc-abstract-order-data-store-interface.php b/includes/interfaces/class-wc-abstract-order-data-store-interface.php index 5688361b918..c043c34e214 100644 --- a/includes/interfaces/class-wc-abstract-order-data-store-interface.php +++ b/includes/interfaces/class-wc-abstract-order-data-store-interface.php @@ -3,7 +3,7 @@ * Order Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interfaces + * @package WooCommerce\Interfaces */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-coupon-data-store-interface.php b/includes/interfaces/class-wc-coupon-data-store-interface.php index c97e2c2f6d2..95256bcc00d 100644 --- a/includes/interfaces/class-wc-coupon-data-store-interface.php +++ b/includes/interfaces/class-wc-coupon-data-store-interface.php @@ -3,7 +3,7 @@ * Coupon Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interfaces + * @package WooCommerce\Interfaces */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-customer-data-store-interface.php b/includes/interfaces/class-wc-customer-data-store-interface.php index b353fc3b0f2..d2601898516 100644 --- a/includes/interfaces/class-wc-customer-data-store-interface.php +++ b/includes/interfaces/class-wc-customer-data-store-interface.php @@ -3,7 +3,7 @@ * Customer Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-customer-download-data-store-interface.php b/includes/interfaces/class-wc-customer-download-data-store-interface.php index 4f9cb235aeb..4ef79c59395 100644 --- a/includes/interfaces/class-wc-customer-download-data-store-interface.php +++ b/includes/interfaces/class-wc-customer-download-data-store-interface.php @@ -3,7 +3,7 @@ * Customer Download Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-customer-download-log-data-store-interface.php b/includes/interfaces/class-wc-customer-download-log-data-store-interface.php index 06d9e1d5cf4..32c5b168c4f 100644 --- a/includes/interfaces/class-wc-customer-download-log-data-store-interface.php +++ b/includes/interfaces/class-wc-customer-download-log-data-store-interface.php @@ -3,7 +3,7 @@ * Customer Download Log Data Store Interface * * @version 3.3.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-importer-interface.php b/includes/interfaces/class-wc-importer-interface.php index fc6e3f9de48..fa4317932b8 100644 --- a/includes/interfaces/class-wc-importer-interface.php +++ b/includes/interfaces/class-wc-importer-interface.php @@ -2,7 +2,7 @@ /** * WooCommerce Importer Interface * - * @package WooCommerce/Interface + * @package WooCommerce\Interface * @version 3.1.0 */ diff --git a/includes/interfaces/class-wc-log-handler-interface.php b/includes/interfaces/class-wc-log-handler-interface.php index c8b3dd8e455..d84e39720c8 100644 --- a/includes/interfaces/class-wc-log-handler-interface.php +++ b/includes/interfaces/class-wc-log-handler-interface.php @@ -3,7 +3,7 @@ * Log Handler Interface * * @version 3.3.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-logger-interface.php b/includes/interfaces/class-wc-logger-interface.php index 13194d19ccb..726b20cfe66 100644 --- a/includes/interfaces/class-wc-logger-interface.php +++ b/includes/interfaces/class-wc-logger-interface.php @@ -3,7 +3,7 @@ * Logger Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-object-data-store-interface.php b/includes/interfaces/class-wc-object-data-store-interface.php index 006873621ad..f6f276aaae6 100644 --- a/includes/interfaces/class-wc-object-data-store-interface.php +++ b/includes/interfaces/class-wc-object-data-store-interface.php @@ -3,7 +3,7 @@ * Object Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-order-data-store-interface.php b/includes/interfaces/class-wc-order-data-store-interface.php index 4727b9eb181..6f00c8a3efe 100644 --- a/includes/interfaces/class-wc-order-data-store-interface.php +++ b/includes/interfaces/class-wc-order-data-store-interface.php @@ -3,7 +3,7 @@ * Order Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-order-item-data-store-interface.php b/includes/interfaces/class-wc-order-item-data-store-interface.php index cbb13c27428..68ba29b4013 100644 --- a/includes/interfaces/class-wc-order-item-data-store-interface.php +++ b/includes/interfaces/class-wc-order-item-data-store-interface.php @@ -3,7 +3,7 @@ * Order Item Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-order-item-product-data-store-interface.php b/includes/interfaces/class-wc-order-item-product-data-store-interface.php index a6551ae0c1c..f5cd402ea2f 100644 --- a/includes/interfaces/class-wc-order-item-product-data-store-interface.php +++ b/includes/interfaces/class-wc-order-item-product-data-store-interface.php @@ -3,7 +3,7 @@ * Order Item Product Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-order-item-type-data-store-interface.php b/includes/interfaces/class-wc-order-item-type-data-store-interface.php index 548b4676fa7..006a4e6b0d4 100644 --- a/includes/interfaces/class-wc-order-item-type-data-store-interface.php +++ b/includes/interfaces/class-wc-order-item-type-data-store-interface.php @@ -3,7 +3,7 @@ * Order Item Type Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-order-refund-data-store-interface.php b/includes/interfaces/class-wc-order-refund-data-store-interface.php index 30961beef6c..b97864d06e3 100644 --- a/includes/interfaces/class-wc-order-refund-data-store-interface.php +++ b/includes/interfaces/class-wc-order-refund-data-store-interface.php @@ -3,7 +3,7 @@ * Order Refund Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-payment-token-data-store-interface.php b/includes/interfaces/class-wc-payment-token-data-store-interface.php index 3fdf0eacbef..fb2a581e741 100644 --- a/includes/interfaces/class-wc-payment-token-data-store-interface.php +++ b/includes/interfaces/class-wc-payment-token-data-store-interface.php @@ -3,7 +3,7 @@ * Payment Token Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-product-data-store-interface.php b/includes/interfaces/class-wc-product-data-store-interface.php index c4f92f5d597..3e50cfedf14 100644 --- a/includes/interfaces/class-wc-product-data-store-interface.php +++ b/includes/interfaces/class-wc-product-data-store-interface.php @@ -3,7 +3,7 @@ * Product Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-product-variable-data-store-interface.php b/includes/interfaces/class-wc-product-variable-data-store-interface.php index 3a62ac87a90..b22893dc3a6 100644 --- a/includes/interfaces/class-wc-product-variable-data-store-interface.php +++ b/includes/interfaces/class-wc-product-variable-data-store-interface.php @@ -3,7 +3,7 @@ * Product Variable Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-queue-interface.php b/includes/interfaces/class-wc-queue-interface.php index c341b6aff28..5a960d383f7 100644 --- a/includes/interfaces/class-wc-queue-interface.php +++ b/includes/interfaces/class-wc-queue-interface.php @@ -3,7 +3,7 @@ * Queue Interface * * @version 3.5.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-shipping-zone-data-store-interface.php b/includes/interfaces/class-wc-shipping-zone-data-store-interface.php index 830ca6cf5bd..7009c5b7209 100644 --- a/includes/interfaces/class-wc-shipping-zone-data-store-interface.php +++ b/includes/interfaces/class-wc-shipping-zone-data-store-interface.php @@ -3,7 +3,7 @@ * Shipping Zone Data Store Interface * * @version 3.0.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/interfaces/class-wc-webhooks-data-store-interface.php b/includes/interfaces/class-wc-webhooks-data-store-interface.php index 3d4839de9f0..f0e2e729843 100644 --- a/includes/interfaces/class-wc-webhooks-data-store-interface.php +++ b/includes/interfaces/class-wc-webhooks-data-store-interface.php @@ -3,7 +3,7 @@ * Webhook Data Store Interface * * @version 3.2.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/legacy/abstract-wc-legacy-order.php b/includes/legacy/abstract-wc-legacy-order.php index ea7729f5833..8867096c739 100644 --- a/includes/legacy/abstract-wc-legacy-order.php +++ b/includes/legacy/abstract-wc-legacy-order.php @@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) { * This class will be removed in future versions. * * @version 3.0.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts * @category Abstract Class * @author WooThemes */ diff --git a/includes/legacy/abstract-wc-legacy-payment-token.php b/includes/legacy/abstract-wc-legacy-payment-token.php index d1316d1b4cd..ed7201a3038 100644 --- a/includes/legacy/abstract-wc-legacy-payment-token.php +++ b/includes/legacy/abstract-wc-legacy-payment-token.php @@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) { * directly on the object. * * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @category Class * @author WooCommerce */ diff --git a/includes/legacy/abstract-wc-legacy-product.php b/includes/legacy/abstract-wc-legacy-product.php index 5e3464af08b..97f370e2ed1 100644 --- a/includes/legacy/abstract-wc-legacy-product.php +++ b/includes/legacy/abstract-wc-legacy-product.php @@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) { * This class will be removed in future versions. * * @version 3.0.0 - * @package WooCommerce/Abstracts + * @package WooCommerce\Abstracts * @category Abstract Class * @author WooThemes */ diff --git a/includes/legacy/api/class-wc-rest-legacy-coupons-controller.php b/includes/legacy/api/class-wc-rest-legacy-coupons-controller.php index 3378de41a40..19be8c3cb55 100644 --- a/includes/legacy/api/class-wc-rest-legacy-coupons-controller.php +++ b/includes/legacy/api/class-wc-rest-legacy-coupons-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Legacy Coupons controller class. * - * @package WooCommerce/API + * @package WooCommerce\API * @extends WC_REST_CRUD_Controller */ class WC_REST_Legacy_Coupons_Controller extends WC_REST_CRUD_Controller { diff --git a/includes/legacy/api/class-wc-rest-legacy-orders-controller.php b/includes/legacy/api/class-wc-rest-legacy-orders-controller.php index ccc9db267f3..180e0299241 100644 --- a/includes/legacy/api/class-wc-rest-legacy-orders-controller.php +++ b/includes/legacy/api/class-wc-rest-legacy-orders-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Legacy Orders controller class. * - * @package WooCommerce/API + * @package WooCommerce\API * @extends WC_REST_CRUD_Controller */ class WC_REST_Legacy_Orders_Controller extends WC_REST_CRUD_Controller { diff --git a/includes/legacy/api/class-wc-rest-legacy-products-controller.php b/includes/legacy/api/class-wc-rest-legacy-products-controller.php index 9096cbd0f98..b04ff689726 100644 --- a/includes/legacy/api/class-wc-rest-legacy-products-controller.php +++ b/includes/legacy/api/class-wc-rest-legacy-products-controller.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 3.0.0 */ @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Legacy Products controller class. * - * @package WooCommerce/API + * @package WooCommerce\API * @extends WC_REST_CRUD_Controller */ class WC_REST_Legacy_Products_Controller extends WC_REST_CRUD_Controller { diff --git a/includes/legacy/api/v1/class-wc-api-authentication.php b/includes/legacy/api/v1/class-wc-api-authentication.php index 1d26ae80ff6..a95abce7b8c 100644 --- a/includes/legacy/api/v1/class-wc-api-authentication.php +++ b/includes/legacy/api/v1/class-wc-api-authentication.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1.0 * @version 2.4.0 */ diff --git a/includes/legacy/api/v1/class-wc-api-coupons.php b/includes/legacy/api/v1/class-wc-api-coupons.php index 244b5efd3b0..3f1a2b0428b 100644 --- a/includes/legacy/api/v1/class-wc-api-coupons.php +++ b/includes/legacy/api/v1/class-wc-api-coupons.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v1/class-wc-api-customers.php b/includes/legacy/api/v1/class-wc-api-customers.php index d5edb1503a2..81752d8860d 100644 --- a/includes/legacy/api/v1/class-wc-api-customers.php +++ b/includes/legacy/api/v1/class-wc-api-customers.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v1/class-wc-api-json-handler.php b/includes/legacy/api/v1/class-wc-api-json-handler.php index 691bbb9663c..df01283228d 100644 --- a/includes/legacy/api/v1/class-wc-api-json-handler.php +++ b/includes/legacy/api/v1/class-wc-api-json-handler.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v1/class-wc-api-orders.php b/includes/legacy/api/v1/class-wc-api-orders.php index c4a391d5bdb..e2fee006afb 100644 --- a/includes/legacy/api/v1/class-wc-api-orders.php +++ b/includes/legacy/api/v1/class-wc-api-orders.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v1/class-wc-api-products.php b/includes/legacy/api/v1/class-wc-api-products.php index b608a3f326c..b81bc653cd1 100644 --- a/includes/legacy/api/v1/class-wc-api-products.php +++ b/includes/legacy/api/v1/class-wc-api-products.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 3.0 */ diff --git a/includes/legacy/api/v1/class-wc-api-reports.php b/includes/legacy/api/v1/class-wc-api-reports.php index 527ea64bf94..f8b95db0bd7 100644 --- a/includes/legacy/api/v1/class-wc-api-reports.php +++ b/includes/legacy/api/v1/class-wc-api-reports.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v1/class-wc-api-resource.php b/includes/legacy/api/v1/class-wc-api-resource.php index d419f8346e9..ae1bd956fd5 100644 --- a/includes/legacy/api/v1/class-wc-api-resource.php +++ b/includes/legacy/api/v1/class-wc-api-resource.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v1/class-wc-api-server.php b/includes/legacy/api/v1/class-wc-api-server.php index 182d482b51f..15ba35f05e5 100644 --- a/includes/legacy/api/v1/class-wc-api-server.php +++ b/includes/legacy/api/v1/class-wc-api-server.php @@ -9,7 +9,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v1/class-wc-api-xml-handler.php b/includes/legacy/api/v1/class-wc-api-xml-handler.php index 04f47e669e4..a9b5fc7d4ea 100644 --- a/includes/legacy/api/v1/class-wc-api-xml-handler.php +++ b/includes/legacy/api/v1/class-wc-api-xml-handler.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v1/interface-wc-api-handler.php b/includes/legacy/api/v1/interface-wc-api-handler.php index 464d9cb73cb..334c204f241 100644 --- a/includes/legacy/api/v1/interface-wc-api-handler.php +++ b/includes/legacy/api/v1/interface-wc-api-handler.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 2.1 */ diff --git a/includes/legacy/api/v2/class-wc-api-authentication.php b/includes/legacy/api/v2/class-wc-api-authentication.php index 2c75a75b605..31ee951667d 100644 --- a/includes/legacy/api/v2/class-wc-api-authentication.php +++ b/includes/legacy/api/v2/class-wc-api-authentication.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1.0 * @version 2.4.0 */ diff --git a/includes/legacy/api/v2/class-wc-api-coupons.php b/includes/legacy/api/v2/class-wc-api-coupons.php index ca57fb4670e..4a7b12ae0bf 100644 --- a/includes/legacy/api/v2/class-wc-api-coupons.php +++ b/includes/legacy/api/v2/class-wc-api-coupons.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v2/class-wc-api-customers.php b/includes/legacy/api/v2/class-wc-api-customers.php index 4912be3b34e..03b18dde8d2 100644 --- a/includes/legacy/api/v2/class-wc-api-customers.php +++ b/includes/legacy/api/v2/class-wc-api-customers.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.2 */ diff --git a/includes/legacy/api/v2/class-wc-api-exception.php b/includes/legacy/api/v2/class-wc-api-exception.php index 834ed04d6eb..986f56d5903 100644 --- a/includes/legacy/api/v2/class-wc-api-exception.php +++ b/includes/legacy/api/v2/class-wc-api-exception.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.2 */ diff --git a/includes/legacy/api/v2/class-wc-api-json-handler.php b/includes/legacy/api/v2/class-wc-api-json-handler.php index 672aa8850c2..b86f2e41820 100644 --- a/includes/legacy/api/v2/class-wc-api-json-handler.php +++ b/includes/legacy/api/v2/class-wc-api-json-handler.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v2/class-wc-api-orders.php b/includes/legacy/api/v2/class-wc-api-orders.php index 67fc745d364..a935a44541f 100644 --- a/includes/legacy/api/v2/class-wc-api-orders.php +++ b/includes/legacy/api/v2/class-wc-api-orders.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v2/class-wc-api-products.php b/includes/legacy/api/v2/class-wc-api-products.php index 0ceaf023a0c..d065f886572 100644 --- a/includes/legacy/api/v2/class-wc-api-products.php +++ b/includes/legacy/api/v2/class-wc-api-products.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 3.0 */ diff --git a/includes/legacy/api/v2/class-wc-api-reports.php b/includes/legacy/api/v2/class-wc-api-reports.php index 8387a2e7b9b..aae6d5f822c 100644 --- a/includes/legacy/api/v2/class-wc-api-reports.php +++ b/includes/legacy/api/v2/class-wc-api-reports.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v2/class-wc-api-resource.php b/includes/legacy/api/v2/class-wc-api-resource.php index cd2a9ecde6f..9475ad3a27b 100644 --- a/includes/legacy/api/v2/class-wc-api-resource.php +++ b/includes/legacy/api/v2/class-wc-api-resource.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v2/class-wc-api-server.php b/includes/legacy/api/v2/class-wc-api-server.php index 4df7e3bfcb3..eefa415b626 100644 --- a/includes/legacy/api/v2/class-wc-api-server.php +++ b/includes/legacy/api/v2/class-wc-api-server.php @@ -9,7 +9,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v2/class-wc-api-webhooks.php b/includes/legacy/api/v2/class-wc-api-webhooks.php index 83121936eaf..a8395e9ab82 100644 --- a/includes/legacy/api/v2/class-wc-api-webhooks.php +++ b/includes/legacy/api/v2/class-wc-api-webhooks.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.2 */ diff --git a/includes/legacy/api/v2/interface-wc-api-handler.php b/includes/legacy/api/v2/interface-wc-api-handler.php index 484f9f57f02..30fa3642b98 100644 --- a/includes/legacy/api/v2/interface-wc-api-handler.php +++ b/includes/legacy/api/v2/interface-wc-api-handler.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v3/class-wc-api-authentication.php b/includes/legacy/api/v3/class-wc-api-authentication.php index 88f0a711644..c57f74a9d11 100644 --- a/includes/legacy/api/v3/class-wc-api-authentication.php +++ b/includes/legacy/api/v3/class-wc-api-authentication.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1.0 * @version 2.4.0 */ diff --git a/includes/legacy/api/v3/class-wc-api-coupons.php b/includes/legacy/api/v3/class-wc-api-coupons.php index 43c71cb817c..49dbc0d4677 100644 --- a/includes/legacy/api/v3/class-wc-api-coupons.php +++ b/includes/legacy/api/v3/class-wc-api-coupons.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v3/class-wc-api-customers.php b/includes/legacy/api/v3/class-wc-api-customers.php index 8e6c5a13d0b..afb092726ad 100644 --- a/includes/legacy/api/v3/class-wc-api-customers.php +++ b/includes/legacy/api/v3/class-wc-api-customers.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.2 */ diff --git a/includes/legacy/api/v3/class-wc-api-exception.php b/includes/legacy/api/v3/class-wc-api-exception.php index 834ed04d6eb..986f56d5903 100644 --- a/includes/legacy/api/v3/class-wc-api-exception.php +++ b/includes/legacy/api/v3/class-wc-api-exception.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.2 */ diff --git a/includes/legacy/api/v3/class-wc-api-json-handler.php b/includes/legacy/api/v3/class-wc-api-json-handler.php index 672aa8850c2..b86f2e41820 100644 --- a/includes/legacy/api/v3/class-wc-api-json-handler.php +++ b/includes/legacy/api/v3/class-wc-api-json-handler.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v3/class-wc-api-orders.php b/includes/legacy/api/v3/class-wc-api-orders.php index aa2f69219f6..e2d682d461b 100644 --- a/includes/legacy/api/v3/class-wc-api-orders.php +++ b/includes/legacy/api/v3/class-wc-api-orders.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v3/class-wc-api-products.php b/includes/legacy/api/v3/class-wc-api-products.php index 35b7c206644..c9720ec9039 100644 --- a/includes/legacy/api/v3/class-wc-api-products.php +++ b/includes/legacy/api/v3/class-wc-api-products.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 * @version 3.0 */ diff --git a/includes/legacy/api/v3/class-wc-api-reports.php b/includes/legacy/api/v3/class-wc-api-reports.php index 552fd253fda..c4613a63916 100644 --- a/includes/legacy/api/v3/class-wc-api-reports.php +++ b/includes/legacy/api/v3/class-wc-api-reports.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v3/class-wc-api-resource.php b/includes/legacy/api/v3/class-wc-api-resource.php index 4aface69c0c..e87e9e9268d 100644 --- a/includes/legacy/api/v3/class-wc-api-resource.php +++ b/includes/legacy/api/v3/class-wc-api-resource.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v3/class-wc-api-server.php b/includes/legacy/api/v3/class-wc-api-server.php index 9c22f6ef6fa..fe218dcf6c8 100644 --- a/includes/legacy/api/v3/class-wc-api-server.php +++ b/includes/legacy/api/v3/class-wc-api-server.php @@ -9,7 +9,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/api/v3/class-wc-api-taxes.php b/includes/legacy/api/v3/class-wc-api-taxes.php index 0ff45885226..fef17b98bb3 100644 --- a/includes/legacy/api/v3/class-wc-api-taxes.php +++ b/includes/legacy/api/v3/class-wc-api-taxes.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.5.0 */ diff --git a/includes/legacy/api/v3/class-wc-api-webhooks.php b/includes/legacy/api/v3/class-wc-api-webhooks.php index 83121936eaf..a8395e9ab82 100644 --- a/includes/legacy/api/v3/class-wc-api-webhooks.php +++ b/includes/legacy/api/v3/class-wc-api-webhooks.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.2 */ diff --git a/includes/legacy/api/v3/interface-wc-api-handler.php b/includes/legacy/api/v3/interface-wc-api-handler.php index 484f9f57f02..30fa3642b98 100644 --- a/includes/legacy/api/v3/interface-wc-api-handler.php +++ b/includes/legacy/api/v3/interface-wc-api-handler.php @@ -6,7 +6,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.1 */ diff --git a/includes/legacy/class-wc-legacy-api.php b/includes/legacy/class-wc-legacy-api.php index 4bb14fa0b62..f121fff8c82 100644 --- a/includes/legacy/class-wc-legacy-api.php +++ b/includes/legacy/class-wc-legacy-api.php @@ -4,7 +4,7 @@ * * @author WooThemes * @category API - * @package WooCommerce/API + * @package WooCommerce\API * @since 2.6 */ diff --git a/includes/legacy/class-wc-legacy-cart.php b/includes/legacy/class-wc-legacy-cart.php index 4a5b14e0518..94a65443a38 100644 --- a/includes/legacy/class-wc-legacy-cart.php +++ b/includes/legacy/class-wc-legacy-cart.php @@ -6,7 +6,7 @@ * This class will be removed in future versions. * * @version 3.2.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @category Class * @author Automattic */ diff --git a/includes/legacy/class-wc-legacy-coupon.php b/includes/legacy/class-wc-legacy-coupon.php index cad0fc1fdb1..95b3be4a9b5 100644 --- a/includes/legacy/class-wc-legacy-coupon.php +++ b/includes/legacy/class-wc-legacy-coupon.php @@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WC_Legacy_Coupon * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @category Class * @author WooThemes */ diff --git a/includes/legacy/class-wc-legacy-customer.php b/includes/legacy/class-wc-legacy-customer.php index 5ad3d952afe..37ed5922ad9 100644 --- a/includes/legacy/class-wc-legacy-customer.php +++ b/includes/legacy/class-wc-legacy-customer.php @@ -7,7 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) { * Legacy Customer. * * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @category Class * @author WooThemes */ diff --git a/includes/legacy/class-wc-legacy-shipping-zone.php b/includes/legacy/class-wc-legacy-shipping-zone.php index aa06337a36c..3c1c3a0d754 100644 --- a/includes/legacy/class-wc-legacy-shipping-zone.php +++ b/includes/legacy/class-wc-legacy-shipping-zone.php @@ -7,7 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) { * Legacy Shipping Zone. * * @version 3.0.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @category Class * @author WooThemes */ diff --git a/includes/legacy/class-wc-legacy-webhook.php b/includes/legacy/class-wc-legacy-webhook.php index e18000eedff..d1e703477b1 100644 --- a/includes/legacy/class-wc-legacy-webhook.php +++ b/includes/legacy/class-wc-legacy-webhook.php @@ -6,7 +6,7 @@ * This class will be removed in future versions. * * @version 3.2.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes * @category Class * @author Automattic */ diff --git a/includes/log-handlers/class-wc-log-handler-db.php b/includes/log-handlers/class-wc-log-handler-db.php index 77b4f929642..ef961334e23 100644 --- a/includes/log-handlers/class-wc-log-handler-db.php +++ b/includes/log-handlers/class-wc-log-handler-db.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WC_Log_Handler_DB * @version 1.0.0 - * @package WooCommerce/Classes/Log_Handlers + * @package WooCommerce\Classes\Log_Handlers */ class WC_Log_Handler_DB extends WC_Log_Handler { diff --git a/includes/log-handlers/class-wc-log-handler-email.php b/includes/log-handlers/class-wc-log-handler-email.php index 6e23005dbaa..d3d6a683c43 100644 --- a/includes/log-handlers/class-wc-log-handler-email.php +++ b/includes/log-handlers/class-wc-log-handler-email.php @@ -28,7 +28,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WC_Log_Handler_Email * @version 1.0.0 - * @package WooCommerce/Classes/Log_Handlers + * @package WooCommerce\Classes\Log_Handlers */ class WC_Log_Handler_Email extends WC_Log_Handler { diff --git a/includes/log-handlers/class-wc-log-handler-file.php b/includes/log-handlers/class-wc-log-handler-file.php index 136603d44d5..0fc59a36a2d 100644 --- a/includes/log-handlers/class-wc-log-handler-file.php +++ b/includes/log-handlers/class-wc-log-handler-file.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WC_Log_Handler_File * @version 1.0.0 - * @package WooCommerce/Classes/Log_Handlers + * @package WooCommerce\Classes\Log_Handlers */ class WC_Log_Handler_File extends WC_Log_Handler { diff --git a/includes/payment-tokens/class-wc-payment-token-cc.php b/includes/payment-tokens/class-wc-payment-token-cc.php index 32abf6c4e38..f658389846a 100644 --- a/includes/payment-tokens/class-wc-payment-token-cc.php +++ b/includes/payment-tokens/class-wc-payment-token-cc.php @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WC_Payment_Token_CC * @version 3.0.0 * @since 2.6.0 - * @package WooCommerce/PaymentTokens + * @package WooCommerce\PaymentTokens */ class WC_Payment_Token_CC extends WC_Payment_Token { diff --git a/includes/payment-tokens/class-wc-payment-token-echeck.php b/includes/payment-tokens/class-wc-payment-token-echeck.php index edb3b0ecf31..4e1e21e7f7a 100644 --- a/includes/payment-tokens/class-wc-payment-token-echeck.php +++ b/includes/payment-tokens/class-wc-payment-token-echeck.php @@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WC_Payment_Token_ECheck * @version 3.0.0 * @since 2.6.0 - * @package WooCommerce/PaymentTokens + * @package WooCommerce\PaymentTokens */ class WC_Payment_Token_ECheck extends WC_Payment_Token { diff --git a/includes/queue/class-wc-action-queue.php b/includes/queue/class-wc-action-queue.php index f0e3445f42e..702861f54d3 100644 --- a/includes/queue/class-wc-action-queue.php +++ b/includes/queue/class-wc-action-queue.php @@ -3,7 +3,7 @@ * Action Queue * * @version 3.5.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/queue/class-wc-queue.php b/includes/queue/class-wc-queue.php index e17bbb6b9f7..80dd4b67a95 100644 --- a/includes/queue/class-wc-queue.php +++ b/includes/queue/class-wc-queue.php @@ -3,7 +3,7 @@ * WC Queue * * @version 3.5.0 - * @package WooCommerce/Interface + * @package WooCommerce\Interface */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/includes/shipping/flat-rate/class-wc-shipping-flat-rate.php b/includes/shipping/flat-rate/class-wc-shipping-flat-rate.php index c31f946d323..7e1a647afb3 100644 --- a/includes/shipping/flat-rate/class-wc-shipping-flat-rate.php +++ b/includes/shipping/flat-rate/class-wc-shipping-flat-rate.php @@ -3,7 +3,7 @@ * Flat Rate Shipping Method. * * @version 2.6.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ defined( 'ABSPATH' ) || exit; diff --git a/includes/shipping/flat-rate/includes/settings-flat-rate.php b/includes/shipping/flat-rate/includes/settings-flat-rate.php index 803c961aa76..b4609d6b89b 100644 --- a/includes/shipping/flat-rate/includes/settings-flat-rate.php +++ b/includes/shipping/flat-rate/includes/settings-flat-rate.php @@ -2,7 +2,7 @@ /** * Settings for flat rate shipping. * - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ defined( 'ABSPATH' ) || exit; diff --git a/includes/shipping/free-shipping/class-wc-shipping-free-shipping.php b/includes/shipping/free-shipping/class-wc-shipping-free-shipping.php index 18cbc76315c..9f45ef6cb80 100644 --- a/includes/shipping/free-shipping/class-wc-shipping-free-shipping.php +++ b/includes/shipping/free-shipping/class-wc-shipping-free-shipping.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WC_Shipping_Free_Shipping * @version 2.6.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ class WC_Shipping_Free_Shipping extends WC_Shipping_Method { diff --git a/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php b/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php index c5d78a8c227..a0d47dcb8e1 100644 --- a/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php +++ b/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @deprecated 2.6.0 * @version 2.4.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ class WC_Shipping_Legacy_Flat_Rate extends WC_Shipping_Method { diff --git a/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php b/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php index 55c4ebde1fc..e8f3b054dd2 100644 --- a/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php +++ b/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @deprecated 2.6.0 * @version 2.4.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ class WC_Shipping_Legacy_Free_Shipping extends WC_Shipping_Method { diff --git a/includes/shipping/legacy-international-delivery/class-wc-shipping-legacy-international-delivery.php b/includes/shipping/legacy-international-delivery/class-wc-shipping-legacy-international-delivery.php index 4bbc884ba8e..6ddc038c6d5 100644 --- a/includes/shipping/legacy-international-delivery/class-wc-shipping-legacy-international-delivery.php +++ b/includes/shipping/legacy-international-delivery/class-wc-shipping-legacy-international-delivery.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @deprecated 2.6.0 * @version 2.4.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ class WC_Shipping_Legacy_International_Delivery extends WC_Shipping_Legacy_Flat_Rate { diff --git a/includes/shipping/legacy-local-delivery/class-wc-shipping-legacy-local-delivery.php b/includes/shipping/legacy-local-delivery/class-wc-shipping-legacy-local-delivery.php index a0d435e6b2e..4484b79ce6e 100644 --- a/includes/shipping/legacy-local-delivery/class-wc-shipping-legacy-local-delivery.php +++ b/includes/shipping/legacy-local-delivery/class-wc-shipping-legacy-local-delivery.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @deprecated 2.6.0 * @version 2.3.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ class WC_Shipping_Legacy_Local_Delivery extends WC_Shipping_Local_Pickup { diff --git a/includes/shipping/legacy-local-pickup/class-wc-shipping-legacy-local-pickup.php b/includes/shipping/legacy-local-pickup/class-wc-shipping-legacy-local-pickup.php index 6730eb44786..dc0608e442e 100644 --- a/includes/shipping/legacy-local-pickup/class-wc-shipping-legacy-local-pickup.php +++ b/includes/shipping/legacy-local-pickup/class-wc-shipping-legacy-local-pickup.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @deprecated 2.6.0 * @version 2.3.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ class WC_Shipping_Legacy_Local_Pickup extends WC_Shipping_Method { diff --git a/includes/shipping/local-pickup/class-wc-shipping-local-pickup.php b/includes/shipping/local-pickup/class-wc-shipping-local-pickup.php index 1724dc6a877..a64c69951d0 100644 --- a/includes/shipping/local-pickup/class-wc-shipping-local-pickup.php +++ b/includes/shipping/local-pickup/class-wc-shipping-local-pickup.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WC_Shipping_Local_Pickup * @version 2.6.0 - * @package WooCommerce/Classes/Shipping + * @package WooCommerce\Classes\Shipping */ class WC_Shipping_Local_Pickup extends WC_Shipping_Method { diff --git a/includes/shortcodes/class-wc-shortcode-cart.php b/includes/shortcodes/class-wc-shortcode-cart.php index 060a2ad3687..3784fb79b5d 100644 --- a/includes/shortcodes/class-wc-shortcode-cart.php +++ b/includes/shortcodes/class-wc-shortcode-cart.php @@ -4,7 +4,7 @@ * * Used on the cart page, the cart shortcode displays the cart contents and interface for coupon codes and other cart bits and pieces. * - * @package WooCommerce/Shortcodes/Cart + * @package WooCommerce\Shortcodes\Cart * @version 2.3.0 */ diff --git a/includes/shortcodes/class-wc-shortcode-checkout.php b/includes/shortcodes/class-wc-shortcode-checkout.php index 31413213a72..4f6450e63d6 100644 --- a/includes/shortcodes/class-wc-shortcode-checkout.php +++ b/includes/shortcodes/class-wc-shortcode-checkout.php @@ -4,7 +4,7 @@ * * Used on the checkout page, the checkout shortcode displays the checkout process. * - * @package WooCommerce/Shortcodes/Checkout + * @package WooCommerce\Shortcodes\Checkout * @version 2.0.0 */ diff --git a/includes/shortcodes/class-wc-shortcode-my-account.php b/includes/shortcodes/class-wc-shortcode-my-account.php index e3906c5371c..c01aaa36356 100644 --- a/includes/shortcodes/class-wc-shortcode-my-account.php +++ b/includes/shortcodes/class-wc-shortcode-my-account.php @@ -4,7 +4,7 @@ * * Shows the 'my account' section where the customer can view past orders and update their information. * - * @package WooCommerce/Shortcodes/My_Account + * @package WooCommerce\Shortcodes\My_Account * @version 2.0.0 */ diff --git a/includes/shortcodes/class-wc-shortcode-order-tracking.php b/includes/shortcodes/class-wc-shortcode-order-tracking.php index f9736c08ced..6798539ae82 100644 --- a/includes/shortcodes/class-wc-shortcode-order-tracking.php +++ b/includes/shortcodes/class-wc-shortcode-order-tracking.php @@ -4,7 +4,7 @@ * * Lets a user see the status of an order by entering their order details. * - * @package WooCommerce/Shortcodes/Order_Tracking + * @package WooCommerce\Shortcodes\Order_Tracking * @version 3.0.0 */ diff --git a/includes/shortcodes/class-wc-shortcode-products.php b/includes/shortcodes/class-wc-shortcode-products.php index b195676a607..9410efa65af 100644 --- a/includes/shortcodes/class-wc-shortcode-products.php +++ b/includes/shortcodes/class-wc-shortcode-products.php @@ -2,7 +2,7 @@ /** * Products shortcode * - * @package WooCommerce/Shortcodes + * @package WooCommerce\Shortcodes * @version 3.2.4 */ diff --git a/includes/theme-support/class-wc-twenty-eleven.php b/includes/theme-support/class-wc-twenty-eleven.php index a0b8391ef9b..fb06a7a84dc 100644 --- a/includes/theme-support/class-wc-twenty-eleven.php +++ b/includes/theme-support/class-wc-twenty-eleven.php @@ -3,7 +3,7 @@ * Twenty Eleven support. * * @since 3.3.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/theme-support/class-wc-twenty-fifteen.php b/includes/theme-support/class-wc-twenty-fifteen.php index ece231ea996..83e1930cf93 100644 --- a/includes/theme-support/class-wc-twenty-fifteen.php +++ b/includes/theme-support/class-wc-twenty-fifteen.php @@ -4,7 +4,7 @@ * * @class WC_Twenty_Fifteen * @since 3.3.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/theme-support/class-wc-twenty-fourteen.php b/includes/theme-support/class-wc-twenty-fourteen.php index 1cef95456f8..ce04395299d 100644 --- a/includes/theme-support/class-wc-twenty-fourteen.php +++ b/includes/theme-support/class-wc-twenty-fourteen.php @@ -4,7 +4,7 @@ * * @class WC_Twenty_Fourteen * @since 3.3.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/theme-support/class-wc-twenty-nineteen.php b/includes/theme-support/class-wc-twenty-nineteen.php index a0bcf9f443e..47c1aff660c 100644 --- a/includes/theme-support/class-wc-twenty-nineteen.php +++ b/includes/theme-support/class-wc-twenty-nineteen.php @@ -3,7 +3,7 @@ * Twenty Nineteen support. * * @since 3.5.X - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/theme-support/class-wc-twenty-seventeen.php b/includes/theme-support/class-wc-twenty-seventeen.php index cca349a2175..2093d2200e7 100644 --- a/includes/theme-support/class-wc-twenty-seventeen.php +++ b/includes/theme-support/class-wc-twenty-seventeen.php @@ -3,7 +3,7 @@ * Twenty Seventeen support. * * @since 2.6.9 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/theme-support/class-wc-twenty-sixteen.php b/includes/theme-support/class-wc-twenty-sixteen.php index 831d65e97fe..c9681fa5e98 100644 --- a/includes/theme-support/class-wc-twenty-sixteen.php +++ b/includes/theme-support/class-wc-twenty-sixteen.php @@ -3,7 +3,7 @@ * Twenty Sixteen support. * * @since 3.3.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/theme-support/class-wc-twenty-ten.php b/includes/theme-support/class-wc-twenty-ten.php index feac6e8036e..8a9262e6191 100644 --- a/includes/theme-support/class-wc-twenty-ten.php +++ b/includes/theme-support/class-wc-twenty-ten.php @@ -3,7 +3,7 @@ * Twenty Ten support. * * @since 3.3.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/theme-support/class-wc-twenty-thirteen.php b/includes/theme-support/class-wc-twenty-thirteen.php index de4912f8c80..4e80b3e27c6 100644 --- a/includes/theme-support/class-wc-twenty-thirteen.php +++ b/includes/theme-support/class-wc-twenty-thirteen.php @@ -4,7 +4,7 @@ * * @class WC_Twenty_Thirteen * @since 3.3.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/theme-support/class-wc-twenty-twelve.php b/includes/theme-support/class-wc-twenty-twelve.php index 4eec7997c98..116dabea432 100644 --- a/includes/theme-support/class-wc-twenty-twelve.php +++ b/includes/theme-support/class-wc-twenty-twelve.php @@ -4,7 +4,7 @@ * * @class WC_Twenty_Twelve * @since 3.3.0 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ defined( 'ABSPATH' ) || exit; diff --git a/includes/theme-support/class-wc-twenty-twenty.php b/includes/theme-support/class-wc-twenty-twenty.php index 35bf512b205..47296f639ab 100644 --- a/includes/theme-support/class-wc-twenty-twenty.php +++ b/includes/theme-support/class-wc-twenty-twenty.php @@ -3,7 +3,7 @@ * Twenty Twenty support. * * @since 3.8.1 - * @package WooCommerce/Classes + * @package WooCommerce\Classes */ use Automattic\Jetpack\Constants; diff --git a/includes/traits/trait-wc-item-totals.php b/includes/traits/trait-wc-item-totals.php index 39e358807f5..d64d3215b7f 100644 --- a/includes/traits/trait-wc-item-totals.php +++ b/includes/traits/trait-wc-item-totals.php @@ -2,7 +2,7 @@ /** * This ongoing trait will have shared calculation logic between WC_Abstract_Order and WC_Cart_Totals classes. * - * @package WooCommerce/Traits + * @package WooCommerce\Traits * @version 3.9.0 */ diff --git a/includes/walkers/class-product-cat-dropdown-walker.php b/includes/walkers/class-product-cat-dropdown-walker.php index 90ff3c7cf60..fb4163fe934 100644 --- a/includes/walkers/class-product-cat-dropdown-walker.php +++ b/includes/walkers/class-product-cat-dropdown-walker.php @@ -2,7 +2,7 @@ /** * Legacy WC_Product_Cat_Dropdown_Walker file * - * @package WooCommerce/Classes/Walkers + * @package WooCommerce\Classes\Walkers * @deprecated 3.4.0 */ diff --git a/includes/walkers/class-product-cat-list-walker.php b/includes/walkers/class-product-cat-list-walker.php index 63a172e9341..9eca89ac0ac 100644 --- a/includes/walkers/class-product-cat-list-walker.php +++ b/includes/walkers/class-product-cat-list-walker.php @@ -2,7 +2,7 @@ /** * Legacy WC_Product_Cat_List_Walker file * - * @package WooCommerce/Classes/Walkers + * @package WooCommerce\Classes\Walkers * @deprecated 3.4.0 */ diff --git a/includes/walkers/class-wc-product-cat-dropdown-walker.php b/includes/walkers/class-wc-product-cat-dropdown-walker.php index 34250efcfb1..4b64298bf54 100644 --- a/includes/walkers/class-wc-product-cat-dropdown-walker.php +++ b/includes/walkers/class-wc-product-cat-dropdown-walker.php @@ -2,7 +2,7 @@ /** * WC_Product_Cat_Dropdown_Walker class * - * @package WooCommerce/Classes/Walkers + * @package WooCommerce\Classes\Walkers * @version 3.4.0 */ diff --git a/includes/walkers/class-wc-product-cat-list-walker.php b/includes/walkers/class-wc-product-cat-list-walker.php index 28b1785f163..cdd1fbba5d8 100644 --- a/includes/walkers/class-wc-product-cat-list-walker.php +++ b/includes/walkers/class-wc-product-cat-list-walker.php @@ -2,7 +2,7 @@ /** * WC_Product_Cat_List_Walker class * - * @package WooCommerce/Classes/Walkers + * @package WooCommerce\Classes\Walkers * @version 3.4.0 */ diff --git a/includes/wc-account-functions.php b/includes/wc-account-functions.php index 840990d1d43..2d67cad27b4 100644 --- a/includes/wc-account-functions.php +++ b/includes/wc-account-functions.php @@ -4,7 +4,7 @@ * * Functions for account specific things. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.6.0 */ diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index 658cb2284a3..535a719f1b8 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -2,7 +2,7 @@ /** * WooCommerce Attribute Functions * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.1.0 */ diff --git a/includes/wc-cart-functions.php b/includes/wc-cart-functions.php index b9f05304c04..e5ee3067ec9 100644 --- a/includes/wc-cart-functions.php +++ b/includes/wc-cart-functions.php @@ -4,7 +4,7 @@ * * Functions for cart specific things. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.5.0 */ diff --git a/includes/wc-conditional-functions.php b/includes/wc-conditional-functions.php index 53bc24b4f30..641066cb657 100644 --- a/includes/wc-conditional-functions.php +++ b/includes/wc-conditional-functions.php @@ -4,7 +4,7 @@ * * Functions for determining the current query/page. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.3.0 */ diff --git a/includes/wc-coupon-functions.php b/includes/wc-coupon-functions.php index 13fd7c0f9e3..c3f96c2700c 100644 --- a/includes/wc-coupon-functions.php +++ b/includes/wc-coupon-functions.php @@ -4,7 +4,7 @@ * * Functions for coupon specific things. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 3.0.0 */ diff --git a/includes/wc-formatting-functions.php b/includes/wc-formatting-functions.php index fc1064a2ebf..e92b78651d7 100644 --- a/includes/wc-formatting-functions.php +++ b/includes/wc-formatting-functions.php @@ -4,7 +4,7 @@ * * Functions for formatting data. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.1.0 */ diff --git a/includes/wc-notice-functions.php b/includes/wc-notice-functions.php index 1d417955d48..d1f05e0593b 100644 --- a/includes/wc-notice-functions.php +++ b/includes/wc-notice-functions.php @@ -4,7 +4,7 @@ * * Functions for error/message handling and display. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.1.0 */ diff --git a/includes/wc-order-functions.php b/includes/wc-order-functions.php index cb0d87db52d..5c8a76e05d9 100644 --- a/includes/wc-order-functions.php +++ b/includes/wc-order-functions.php @@ -4,7 +4,7 @@ * * Functions for order specific things. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 3.4.0 */ diff --git a/includes/wc-order-item-functions.php b/includes/wc-order-item-functions.php index 825a22ac454..5f7c6a1f942 100644 --- a/includes/wc-order-item-functions.php +++ b/includes/wc-order-item-functions.php @@ -4,7 +4,7 @@ * * Functions for order specific things. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 3.4.0 */ diff --git a/includes/wc-product-functions.php b/includes/wc-product-functions.php index e7ee0359e46..7edeef07136 100644 --- a/includes/wc-product-functions.php +++ b/includes/wc-product-functions.php @@ -4,7 +4,7 @@ * * Functions for product specific things. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 3.0.0 */ diff --git a/includes/wc-rest-functions.php b/includes/wc-rest-functions.php index 065b079ed3f..54029b4074e 100644 --- a/includes/wc-rest-functions.php +++ b/includes/wc-rest-functions.php @@ -4,7 +4,7 @@ * * Functions for REST specific things. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.6.0 */ diff --git a/includes/wc-stock-functions.php b/includes/wc-stock-functions.php index c92e474d1a1..e65d33f20fb 100644 --- a/includes/wc-stock-functions.php +++ b/includes/wc-stock-functions.php @@ -4,7 +4,7 @@ * * Functions used to manage product stock levels. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 3.4.0 */ diff --git a/includes/wc-template-hooks.php b/includes/wc-template-hooks.php index f45ea6a2d49..cc0b5189f24 100644 --- a/includes/wc-template-hooks.php +++ b/includes/wc-template-hooks.php @@ -4,7 +4,7 @@ * * Action/filter hooks used for WooCommerce functions/templates. * - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.1.0 */ diff --git a/includes/wc-term-functions.php b/includes/wc-term-functions.php index 9d5032d8f5f..f40a89fb6b8 100644 --- a/includes/wc-term-functions.php +++ b/includes/wc-term-functions.php @@ -4,7 +4,7 @@ * * Functions for handling terms/term meta. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.1.0 */ diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 076aa177b14..e51567a8058 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -4,7 +4,7 @@ * * Functions for updating data, used by the background updater. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 3.3.0 */ diff --git a/includes/wc-user-functions.php b/includes/wc-user-functions.php index 5d49e84ae37..282582cf624 100644 --- a/includes/wc-user-functions.php +++ b/includes/wc-user-functions.php @@ -4,7 +4,7 @@ * * Functions for customers. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.2.0 */ diff --git a/includes/wc-webhook-functions.php b/includes/wc-webhook-functions.php index b5205c6607b..bc1d15998eb 100644 --- a/includes/wc-webhook-functions.php +++ b/includes/wc-webhook-functions.php @@ -2,7 +2,7 @@ /** * WooCommerce Webhook functions * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 3.3.0 */ diff --git a/includes/wc-widget-functions.php b/includes/wc-widget-functions.php index 2972680371f..49da8f74a93 100644 --- a/includes/wc-widget-functions.php +++ b/includes/wc-widget-functions.php @@ -4,7 +4,7 @@ * * Widget related functions and widget registration. * - * @package WooCommerce/Functions + * @package WooCommerce\Functions * @version 2.3.0 */ diff --git a/includes/wccom-site/rest-api/endpoints/class-wc-rest-wccom-site-installer-controller.php b/includes/wccom-site/rest-api/endpoints/class-wc-rest-wccom-site-installer-controller.php index d4f5dda0b0b..60135f89686 100644 --- a/includes/wccom-site/rest-api/endpoints/class-wc-rest-wccom-site-installer-controller.php +++ b/includes/wccom-site/rest-api/endpoints/class-wc-rest-wccom-site-installer-controller.php @@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit; /** * REST API WCCOM Site Installer Controller Class. * - * @package WooCommerce/WCCOM_Site/REST_API + * @package WooCommerce\WCCOM_Site\REST_API * @extends WC_REST_Controller */ class WC_REST_WCCOM_Site_Installer_Controller extends WC_REST_Controller { diff --git a/includes/widgets/class-wc-widget-cart.php b/includes/widgets/class-wc-widget-cart.php index 0f4cb8a2a31..cc76280b5a7 100644 --- a/includes/widgets/class-wc-widget-cart.php +++ b/includes/widgets/class-wc-widget-cart.php @@ -4,7 +4,7 @@ * * Displays shopping cart widget. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 2.3.0 */ diff --git a/includes/widgets/class-wc-widget-layered-nav-filters.php b/includes/widgets/class-wc-widget-layered-nav-filters.php index 68ebfd4a320..a333081c097 100644 --- a/includes/widgets/class-wc-widget-layered-nav-filters.php +++ b/includes/widgets/class-wc-widget-layered-nav-filters.php @@ -2,7 +2,7 @@ /** * Layered Navigation Filters Widget. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 2.3.0 */ diff --git a/includes/widgets/class-wc-widget-layered-nav.php b/includes/widgets/class-wc-widget-layered-nav.php index ea8e65c6265..8a8dbbab11e 100644 --- a/includes/widgets/class-wc-widget-layered-nav.php +++ b/includes/widgets/class-wc-widget-layered-nav.php @@ -2,7 +2,7 @@ /** * Layered nav widget * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 2.6.0 */ diff --git a/includes/widgets/class-wc-widget-price-filter.php b/includes/widgets/class-wc-widget-price-filter.php index a27bbf1b048..cd8c5907ce8 100644 --- a/includes/widgets/class-wc-widget-price-filter.php +++ b/includes/widgets/class-wc-widget-price-filter.php @@ -4,7 +4,7 @@ * * Generates a range slider to filter products by price. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 2.3.0 */ diff --git a/includes/widgets/class-wc-widget-product-categories.php b/includes/widgets/class-wc-widget-product-categories.php index 5025968523c..26b590bcdf7 100644 --- a/includes/widgets/class-wc-widget-product-categories.php +++ b/includes/widgets/class-wc-widget-product-categories.php @@ -2,7 +2,7 @@ /** * Product Categories Widget * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 2.3.0 */ diff --git a/includes/widgets/class-wc-widget-product-search.php b/includes/widgets/class-wc-widget-product-search.php index 2df11926494..c27debbeb83 100644 --- a/includes/widgets/class-wc-widget-product-search.php +++ b/includes/widgets/class-wc-widget-product-search.php @@ -2,7 +2,7 @@ /** * Product Search Widget. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 2.3.0 */ diff --git a/includes/widgets/class-wc-widget-product-tag-cloud.php b/includes/widgets/class-wc-widget-product-tag-cloud.php index c6f04988374..4d85bc0e45d 100644 --- a/includes/widgets/class-wc-widget-product-tag-cloud.php +++ b/includes/widgets/class-wc-widget-product-tag-cloud.php @@ -2,7 +2,7 @@ /** * Tag Cloud Widget. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 3.4.0 */ diff --git a/includes/widgets/class-wc-widget-products.php b/includes/widgets/class-wc-widget-products.php index d9242f299ac..be373488920 100644 --- a/includes/widgets/class-wc-widget-products.php +++ b/includes/widgets/class-wc-widget-products.php @@ -2,7 +2,7 @@ /** * List products. One widget to rule them all. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 3.3.0 */ diff --git a/includes/widgets/class-wc-widget-rating-filter.php b/includes/widgets/class-wc-widget-rating-filter.php index 9570f90deb5..669038860b1 100644 --- a/includes/widgets/class-wc-widget-rating-filter.php +++ b/includes/widgets/class-wc-widget-rating-filter.php @@ -2,7 +2,7 @@ /** * Rating Filter Widget and related functions. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 2.6.0 */ diff --git a/includes/widgets/class-wc-widget-recent-reviews.php b/includes/widgets/class-wc-widget-recent-reviews.php index da2934400d1..635e26975b6 100644 --- a/includes/widgets/class-wc-widget-recent-reviews.php +++ b/includes/widgets/class-wc-widget-recent-reviews.php @@ -2,7 +2,7 @@ /** * Recent Reviews Widget. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 2.3.0 */ diff --git a/includes/widgets/class-wc-widget-recently-viewed.php b/includes/widgets/class-wc-widget-recently-viewed.php index b721110f3be..e023927f6aa 100644 --- a/includes/widgets/class-wc-widget-recently-viewed.php +++ b/includes/widgets/class-wc-widget-recently-viewed.php @@ -2,7 +2,7 @@ /** * Recent Products Widget. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 3.3.0 */ diff --git a/includes/widgets/class-wc-widget-top-rated-products.php b/includes/widgets/class-wc-widget-top-rated-products.php index 8af6b332dad..a5241ece94c 100644 --- a/includes/widgets/class-wc-widget-top-rated-products.php +++ b/includes/widgets/class-wc-widget-top-rated-products.php @@ -3,7 +3,7 @@ * Top Rated Products Widget. * Gets and displays top rated products in an unordered list. * - * @package WooCommerce/Widgets + * @package WooCommerce\Widgets * @version 3.3.0 */ diff --git a/templates/archive-product.php b/templates/archive-product.php index e4f3938b3e4..998cd5c12e6 100644 --- a/templates/archive-product.php +++ b/templates/archive-product.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/auth/footer.php b/templates/auth/footer.php index 85c4726a951..69a5252c823 100644 --- a/templates/auth/footer.php +++ b/templates/auth/footer.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Auth + * @package WooCommerce\Templates\Auth * @version 2.4.0 */ diff --git a/templates/auth/form-grant-access.php b/templates/auth/form-grant-access.php index f77fb2e2fe9..0b67e7ac8ee 100644 --- a/templates/auth/form-grant-access.php +++ b/templates/auth/form-grant-access.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Auth + * @package WooCommerce\Templates\Auth * @version 4.3.0 */ diff --git a/templates/auth/form-login.php b/templates/auth/form-login.php index 8aa5330044a..3606ca0a7a3 100644 --- a/templates/auth/form-login.php +++ b/templates/auth/form-login.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Auth + * @package WooCommerce\Templates\Auth * @version 3.4.0 */ diff --git a/templates/auth/header.php b/templates/auth/header.php index 913eed0f4f4..e05ccc939b8 100644 --- a/templates/auth/header.php +++ b/templates/auth/header.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Auth + * @package WooCommerce\Templates\Auth * @version 2.4.0 */ diff --git a/templates/cart/cart-empty.php b/templates/cart/cart-empty.php index 739c8a8c6d2..b4069165629 100644 --- a/templates/cart/cart-empty.php +++ b/templates/cart/cart-empty.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.0 */ diff --git a/templates/cart/cart-item-data.php b/templates/cart/cart-item-data.php index 2f2ab6f0601..d93000910a9 100644 --- a/templates/cart/cart-item-data.php +++ b/templates/cart/cart-item-data.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.4.0 */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/templates/cart/cart-shipping.php b/templates/cart/cart-shipping.php index 1bad8799f88..134b05b3496 100644 --- a/templates/cart/cart-shipping.php +++ b/templates/cart/cart-shipping.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/cart/cart-totals.php b/templates/cart/cart-totals.php index e9602e0314d..f5af332ca9b 100644 --- a/templates/cart/cart-totals.php +++ b/templates/cart/cart-totals.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.3.6 */ diff --git a/templates/cart/cross-sells.php b/templates/cart/cross-sells.php index 1312c5242df..2f9a4781cf9 100644 --- a/templates/cart/cross-sells.php +++ b/templates/cart/cross-sells.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 4.4.0 */ diff --git a/templates/cart/mini-cart.php b/templates/cart/mini-cart.php index 3d3be6423d3..57c73ff56d9 100644 --- a/templates/cart/mini-cart.php +++ b/templates/cart/mini-cart.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.7.0 */ diff --git a/templates/cart/proceed-to-checkout-button.php b/templates/cart/proceed-to-checkout-button.php index ea17318117f..d678926e88c 100644 --- a/templates/cart/proceed-to-checkout-button.php +++ b/templates/cart/proceed-to-checkout-button.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.4.0 */ diff --git a/templates/cart/shipping-calculator.php b/templates/cart/shipping-calculator.php index 441ab92e0ad..3cd4402b442 100644 --- a/templates/cart/shipping-calculator.php +++ b/templates/cart/shipping-calculator.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 4.0.0 */ diff --git a/templates/checkout/cart-errors.php b/templates/checkout/cart-errors.php index c16f09fe08f..85a280e8a38 100644 --- a/templates/checkout/cart-errors.php +++ b/templates/checkout/cart-errors.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.0 */ diff --git a/templates/checkout/form-billing.php b/templates/checkout/form-billing.php index 731b3187c3a..9889929e2e4 100644 --- a/templates/checkout/form-billing.php +++ b/templates/checkout/form-billing.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 * @global WC_Checkout $checkout */ diff --git a/templates/checkout/form-checkout.php b/templates/checkout/form-checkout.php index db9f9d35b0a..00d5459985d 100644 --- a/templates/checkout/form-checkout.php +++ b/templates/checkout/form-checkout.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.0 */ diff --git a/templates/checkout/form-coupon.php b/templates/checkout/form-coupon.php index 3bfc0f1fb36..bca033618fa 100644 --- a/templates/checkout/form-coupon.php +++ b/templates/checkout/form-coupon.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.4 */ diff --git a/templates/checkout/form-login.php b/templates/checkout/form-login.php index b838a59f90c..c9da081bd8b 100644 --- a/templates/checkout/form-login.php +++ b/templates/checkout/form-login.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.8.0 */ diff --git a/templates/checkout/form-pay.php b/templates/checkout/form-pay.php index 98bb85d6996..b9244b6e210 100644 --- a/templates/checkout/form-pay.php +++ b/templates/checkout/form-pay.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/checkout/form-shipping.php b/templates/checkout/form-shipping.php index 3e2c164f07d..f395ba25368 100644 --- a/templates/checkout/form-shipping.php +++ b/templates/checkout/form-shipping.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 * @global WC_Checkout $checkout */ diff --git a/templates/checkout/order-receipt.php b/templates/checkout/order-receipt.php index fae638a9ff4..bd8ca6f39fb 100644 --- a/templates/checkout/order-receipt.php +++ b/templates/checkout/order-receipt.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.2.0 */ diff --git a/templates/checkout/payment-method.php b/templates/checkout/payment-method.php index 0e8a654508a..a3d4dbd1384 100644 --- a/templates/checkout/payment-method.php +++ b/templates/checkout/payment-method.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.0 */ diff --git a/templates/checkout/payment.php b/templates/checkout/payment.php index 7262fc55ffa..a5467a71c72 100644 --- a/templates/checkout/payment.php +++ b/templates/checkout/payment.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.3 */ diff --git a/templates/checkout/review-order.php b/templates/checkout/review-order.php index 3fb3639f806..e85d43dc39c 100644 --- a/templates/checkout/review-order.php +++ b/templates/checkout/review-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.8.0 */ diff --git a/templates/checkout/terms.php b/templates/checkout/terms.php index cca6c52b08f..21ade908400 100644 --- a/templates/checkout/terms.php +++ b/templates/checkout/terms.php @@ -2,7 +2,7 @@ /** * Checkout terms and conditions area. * - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/checkout/thankyou.php b/templates/checkout/thankyou.php index ad89003f2d2..35f457bc67f 100644 --- a/templates/checkout/thankyou.php +++ b/templates/checkout/thankyou.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.7.0 */ diff --git a/templates/content-product.php b/templates/content-product.php index 3d5f0d5347a..6058ebbebbd 100644 --- a/templates/content-product.php +++ b/templates/content-product.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/content-product_cat.php b/templates/content-product_cat.php index 1eeea197c48..1a67fcddd9f 100644 --- a/templates/content-product_cat.php +++ b/templates/content-product_cat.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.6.1 */ diff --git a/templates/content-single-product.php b/templates/content-single-product.php index edcd3d19741..37a2c063661 100644 --- a/templates/content-single-product.php +++ b/templates/content-single-product.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/content-widget-price-filter.php b/templates/content-widget-price-filter.php index d7bb4148c18..a491d343fc1 100644 --- a/templates/content-widget-price-filter.php +++ b/templates/content-widget-price-filter.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.7.1 */ diff --git a/templates/content-widget-product.php b/templates/content-widget-product.php index 9d8a47e6348..a64ff1e10aa 100644 --- a/templates/content-widget-product.php +++ b/templates/content-widget-product.php @@ -10,7 +10,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.5 */ diff --git a/templates/content-widget-reviews.php b/templates/content-widget-reviews.php index cd29c237acb..d46cbd5873f 100644 --- a/templates/content-widget-reviews.php +++ b/templates/content-widget-reviews.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/emails/admin-cancelled-order.php b/templates/emails/admin-cancelled-order.php index d83dc28b765..af117403f0d 100644 --- a/templates/emails/admin-cancelled-order.php +++ b/templates/emails/admin-cancelled-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 4.1.0 */ diff --git a/templates/emails/admin-failed-order.php b/templates/emails/admin-failed-order.php index 528492b6d6e..7fa1da5c203 100644 --- a/templates/emails/admin-failed-order.php +++ b/templates/emails/admin-failed-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/admin-new-order.php b/templates/emails/admin-new-order.php index cefa3439f66..8f20c7d1276 100644 --- a/templates/emails/admin-new-order.php +++ b/templates/emails/admin-new-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/HTML + * @package WooCommerce\Templates\Emails\HTML * @version 3.7.0 */ diff --git a/templates/emails/customer-completed-order.php b/templates/emails/customer-completed-order.php index fe83f0e11a8..75de74a045f 100644 --- a/templates/emails/customer-completed-order.php +++ b/templates/emails/customer-completed-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/customer-invoice.php b/templates/emails/customer-invoice.php index 1fd444d14e4..e0564448390 100644 --- a/templates/emails/customer-invoice.php +++ b/templates/emails/customer-invoice.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/customer-new-account.php b/templates/emails/customer-new-account.php index e0c18310076..3154c7cdde2 100644 --- a/templates/emails/customer-new-account.php +++ b/templates/emails/customer-new-account.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/customer-note.php b/templates/emails/customer-note.php index 696e081c26f..8b5734f05ca 100644 --- a/templates/emails/customer-note.php +++ b/templates/emails/customer-note.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/customer-on-hold-order.php b/templates/emails/customer-on-hold-order.php index 36ca694a174..d19bf8d199e 100644 --- a/templates/emails/customer-on-hold-order.php +++ b/templates/emails/customer-on-hold-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/customer-processing-order.php b/templates/emails/customer-processing-order.php index 798763aa024..8227ce9a50d 100644 --- a/templates/emails/customer-processing-order.php +++ b/templates/emails/customer-processing-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/customer-refunded-order.php b/templates/emails/customer-refunded-order.php index d2bdbe981e9..fbd5e351f4b 100644 --- a/templates/emails/customer-refunded-order.php +++ b/templates/emails/customer-refunded-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/customer-reset-password.php b/templates/emails/customer-reset-password.php index 7166442b12e..1b418087261 100644 --- a/templates/emails/customer-reset-password.php +++ b/templates/emails/customer-reset-password.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 4.0.0 */ diff --git a/templates/emails/email-addresses.php b/templates/emails/email-addresses.php index d36a023cce2..8e9d7032432 100644 --- a/templates/emails/email-addresses.php +++ b/templates/emails/email-addresses.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.9.0 */ diff --git a/templates/emails/email-customer-details.php b/templates/emails/email-customer-details.php index ee09fd2aa60..70c42c2ec3d 100644 --- a/templates/emails/email-customer-details.php +++ b/templates/emails/email-customer-details.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 2.5.0 */ diff --git a/templates/emails/email-downloads.php b/templates/emails/email-downloads.php index a5fcff7f353..6fce4728ab7 100644 --- a/templates/emails/email-downloads.php +++ b/templates/emails/email-downloads.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/emails/email-footer.php b/templates/emails/email-footer.php index 0330de1dd31..4579924cd85 100644 --- a/templates/emails/email-footer.php +++ b/templates/emails/email-footer.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/email-header.php b/templates/emails/email-header.php index da949e827da..23793c022ab 100644 --- a/templates/emails/email-header.php +++ b/templates/emails/email-header.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 4.0.0 */ diff --git a/templates/emails/email-order-details.php b/templates/emails/email-order-details.php index b591fc0f006..2184d691e3e 100644 --- a/templates/emails/email-order-details.php +++ b/templates/emails/email-order-details.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/email-order-items.php b/templates/emails/email-order-items.php index 33fc1132a42..74bc9c119e8 100644 --- a/templates/emails/email-order-items.php +++ b/templates/emails/email-order-items.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/email-styles.php b/templates/emails/email-styles.php index 081a8ece64e..df8dd4e8a10 100644 --- a/templates/emails/email-styles.php +++ b/templates/emails/email-styles.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 4.0.0 */ diff --git a/templates/emails/plain/admin-cancelled-order.php b/templates/emails/plain/admin-cancelled-order.php index 30117f7dc3a..271ab6dda83 100644 --- a/templates/emails/plain/admin-cancelled-order.php +++ b/templates/emails/plain/admin-cancelled-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 4.1.0 */ diff --git a/templates/emails/plain/admin-failed-order.php b/templates/emails/plain/admin-failed-order.php index 9c0cd2441b1..90148e6eca6 100644 --- a/templates/emails/plain/admin-failed-order.php +++ b/templates/emails/plain/admin-failed-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/admin-new-order.php b/templates/emails/plain/admin-new-order.php index 82efa4259a3..97931f666af 100644 --- a/templates/emails/plain/admin-new-order.php +++ b/templates/emails/plain/admin-new-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/customer-completed-order.php b/templates/emails/plain/customer-completed-order.php index 129556b4940..56f007125f2 100644 --- a/templates/emails/plain/customer-completed-order.php +++ b/templates/emails/plain/customer-completed-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/customer-invoice.php b/templates/emails/plain/customer-invoice.php index 32a6bdb9c78..a70e6108e4e 100644 --- a/templates/emails/plain/customer-invoice.php +++ b/templates/emails/plain/customer-invoice.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/customer-new-account.php b/templates/emails/plain/customer-new-account.php index 4dcb04e3820..56204d24bdb 100644 --- a/templates/emails/plain/customer-new-account.php +++ b/templates/emails/plain/customer-new-account.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/customer-note.php b/templates/emails/plain/customer-note.php index 4f593ba75db..85f0f4a0f3d 100644 --- a/templates/emails/plain/customer-note.php +++ b/templates/emails/plain/customer-note.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/customer-on-hold-order.php b/templates/emails/plain/customer-on-hold-order.php index 3a5ba46b744..b5dec0ad882 100644 --- a/templates/emails/plain/customer-on-hold-order.php +++ b/templates/emails/plain/customer-on-hold-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/customer-processing-order.php b/templates/emails/plain/customer-processing-order.php index 57c8860c2a6..fead3d79224 100644 --- a/templates/emails/plain/customer-processing-order.php +++ b/templates/emails/plain/customer-processing-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/customer-refunded-order.php b/templates/emails/plain/customer-refunded-order.php index 1aa31a53bb8..a6626d37165 100644 --- a/templates/emails/plain/customer-refunded-order.php +++ b/templates/emails/plain/customer-refunded-order.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/customer-reset-password.php b/templates/emails/plain/customer-reset-password.php index 12f5a6bade8..efc4e5b8c26 100644 --- a/templates/emails/plain/customer-reset-password.php +++ b/templates/emails/plain/customer-reset-password.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/emails/plain/email-addresses.php b/templates/emails/plain/email-addresses.php index 2f14522c99d..92ec35eec07 100644 --- a/templates/emails/plain/email-addresses.php +++ b/templates/emails/plain/email-addresses.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.4.0 */ diff --git a/templates/emails/plain/email-customer-details.php b/templates/emails/plain/email-customer-details.php index f5b0ebf91f0..e86c24a2fdb 100644 --- a/templates/emails/plain/email-customer-details.php +++ b/templates/emails/plain/email-customer-details.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.4.0 */ diff --git a/templates/emails/plain/email-downloads.php b/templates/emails/plain/email-downloads.php index 95e3bd19fd1..12855128873 100644 --- a/templates/emails/plain/email-downloads.php +++ b/templates/emails/plain/email-downloads.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/emails/plain/email-order-details.php b/templates/emails/plain/email-order-details.php index c9e371fdc49..3a292aa412f 100644 --- a/templates/emails/plain/email-order-details.php +++ b/templates/emails/plain/email-order-details.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails + * @package WooCommerce\Templates\Emails * @version 3.7.0 */ diff --git a/templates/emails/plain/email-order-items.php b/templates/emails/plain/email-order-items.php index 92a30c27fec..bcd446630e9 100644 --- a/templates/emails/plain/email-order-items.php +++ b/templates/emails/plain/email-order-items.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates/Emails/Plain + * @package WooCommerce\Templates\Emails\Plain * @version 3.7.0 */ diff --git a/templates/global/breadcrumb.php b/templates/global/breadcrumb.php index 4da8469c826..3d6bc21aa5a 100644 --- a/templates/global/breadcrumb.php +++ b/templates/global/breadcrumb.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.3.0 * @see woocommerce_breadcrumb() */ diff --git a/templates/global/form-login.php b/templates/global/form-login.php index 74fcd651065..1c64a4439b2 100644 --- a/templates/global/form-login.php +++ b/templates/global/form-login.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/global/quantity-input.php b/templates/global/quantity-input.php index f2994813d92..172fc858e6c 100644 --- a/templates/global/quantity-input.php +++ b/templates/global/quantity-input.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 4.0.0 */ diff --git a/templates/global/sidebar.php b/templates/global/sidebar.php index 98622e715f3..ed499b4b442 100644 --- a/templates/global/sidebar.php +++ b/templates/global/sidebar.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 1.6.4 */ diff --git a/templates/global/wrapper-end.php b/templates/global/wrapper-end.php index 9f5c4ad7300..3072175de77 100644 --- a/templates/global/wrapper-end.php +++ b/templates/global/wrapper-end.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.3.0 */ diff --git a/templates/global/wrapper-start.php b/templates/global/wrapper-start.php index 2bf8e7dd52e..aceb891a35d 100644 --- a/templates/global/wrapper-start.php +++ b/templates/global/wrapper-start.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.3.0 */ diff --git a/templates/loop/add-to-cart.php b/templates/loop/add-to-cart.php index b2637d41b2d..9e4dda075e1 100644 --- a/templates/loop/add-to-cart.php +++ b/templates/loop/add-to-cart.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.3.0 */ diff --git a/templates/loop/loop-end.php b/templates/loop/loop-end.php index 5d92f1252f1..802acb977b5 100644 --- a/templates/loop/loop-end.php +++ b/templates/loop/loop-end.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.0.0 */ diff --git a/templates/loop/loop-start.php b/templates/loop/loop-start.php index 0fa6c789159..b2d4960114b 100644 --- a/templates/loop/loop-start.php +++ b/templates/loop/loop-start.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.3.0 */ diff --git a/templates/loop/no-products-found.php b/templates/loop/no-products-found.php index b4db1b0ffa7..906edb35b15 100644 --- a/templates/loop/no-products-found.php +++ b/templates/loop/no-products-found.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.0.0 */ diff --git a/templates/loop/orderby.php b/templates/loop/orderby.php index 8b660ac99e7..5b2c1f80f6f 100644 --- a/templates/loop/orderby.php +++ b/templates/loop/orderby.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/loop/pagination.php b/templates/loop/pagination.php index cfa3763dce0..9d61f8799cf 100644 --- a/templates/loop/pagination.php +++ b/templates/loop/pagination.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.3.1 */ diff --git a/templates/loop/price.php b/templates/loop/price.php index 31ec3d42899..951ca1794e7 100644 --- a/templates/loop/price.php +++ b/templates/loop/price.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 1.6.4 */ diff --git a/templates/loop/rating.php b/templates/loop/rating.php index 560d72e4dcf..9b29acac5f0 100644 --- a/templates/loop/rating.php +++ b/templates/loop/rating.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/loop/result-count.php b/templates/loop/result-count.php index 1f1798261a3..faec64365a4 100644 --- a/templates/loop/result-count.php +++ b/templates/loop/result-count.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.7.0 */ diff --git a/templates/loop/sale-flash.php b/templates/loop/sale-flash.php index cf537316257..2b35f769064 100644 --- a/templates/loop/sale-flash.php +++ b/templates/loop/sale-flash.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 1.6.4 */ diff --git a/templates/myaccount/dashboard.php b/templates/myaccount/dashboard.php index d1a413e50ce..9f79a916cd8 100644 --- a/templates/myaccount/dashboard.php +++ b/templates/myaccount/dashboard.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 4.4.0 */ diff --git a/templates/myaccount/downloads.php b/templates/myaccount/downloads.php index b06139e050b..630b7fc6d26 100644 --- a/templates/myaccount/downloads.php +++ b/templates/myaccount/downloads.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.2.0 */ diff --git a/templates/myaccount/form-add-payment-method.php b/templates/myaccount/form-add-payment-method.php index ec84ba4a718..71b859aa4db 100644 --- a/templates/myaccount/form-add-payment-method.php +++ b/templates/myaccount/form-add-payment-method.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 4.3.0 */ diff --git a/templates/myaccount/form-edit-account.php b/templates/myaccount/form-edit-account.php index 27d932a32a7..eb5dfd180b5 100644 --- a/templates/myaccount/form-edit-account.php +++ b/templates/myaccount/form-edit-account.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.0 */ diff --git a/templates/myaccount/form-edit-address.php b/templates/myaccount/form-edit-address.php index 408fd86e0fb..6916bef15c7 100644 --- a/templates/myaccount/form-edit-address.php +++ b/templates/myaccount/form-edit-address.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/myaccount/form-login.php b/templates/myaccount/form-login.php index 9ffa25aeb63..66801791c4b 100644 --- a/templates/myaccount/form-login.php +++ b/templates/myaccount/form-login.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 4.1.0 */ diff --git a/templates/myaccount/form-lost-password.php b/templates/myaccount/form-lost-password.php index f537282fb1d..15fc984a745 100644 --- a/templates/myaccount/form-lost-password.php +++ b/templates/myaccount/form-lost-password.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.2 */ diff --git a/templates/myaccount/form-reset-password.php b/templates/myaccount/form-reset-password.php index b97991e4038..3106f6022da 100644 --- a/templates/myaccount/form-reset-password.php +++ b/templates/myaccount/form-reset-password.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.5 */ diff --git a/templates/myaccount/lost-password-confirmation.php b/templates/myaccount/lost-password-confirmation.php index f2376f64c6f..14665a8c9f3 100644 --- a/templates/myaccount/lost-password-confirmation.php +++ b/templates/myaccount/lost-password-confirmation.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.9.0 */ diff --git a/templates/myaccount/my-account.php b/templates/myaccount/my-account.php index d724d7adc10..9a4f85f875e 100644 --- a/templates/myaccount/my-account.php +++ b/templates/myaccount/my-account.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.0 */ diff --git a/templates/myaccount/my-address.php b/templates/myaccount/my-address.php index 97f560a3eb0..5cd3161a3ac 100644 --- a/templates/myaccount/my-address.php +++ b/templates/myaccount/my-address.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.6.0 */ diff --git a/templates/myaccount/my-downloads.php b/templates/myaccount/my-downloads.php index 85046fc133b..8c3544e561a 100644 --- a/templates/myaccount/my-downloads.php +++ b/templates/myaccount/my-downloads.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.0.0 * @deprecated 2.6.0 */ diff --git a/templates/myaccount/my-orders.php b/templates/myaccount/my-orders.php index 0b671f01325..77761e0486c 100644 --- a/templates/myaccount/my-orders.php +++ b/templates/myaccount/my-orders.php @@ -3,7 +3,7 @@ * My Orders - Deprecated * * @deprecated 2.6.0 this template file is no longer used. My Account shortcode uses orders.php. - * @package WooCommerce/Templates + * @package WooCommerce\Templates */ defined( 'ABSPATH' ) || exit; diff --git a/templates/myaccount/navigation.php b/templates/myaccount/navigation.php index cca86825258..8fc0db02388 100644 --- a/templates/myaccount/navigation.php +++ b/templates/myaccount/navigation.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.6.0 */ diff --git a/templates/myaccount/orders.php b/templates/myaccount/orders.php index b9059b9cfc6..b36005b2101 100644 --- a/templates/myaccount/orders.php +++ b/templates/myaccount/orders.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.7.0 */ diff --git a/templates/myaccount/payment-methods.php b/templates/myaccount/payment-methods.php index a016cf2445c..8c6ad65b296 100644 --- a/templates/myaccount/payment-methods.php +++ b/templates/myaccount/payment-methods.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.6.0 */ diff --git a/templates/myaccount/view-order.php b/templates/myaccount/view-order.php index a75dec89a15..2691e3dfc67 100644 --- a/templates/myaccount/view-order.php +++ b/templates/myaccount/view-order.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.0.0 */ diff --git a/templates/notices/error.php b/templates/notices/error.php index 8bbeeb7adf3..fe4af627643 100644 --- a/templates/notices/error.php +++ b/templates/notices/error.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.9.0 */ diff --git a/templates/notices/notice.php b/templates/notices/notice.php index b300f8d10a9..4e611df074d 100644 --- a/templates/notices/notice.php +++ b/templates/notices/notice.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.9.0 */ diff --git a/templates/notices/success.php b/templates/notices/success.php index 17b5fc19af5..e8643e57b83 100644 --- a/templates/notices/success.php +++ b/templates/notices/success.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.9.0 */ diff --git a/templates/order/form-tracking.php b/templates/order/form-tracking.php index be4eb2d9cc2..d26f1a062a9 100644 --- a/templates/order/form-tracking.php +++ b/templates/order/form-tracking.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/order/order-again.php b/templates/order/order-again.php index 9c5ab84c0d5..f7bc2242cdd 100644 --- a/templates/order/order-again.php +++ b/templates/order/order-again.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.0 */ diff --git a/templates/order/order-details-customer.php b/templates/order/order-details-customer.php index 4dc37ac7850..62db6400719 100644 --- a/templates/order/order-details-customer.php +++ b/templates/order/order-details-customer.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.4 */ diff --git a/templates/order/order-details-item.php b/templates/order/order-details-item.php index 68fb1883adb..7894d37b92f 100644 --- a/templates/order/order-details-item.php +++ b/templates/order/order-details-item.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.7.0 */ diff --git a/templates/order/order-details.php b/templates/order/order-details.php index 17f82e1bc27..a63bb53df0b 100644 --- a/templates/order/order-details.php +++ b/templates/order/order-details.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.7.0 */ diff --git a/templates/order/order-downloads.php b/templates/order/order-downloads.php index 1a7c28469ec..9566cd34162 100644 --- a/templates/order/order-downloads.php +++ b/templates/order/order-downloads.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.3.0 */ diff --git a/templates/order/tracking.php b/templates/order/tracking.php index c1bc9a75dd1..7e9d55422f1 100644 --- a/templates/order/tracking.php +++ b/templates/order/tracking.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.2.0 */ diff --git a/templates/product-searchform.php b/templates/product-searchform.php index 92e515b9fd5..c6c92bd5fbd 100644 --- a/templates/product-searchform.php +++ b/templates/product-searchform.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.3.0 */ diff --git a/templates/single-product-reviews.php b/templates/single-product-reviews.php index 8ed5a42b970..995a11ea348 100644 --- a/templates/single-product-reviews.php +++ b/templates/single-product-reviews.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 4.3.0 */ diff --git a/templates/single-product.php b/templates/single-product.php index 66598ae6a26..39eeb1df18e 100644 --- a/templates/single-product.php +++ b/templates/single-product.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 1.6.4 */ diff --git a/templates/single-product/add-to-cart/external.php b/templates/single-product/add-to-cart/external.php index 8a9e3e0d6ca..92039e72f9b 100644 --- a/templates/single-product/add-to-cart/external.php +++ b/templates/single-product/add-to-cart/external.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/single-product/add-to-cart/grouped.php b/templates/single-product/add-to-cart/grouped.php index 5193f93b34b..98c6561f946 100644 --- a/templates/single-product/add-to-cart/grouped.php +++ b/templates/single-product/add-to-cart/grouped.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 4.0.0 */ diff --git a/templates/single-product/add-to-cart/simple.php b/templates/single-product/add-to-cart/simple.php index 5fcae249d91..494ece1c465 100644 --- a/templates/single-product/add-to-cart/simple.php +++ b/templates/single-product/add-to-cart/simple.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/single-product/add-to-cart/variable.php b/templates/single-product/add-to-cart/variable.php index e11fd49c8e7..4d1424845b4 100644 --- a/templates/single-product/add-to-cart/variable.php +++ b/templates/single-product/add-to-cart/variable.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.5 */ diff --git a/templates/single-product/add-to-cart/variation-add-to-cart-button.php b/templates/single-product/add-to-cart/variation-add-to-cart-button.php index 00972daf381..03b7aeb02a9 100644 --- a/templates/single-product/add-to-cart/variation-add-to-cart-button.php +++ b/templates/single-product/add-to-cart/variation-add-to-cart-button.php @@ -3,7 +3,7 @@ * Single variation cart button * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/single-product/add-to-cart/variation.php b/templates/single-product/add-to-cart/variation.php index 18475a59e0a..af3dde3d5f9 100644 --- a/templates/single-product/add-to-cart/variation.php +++ b/templates/single-product/add-to-cart/variation.php @@ -6,7 +6,7 @@ * The values will be dynamically replaced after selecting attributes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.5.0 */ diff --git a/templates/single-product/meta.php b/templates/single-product/meta.php index 9a76e18786f..68a7e0f78d2 100644 --- a/templates/single-product/meta.php +++ b/templates/single-product/meta.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.0.0 */ diff --git a/templates/single-product/photoswipe.php b/templates/single-product/photoswipe.php index 7d91793ef16..761b0b167ea 100644 --- a/templates/single-product/photoswipe.php +++ b/templates/single-product/photoswipe.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.0.0 */ diff --git a/templates/single-product/price.php b/templates/single-product/price.php index 4dd920dad28..38e6d4d2ce3 100644 --- a/templates/single-product/price.php +++ b/templates/single-product/price.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.0.0 */ diff --git a/templates/single-product/product-attributes.php b/templates/single-product/product-attributes.php index cc0f236ba06..86faf529eeb 100644 --- a/templates/single-product/product-attributes.php +++ b/templates/single-product/product-attributes.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/single-product/product-image.php b/templates/single-product/product-image.php index e6a028c5ce1..0399028c8d8 100644 --- a/templates/single-product/product-image.php +++ b/templates/single-product/product-image.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.1 */ diff --git a/templates/single-product/product-thumbnails.php b/templates/single-product/product-thumbnails.php index 6702e1a02b9..cec3f34fd25 100644 --- a/templates/single-product/product-thumbnails.php +++ b/templates/single-product/product-thumbnails.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.1 */ diff --git a/templates/single-product/rating.php b/templates/single-product/rating.php index 14d2ff81aea..a758f8bd920 100644 --- a/templates/single-product/rating.php +++ b/templates/single-product/rating.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/single-product/related.php b/templates/single-product/related.php index a9b4210be57..a7d3a3edbf7 100644 --- a/templates/single-product/related.php +++ b/templates/single-product/related.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.9.0 */ diff --git a/templates/single-product/review-meta.php b/templates/single-product/review-meta.php index 46dd3f161c1..f4fb2391e7c 100644 --- a/templates/single-product/review-meta.php +++ b/templates/single-product/review-meta.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.4.0 */ diff --git a/templates/single-product/review-rating.php b/templates/single-product/review-rating.php index 532ef95f5d6..eabe57a5ee9 100644 --- a/templates/single-product/review-rating.php +++ b/templates/single-product/review-rating.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.6.0 */ diff --git a/templates/single-product/review.php b/templates/single-product/review.php index f566e22d224..cc22770cadc 100644 --- a/templates/single-product/review.php +++ b/templates/single-product/review.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.6.0 */ diff --git a/templates/single-product/sale-flash.php b/templates/single-product/sale-flash.php index e5e289e0ade..d3ce9654173 100644 --- a/templates/single-product/sale-flash.php +++ b/templates/single-product/sale-flash.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 1.6.4 */ diff --git a/templates/single-product/share.php b/templates/single-product/share.php index 760ea81eda7..eafae09cae9 100644 --- a/templates/single-product/share.php +++ b/templates/single-product/share.php @@ -13,7 +13,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.5.0 */ diff --git a/templates/single-product/short-description.php b/templates/single-product/short-description.php index 0bb12b743af..b2997718225 100644 --- a/templates/single-product/short-description.php +++ b/templates/single-product/short-description.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.3.0 */ diff --git a/templates/single-product/stock.php b/templates/single-product/stock.php index ce877480b4e..d8b147733d4 100644 --- a/templates/single-product/stock.php +++ b/templates/single-product/stock.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.0.0 */ diff --git a/templates/single-product/tabs/additional-information.php b/templates/single-product/tabs/additional-information.php index e50d827726e..f857b0c1f98 100644 --- a/templates/single-product/tabs/additional-information.php +++ b/templates/single-product/tabs/additional-information.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.0.0 */ diff --git a/templates/single-product/tabs/description.php b/templates/single-product/tabs/description.php index 6b67db84266..e7018a7b523 100644 --- a/templates/single-product/tabs/description.php +++ b/templates/single-product/tabs/description.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 2.0.0 */ diff --git a/templates/single-product/tabs/tabs.php b/templates/single-product/tabs/tabs.php index 83c00e1f1ba..819943c8ab1 100644 --- a/templates/single-product/tabs/tabs.php +++ b/templates/single-product/tabs/tabs.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.8.0 */ diff --git a/templates/single-product/up-sells.php b/templates/single-product/up-sells.php index 1da908c9ab2..36e5ed475cb 100644 --- a/templates/single-product/up-sells.php +++ b/templates/single-product/up-sells.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 3.0.0 */ diff --git a/templates/taxonomy-product_cat.php b/templates/taxonomy-product_cat.php index 2bcc6af3ac6..9294065a625 100644 --- a/templates/taxonomy-product_cat.php +++ b/templates/taxonomy-product_cat.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 1.6.4 */ diff --git a/templates/taxonomy-product_tag.php b/templates/taxonomy-product_tag.php index ef1497dc3c8..2f83cd21471 100644 --- a/templates/taxonomy-product_tag.php +++ b/templates/taxonomy-product_tag.php @@ -11,7 +11,7 @@ * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce/Templates + * @package WooCommerce\Templates * @version 1.6.4 */ diff --git a/tests/Tools/CodeHacking/CodeHacker.php b/tests/Tools/CodeHacking/CodeHacker.php index 86b88959f37..8d31c09cd1c 100644 --- a/tests/Tools/CodeHacking/CodeHacker.php +++ b/tests/Tools/CodeHacking/CodeHacker.php @@ -2,7 +2,7 @@ /** * CodeHacker class file. * - * @package WooCommerce/Testing + * @package WooCommerce\Testing */ //phpcs:disable WordPress.WP.AlternativeFunctions, WordPress.PHP.NoSilencedErrors.Discouraged diff --git a/tests/Tools/CodeHacking/CodeHackerTestHook.php b/tests/Tools/CodeHacking/CodeHackerTestHook.php index 18b0c9aafb6..b0399e0241a 100644 --- a/tests/Tools/CodeHacking/CodeHackerTestHook.php +++ b/tests/Tools/CodeHacking/CodeHackerTestHook.php @@ -2,7 +2,7 @@ /** * CodeHackerTestHook class file. * - * @package WooCommerce/Testing + * @package WooCommerce\Testing */ namespace Automattic\WooCommerce\Testing\Tools\CodeHacking; diff --git a/tests/Tools/CodeHacking/Hacks/BypassFinalsHack.php b/tests/Tools/CodeHacking/Hacks/BypassFinalsHack.php index 0d5f0b4e2fb..f63f927e1d6 100644 --- a/tests/Tools/CodeHacking/Hacks/BypassFinalsHack.php +++ b/tests/Tools/CodeHacking/Hacks/BypassFinalsHack.php @@ -2,7 +2,7 @@ /** * BypassFinalsHack class file. * - * @package WooCommerce/Testing + * @package WooCommerce\Testing */ namespace Automattic\WooCommerce\Testing\Tools\CodeHacking\Hacks; diff --git a/tests/Tools/CodeHacking/Hacks/CodeHack.php b/tests/Tools/CodeHacking/Hacks/CodeHack.php index 5f79b652558..94464e7496d 100644 --- a/tests/Tools/CodeHacking/Hacks/CodeHack.php +++ b/tests/Tools/CodeHacking/Hacks/CodeHack.php @@ -2,7 +2,7 @@ /** * CodeHack class file. * - * @package WooCommerce/Testing + * @package WooCommerce\Testing */ namespace Automattic\WooCommerce\Testing\Tools\CodeHacking\Hacks; diff --git a/tests/Tools/CodeHacking/Hacks/FunctionsMockerHack.php b/tests/Tools/CodeHacking/Hacks/FunctionsMockerHack.php index 5d1d1cbb9c4..67ecabb59e0 100644 --- a/tests/Tools/CodeHacking/Hacks/FunctionsMockerHack.php +++ b/tests/Tools/CodeHacking/Hacks/FunctionsMockerHack.php @@ -2,7 +2,7 @@ /** * FunctionsMockerHack class file. * - * @package WooCommerce/Testing + * @package WooCommerce\Testing */ namespace Automattic\WooCommerce\Testing\Tools\CodeHacking\Hacks; diff --git a/tests/Tools/CodeHacking/Hacks/StaticMockerHack.php b/tests/Tools/CodeHacking/Hacks/StaticMockerHack.php index 9d1709c3b1f..11a335f235e 100644 --- a/tests/Tools/CodeHacking/Hacks/StaticMockerHack.php +++ b/tests/Tools/CodeHacking/Hacks/StaticMockerHack.php @@ -2,7 +2,7 @@ /** * StaticMockerHack class file. * - * @package WooCommerce/Testing + * @package WooCommerce\Testing */ namespace Automattic\WooCommerce\Testing\Tools\CodeHacking\Hacks; diff --git a/tests/legacy/framework/helpers/class-wc-helper-order.php b/tests/legacy/framework/helpers/class-wc-helper-order.php index fff89757e6f..457a37d011f 100644 --- a/tests/legacy/framework/helpers/class-wc-helper-order.php +++ b/tests/legacy/framework/helpers/class-wc-helper-order.php @@ -2,7 +2,7 @@ /** * Order helpers. * - * @package WooCommerce/Tests + * @package WooCommerce\Tests */ /** diff --git a/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php b/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php index ce3fba4c728..faf58e431ed 100644 --- a/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php +++ b/tests/legacy/unit-tests/order/class-wc-tests-order-functions.php @@ -2,7 +2,7 @@ /** * Class WC_Tests_Order_Functions file. * - * @package WooCommerce/Tests + * @package WooCommerce\Tests */ use Automattic\Jetpack\Constants; diff --git a/tests/legacy/unit-tests/payment-gateways/cod.php b/tests/legacy/unit-tests/payment-gateways/cod.php index 8766df0d37b..8dea53d70e5 100644 --- a/tests/legacy/unit-tests/payment-gateways/cod.php +++ b/tests/legacy/unit-tests/payment-gateways/cod.php @@ -2,7 +2,7 @@ /** * Contains tests for the COD Payment Gateway. * - * @package WooCommerce/Tests/PaymentGateways + * @package WooCommerce\Tests\PaymentGateways */ use Automattic\Jetpack\Constants; diff --git a/tests/legacy/unit-tests/payment-gateways/payment-gateways.php b/tests/legacy/unit-tests/payment-gateways/payment-gateways.php index 7f839c0badd..3428db4971d 100644 --- a/tests/legacy/unit-tests/payment-gateways/payment-gateways.php +++ b/tests/legacy/unit-tests/payment-gateways/payment-gateways.php @@ -1,6 +1,6 @@ Date: Wed, 5 Aug 2020 13:51:37 -0300 Subject: [PATCH 415/440] Fixed incorrect package --- includes/admin/views/html-quick-edit-product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/views/html-quick-edit-product.php b/includes/admin/views/html-quick-edit-product.php index b97a00b22b4..3fe48767cbd 100644 --- a/includes/admin/views/html-quick-edit-product.php +++ b/includes/admin/views/html-quick-edit-product.php @@ -2,7 +2,7 @@ /** * Admin View: Quick Edit Product * - * @package admin. + * @package WooCommerce\Admin\Notices */ defined( 'ABSPATH' ) || exit; From a50552af753733526bfde477f4880da221e15d43 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 5 Aug 2020 14:11:20 -0300 Subject: [PATCH 416/440] Use only WooCommerce as package name --- src/Autoloader.php | 2 +- src/Checkout/Helpers/ReserveStock.php | 2 +- src/Checkout/Helpers/ReserveStockException.php | 2 +- src/Container.php | 2 +- src/Internal/DependencyManagement/AbstractServiceProvider.php | 2 +- src/Internal/DependencyManagement/ContainerException.php | 2 +- src/Internal/DependencyManagement/ExtendedContainer.php | 2 +- .../ServiceProviders/ProxiesServiceProvider.php | 2 +- src/Internal/WCCom/ConnectionHelper.php | 2 +- src/Packages.php | 2 +- src/Proxies/ActionsProxy.php | 4 +--- src/Proxies/LegacyProxy.php | 4 +--- .../DependencyManagement/AbstractServiceProviderTest.php | 2 +- .../ClassWithConstructorArgumentWithoutTypeHint.php | 2 +- .../ExampleClasses/ClassWithDependencies.php | 2 +- .../ExampleClasses/ClassWithPrivateConstructor.php | 2 +- .../ExampleClasses/ClassWithScalarConstructorArgument.php | 2 +- .../ExampleClasses/ClassWithSingleton.php | 2 +- .../DependencyManagement/ExampleClasses/DependencyClass.php | 2 +- .../Internal/DependencyManagement/ExtendedContainerTest.php | 2 +- tests/php/src/Proxies/ClassThatDependsOnLegacyCodeTest.php | 2 +- .../Proxies/ExampleClasses/ClassThatDependsOnLegacyCode.php | 2 +- tests/php/src/Proxies/LegacyProxyTest.php | 2 +- tests/php/src/Proxies/MockableLegacyProxyTest.php | 2 +- 24 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/Autoloader.php b/src/Autoloader.php index f2da75ee72b..fb299266388 100644 --- a/src/Autoloader.php +++ b/src/Autoloader.php @@ -2,7 +2,7 @@ /** * Includes the composer Autoloader used for packages and classes in the src/ directory. * - * @package Automattic/WooCommerce + * @package WooCommerce */ namespace Automattic\WooCommerce; diff --git a/src/Checkout/Helpers/ReserveStock.php b/src/Checkout/Helpers/ReserveStock.php index b575ecc62fc..b72dc5691a7 100644 --- a/src/Checkout/Helpers/ReserveStock.php +++ b/src/Checkout/Helpers/ReserveStock.php @@ -2,7 +2,7 @@ /** * Handle product stock reservation during checkout. * - * @package Automattic/WooCommerce + * @package WooCommerce */ namespace Automattic\WooCommerce\Checkout\Helpers; diff --git a/src/Checkout/Helpers/ReserveStockException.php b/src/Checkout/Helpers/ReserveStockException.php index e84409b5f1d..2249b0162c3 100644 --- a/src/Checkout/Helpers/ReserveStockException.php +++ b/src/Checkout/Helpers/ReserveStockException.php @@ -2,7 +2,7 @@ /** * Exceptions for stock reservation. * - * @package Automattic/WooCommerce + * @package WooCommerce */ namespace Automattic\WooCommerce\Checkout\Helpers; diff --git a/src/Container.php b/src/Container.php index faae3e8a672..23b9f9a7fc8 100644 --- a/src/Container.php +++ b/src/Container.php @@ -2,7 +2,7 @@ /** * Container class file. * - * @package Automattic\WooCommerce + * @package WooCommerce */ namespace Automattic\WooCommerce; diff --git a/src/Internal/DependencyManagement/AbstractServiceProvider.php b/src/Internal/DependencyManagement/AbstractServiceProvider.php index 6f9e3537535..1070a0880ac 100644 --- a/src/Internal/DependencyManagement/AbstractServiceProvider.php +++ b/src/Internal/DependencyManagement/AbstractServiceProvider.php @@ -2,7 +2,7 @@ /** * AbstractServiceProvider class file. * - * @package Automattic\WooCommerce\Internal\DependencyManagement + * @package WooCommerce\Internal\DependencyManagement */ namespace Automattic\WooCommerce\Internal\DependencyManagement; diff --git a/src/Internal/DependencyManagement/ContainerException.php b/src/Internal/DependencyManagement/ContainerException.php index 916b1855e31..4dceb188ce8 100644 --- a/src/Internal/DependencyManagement/ContainerException.php +++ b/src/Internal/DependencyManagement/ContainerException.php @@ -2,7 +2,7 @@ /** * ExtendedContainer class file. * - * @package Automattic\WooCommerce\Internal\DependencyManagement + * @package WooCommerce\Internal\DependencyManagement */ namespace Automattic\WooCommerce\Internal\DependencyManagement; diff --git a/src/Internal/DependencyManagement/ExtendedContainer.php b/src/Internal/DependencyManagement/ExtendedContainer.php index 6344489bdb2..9a308b292a0 100644 --- a/src/Internal/DependencyManagement/ExtendedContainer.php +++ b/src/Internal/DependencyManagement/ExtendedContainer.php @@ -2,7 +2,7 @@ /** * ExtendedContainer class file. * - * @package Automattic\WooCommerce\Internal\DependencyManagement + * @package WooCommerce\Internal\DependencyManagement */ namespace Automattic\WooCommerce\Internal\DependencyManagement; diff --git a/src/Internal/DependencyManagement/ServiceProviders/ProxiesServiceProvider.php b/src/Internal/DependencyManagement/ServiceProviders/ProxiesServiceProvider.php index b864bda2e21..a15e0959fa5 100644 --- a/src/Internal/DependencyManagement/ServiceProviders/ProxiesServiceProvider.php +++ b/src/Internal/DependencyManagement/ServiceProviders/ProxiesServiceProvider.php @@ -2,7 +2,7 @@ /** * Proxies class file. * - * @package Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders + * @package WooCommerce\Internal\DependencyManagement\ServiceProviders */ namespace Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders; diff --git a/src/Internal/WCCom/ConnectionHelper.php b/src/Internal/WCCom/ConnectionHelper.php index ab159f6e488..90df2b9560b 100644 --- a/src/Internal/WCCom/ConnectionHelper.php +++ b/src/Internal/WCCom/ConnectionHelper.php @@ -2,7 +2,7 @@ /** * Helpers for managing connection to WooCommerce.com. * - * @package Automattic\WooCommerce\Internals\WCCom + * @package WooCommerce\Internals\WCCom */ namespace Automattic\WooCommerce\Internal\WCCom; diff --git a/src/Packages.php b/src/Packages.php index 1a5b82eb5a2..bd41e7a1818 100644 --- a/src/Packages.php +++ b/src/Packages.php @@ -2,7 +2,7 @@ /** * Loads WooCommece packages from the /packages directory. These are packages developed outside of core. * - * @package Automattic/WooCommerce + * @package WooCommerce */ namespace Automattic\WooCommerce; diff --git a/src/Proxies/ActionsProxy.php b/src/Proxies/ActionsProxy.php index 7e5d583b8d6..d285df9bcc0 100644 --- a/src/Proxies/ActionsProxy.php +++ b/src/Proxies/ActionsProxy.php @@ -2,7 +2,7 @@ /** * ActionsProxy class file. * - * @package Automattic/WooCommerce/Tools/Proxies + * @package WooCommerce\Tools\Proxies */ namespace Automattic\WooCommerce\Proxies; @@ -11,8 +11,6 @@ namespace Automattic\WooCommerce\Proxies; * Proxy for interacting with WordPress actions and filters. * * This class should be used instead of directly accessing the WordPress functions, to ease unit testing. - * - * @package Automattic\WooCommerce\Tools\Proxies */ class ActionsProxy { diff --git a/src/Proxies/LegacyProxy.php b/src/Proxies/LegacyProxy.php index c110b686f92..8db7286809c 100644 --- a/src/Proxies/LegacyProxy.php +++ b/src/Proxies/LegacyProxy.php @@ -2,7 +2,7 @@ /** * LegacyProxy class file. * - * @package Automattic/WooCommerce/Tools/Proxies + * @package WooCommerce\Tools\Proxies */ namespace Automattic\WooCommerce\Proxies; @@ -15,8 +15,6 @@ use \Psr\Container\ContainerInterface as Container; * This class should be used to interact with code outside the `src` directory, especially functions and classes * in the `includes` directory, unless a more specific proxy exists for the functionality at hand (e.g. `ActionsProxy`). * Idempotent functions can be executed directly. - * - * @package Automattic\WooCommerce\Tools\Proxies */ class LegacyProxy { diff --git a/tests/php/src/Internal/DependencyManagement/AbstractServiceProviderTest.php b/tests/php/src/Internal/DependencyManagement/AbstractServiceProviderTest.php index 8dda4b654b8..3cf7ab07edb 100644 --- a/tests/php/src/Internal/DependencyManagement/AbstractServiceProviderTest.php +++ b/tests/php/src/Internal/DependencyManagement/AbstractServiceProviderTest.php @@ -2,7 +2,7 @@ /** * AbstractServiceProviderTests class file. * - * @package Automattic\WooCommerce\Tests\Internal\DependencyManagement + * @package WooCommerce\Tests\Internal\DependencyManagement */ namespace Automattic\WooCommerce\Tests\Internal\DependencyManagement; diff --git a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithConstructorArgumentWithoutTypeHint.php b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithConstructorArgumentWithoutTypeHint.php index 0d45684ff20..b4728900342 100644 --- a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithConstructorArgumentWithoutTypeHint.php +++ b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithConstructorArgumentWithoutTypeHint.php @@ -2,7 +2,7 @@ /** * ClassWithConstructorArgumentWithoutTypeHint class file. * - * @package Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses + * @package WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses */ namespace Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses; diff --git a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithDependencies.php b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithDependencies.php index 9701dd9a049..a4899a7f404 100644 --- a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithDependencies.php +++ b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithDependencies.php @@ -2,7 +2,7 @@ /** * ClassWithDependencies class file. * - * @package Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses + * @package WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses */ namespace Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses; diff --git a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithPrivateConstructor.php b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithPrivateConstructor.php index b4b89ba5b74..835bdb9ad98 100644 --- a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithPrivateConstructor.php +++ b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithPrivateConstructor.php @@ -2,7 +2,7 @@ /** * ClassWithPrivateConstructor class file. * - * @package Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses + * @package WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses */ namespace Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses; diff --git a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithScalarConstructorArgument.php b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithScalarConstructorArgument.php index c7888d3c34c..f9faa90a537 100644 --- a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithScalarConstructorArgument.php +++ b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithScalarConstructorArgument.php @@ -2,7 +2,7 @@ /** * ClassWithConstructorArgumentWithoutTypeHint class file. * - * @package Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses + * @package WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses */ namespace Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses; diff --git a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithSingleton.php b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithSingleton.php index 44205c8009e..aa0c191d648 100644 --- a/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithSingleton.php +++ b/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithSingleton.php @@ -2,7 +2,7 @@ /** * ClassWithSingleton class file. * - * @package Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses + * @package WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses */ // This class is in the root namespace on purpose, since it simulates being a legacy class in the 'includes' directory. diff --git a/tests/php/src/Internal/DependencyManagement/ExampleClasses/DependencyClass.php b/tests/php/src/Internal/DependencyManagement/ExampleClasses/DependencyClass.php index 3305ee2a372..c95a8040d16 100644 --- a/tests/php/src/Internal/DependencyManagement/ExampleClasses/DependencyClass.php +++ b/tests/php/src/Internal/DependencyManagement/ExampleClasses/DependencyClass.php @@ -2,7 +2,7 @@ /** * DependencyClass class file. * - * @package Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses + * @package WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses */ namespace Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses; diff --git a/tests/php/src/Internal/DependencyManagement/ExtendedContainerTest.php b/tests/php/src/Internal/DependencyManagement/ExtendedContainerTest.php index e766e6c4436..837e7431032 100644 --- a/tests/php/src/Internal/DependencyManagement/ExtendedContainerTest.php +++ b/tests/php/src/Internal/DependencyManagement/ExtendedContainerTest.php @@ -2,7 +2,7 @@ /** * ExtendedContainerTests class file. * - * @package Automattic\WooCommerce\Tests\Internal\DependencyManagement + * @package WooCommerce\Tests\Internal\DependencyManagement */ namespace Automattic\WooCommerce\Tests\Internal\DependencyManagement; diff --git a/tests/php/src/Proxies/ClassThatDependsOnLegacyCodeTest.php b/tests/php/src/Proxies/ClassThatDependsOnLegacyCodeTest.php index b9692e16b8b..750489d309a 100644 --- a/tests/php/src/Proxies/ClassThatDependsOnLegacyCodeTest.php +++ b/tests/php/src/Proxies/ClassThatDependsOnLegacyCodeTest.php @@ -2,7 +2,7 @@ /** * ClassThatDependsOnLegacyCodeTest class file * - * @package Automattic\WooCommerce\Tests\Proxies + * @package WooCommerce\Tests\Proxies */ namespace Automattic\WooCommerce\Tests\Proxies; diff --git a/tests/php/src/Proxies/ExampleClasses/ClassThatDependsOnLegacyCode.php b/tests/php/src/Proxies/ExampleClasses/ClassThatDependsOnLegacyCode.php index a6c3b7ed13b..a1268ec89a4 100644 --- a/tests/php/src/Proxies/ExampleClasses/ClassThatDependsOnLegacyCode.php +++ b/tests/php/src/Proxies/ExampleClasses/ClassThatDependsOnLegacyCode.php @@ -2,7 +2,7 @@ /** * ClassThatDependsOnLegacyCode class file * - * @package Automattic\WooCommerce\Tests\Proxies\ExampleClasses + * @package WooCommerce\Tests\Proxies\ExampleClasses */ namespace Automattic\WooCommerce\Tests\Proxies\ExampleClasses; diff --git a/tests/php/src/Proxies/LegacyProxyTest.php b/tests/php/src/Proxies/LegacyProxyTest.php index aebc9e80794..1d7d1f02ba5 100644 --- a/tests/php/src/Proxies/LegacyProxyTest.php +++ b/tests/php/src/Proxies/LegacyProxyTest.php @@ -2,7 +2,7 @@ /** * LegacyProxyTests class file * - * @package Automattic\WooCommerce\Tests\Proxies + * @package WooCommerce\Tests\Proxies */ namespace Automattic\WooCommerce\Tests\Proxies; diff --git a/tests/php/src/Proxies/MockableLegacyProxyTest.php b/tests/php/src/Proxies/MockableLegacyProxyTest.php index 5b739707e49..c502afdc824 100644 --- a/tests/php/src/Proxies/MockableLegacyProxyTest.php +++ b/tests/php/src/Proxies/MockableLegacyProxyTest.php @@ -2,7 +2,7 @@ /** * MockableLegacyProxyTests class file * - * @package Automattic\WooCommerce\Tests\Proxies + * @package WooCommerce\Tests\Proxies */ namespace Automattic\WooCommerce\Tests\Proxies; From 3632714885235098ca6c7a6fe5d3b0e00dce5f92 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 5 Aug 2020 14:23:50 -0300 Subject: [PATCH 417/440] Removed package tag from src --- src/Autoloader.php | 2 -- src/Checkout/Helpers/ReserveStock.php | 2 -- src/Checkout/Helpers/ReserveStockException.php | 2 -- src/Container.php | 2 -- src/Internal/DependencyManagement/AbstractServiceProvider.php | 2 -- src/Internal/DependencyManagement/ContainerException.php | 2 -- src/Internal/DependencyManagement/ExtendedContainer.php | 2 -- .../ServiceProviders/ProxiesServiceProvider.php | 2 -- src/Internal/WCCom/ConnectionHelper.php | 2 -- src/Packages.php | 2 -- src/Proxies/ActionsProxy.php | 2 -- src/Proxies/LegacyProxy.php | 2 -- .../DependencyManagement/AbstractServiceProviderTest.php | 2 -- .../ClassWithConstructorArgumentWithoutTypeHint.php | 2 -- .../ExampleClasses/ClassWithDependencies.php | 2 -- .../ExampleClasses/ClassWithPrivateConstructor.php | 2 -- .../ExampleClasses/ClassWithScalarConstructorArgument.php | 2 -- .../DependencyManagement/ExampleClasses/ClassWithSingleton.php | 2 -- .../DependencyManagement/ExampleClasses/DependencyClass.php | 2 -- .../src/Internal/DependencyManagement/ExtendedContainerTest.php | 2 -- tests/php/src/Proxies/ClassThatDependsOnLegacyCodeTest.php | 2 -- .../src/Proxies/ExampleClasses/ClassThatDependsOnLegacyCode.php | 2 -- tests/php/src/Proxies/LegacyProxyTest.php | 2 -- tests/php/src/Proxies/MockableLegacyProxyTest.php | 2 -- 24 files changed, 48 deletions(-) diff --git a/src/Autoloader.php b/src/Autoloader.php index fb299266388..53f802e31fb 100644 --- a/src/Autoloader.php +++ b/src/Autoloader.php @@ -1,8 +1,6 @@ Date: Wed, 5 Aug 2020 14:39:10 -0300 Subject: [PATCH 418/440] Ignore file comment and package tag in src --- phpcs.xml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/phpcs.xml b/phpcs.xml index 5e17b62b39f..22b22d103c9 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -73,6 +73,15 @@ tests/Tools/
    + + src/ + tests/php/ + + + src/ + tests/php/ + + tests/php/ @@ -80,7 +89,7 @@ tests/php/ - + src/ From 525db3aa21d0a8d272b114a3ccc1f2d83873e755 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 5 Aug 2020 17:49:10 -0300 Subject: [PATCH 419/440] Fixed incorrect package tags --- includes/admin/class-wc-admin-post-types.php | 2 +- .../admin/list-tables/class-wc-admin-list-table-orders.php | 2 +- .../meta-boxes/views/html-product-data-linked-products.php | 2 +- includes/admin/settings/views/html-settings-tax.php | 6 ++++++ includes/admin/settings/views/settings-tax.php | 2 +- .../admin/views/html-notice-regenerating-lookup-table.php | 2 +- includes/cli/class-wc-cli-rest-command.php | 2 +- includes/data-stores/class-wc-coupon-data-store-cpt.php | 2 +- .../class-wc-wccom-site-installer-requirements-check.php | 2 +- includes/wccom-site/class-wc-wccom-site-installer.php | 2 +- includes/wccom-site/class-wc-wccom-site.php | 2 +- .../rest-api/class-wc-rest-wccom-site-installer-errors.php | 2 +- .../class-wc-rest-wccom-site-installer-controller.php | 3 +-- 13 files changed, 18 insertions(+), 13 deletions(-) diff --git a/includes/admin/class-wc-admin-post-types.php b/includes/admin/class-wc-admin-post-types.php index 5ebfcd55659..e2354239990 100644 --- a/includes/admin/class-wc-admin-post-types.php +++ b/includes/admin/class-wc-admin-post-types.php @@ -2,7 +2,7 @@ /** * Post Types Admin * - * @package WooCommerce\admin + * @package WooCommerce\Admin * @version 3.3.0 */ diff --git a/includes/admin/list-tables/class-wc-admin-list-table-orders.php b/includes/admin/list-tables/class-wc-admin-list-table-orders.php index 87a8619e45a..e76991fe440 100644 --- a/includes/admin/list-tables/class-wc-admin-list-table-orders.php +++ b/includes/admin/list-tables/class-wc-admin-list-table-orders.php @@ -2,7 +2,7 @@ /** * List tables: orders. * - * @package WooCommerce\admin + * @package WooCommerce\Admin * @version 3.3.0 */ diff --git a/includes/admin/meta-boxes/views/html-product-data-linked-products.php b/includes/admin/meta-boxes/views/html-product-data-linked-products.php index 8233b27d4b9..703bce477f4 100644 --- a/includes/admin/meta-boxes/views/html-product-data-linked-products.php +++ b/includes/admin/meta-boxes/views/html-product-data-linked-products.php @@ -2,7 +2,7 @@ /** * Linked product options. * - * @package WooCommerce\admin + * @package WooCommerce\Admin */ defined( 'ABSPATH' ) || exit; diff --git a/includes/admin/settings/views/html-settings-tax.php b/includes/admin/settings/views/html-settings-tax.php index 98b6e910527..15a7a95cfbd 100644 --- a/includes/admin/settings/views/html-settings-tax.php +++ b/includes/admin/settings/views/html-settings-tax.php @@ -1,4 +1,10 @@ Date: Wed, 5 Aug 2020 14:19:43 -0700 Subject: [PATCH 420/440] Pinned the dependencies that were not already pinned --- composer.json | 8 +- composer.lock | 83 +- package-lock.json | 5824 ++++++++++++++++++++++++++++++++++++++++----- package.json | 2 +- 4 files changed, 5335 insertions(+), 582 deletions(-) diff --git a/composer.json b/composer.json index ae23f4905c6..282e63ab77d 100644 --- a/composer.json +++ b/composer.json @@ -8,12 +8,12 @@ "minimum-stability": "dev", "require": { "php": ">=7.0", - "automattic/jetpack-autoloader": "^2.0.2", - "automattic/jetpack-constants": "^1.1", + "automattic/jetpack-autoloader": "2.0.2", + "automattic/jetpack-constants": "1.4.0", "composer/installers": "1.7.0", - "league/container": "^3.3", + "league/container": "3.3.1", "maxmind-db/reader": "1.6.0", - "pelago/emogrifier": "^3.1", + "pelago/emogrifier": "3.1.0", "woocommerce/action-scheduler": "3.1.6", "woocommerce/woocommerce-admin": "1.4.0-beta.3", "woocommerce/woocommerce-blocks": "3.1.0", diff --git a/composer.lock b/composer.lock index 483c502abec..a05f2f6a4c4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d7df64252352cb3445d827cf204f24b4", + "content-hash": "d90fdd441ed3eebf7b0bb77b5304b616", "packages": [ { "name": "automattic/jetpack-autoloader", - "version": "v2.1.0", + "version": "v2.0.2", "source": { "type": "git", "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "802517b3ff3010de89141d9f7c4d56aec1d21527" + "reference": "4502da4b2443fc1b61389cacc94c34876aca2b3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/802517b3ff3010de89141d9f7c4d56aec1d21527", - "reference": "802517b3ff3010de89141d9f7c4d56aec1d21527", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/4502da4b2443fc1b61389cacc94c34876aca2b3d", + "reference": "4502da4b2443fc1b61389cacc94c34876aca2b3d", "shasum": "" }, "require": { @@ -40,7 +40,7 @@ "GPL-2.0-or-later" ], "description": "Creates a custom autoloader for a plugin or theme.", - "time": "2020-07-27T20:37:00+00:00" + "time": "2020-07-09T13:18:38+00:00" }, { "name": "automattic/jetpack-constants", @@ -259,6 +259,12 @@ "provider", "service" ], + "funding": [ + { + "url": "https://github.com/philipobenito", + "type": "github" + } + ], "time": "2020-05-18T08:20:23+00:00" }, { @@ -495,6 +501,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-03-16T08:31:04+00:00" }, { @@ -788,6 +808,20 @@ "constructor", "instantiate" ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], "time": "2020-05-29T17:27:14+00:00" }, { @@ -1050,6 +1084,12 @@ "object", "object graph" ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], "time": "2020-06-29T13:22:24+00:00" }, { @@ -2574,6 +2614,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-02-14T07:34:21+00:00" }, { @@ -2636,6 +2690,20 @@ "polyfill", "portable" ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-07-14T12:35:20+00:00" }, { @@ -3041,5 +3109,6 @@ "platform-dev": [], "platform-overrides": { "php": "7.1" - } + }, + "plugin-api-version": "1.1.0" } diff --git a/package-lock.json b/package-lock.json index 2b8c89d52ce..27f3b90f3e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3668,6 +3668,24 @@ "regenerator-runtime": "^0.13.2" } }, + "@babel/runtime-corejs3": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.11.2.tgz", + "integrity": "sha512-qh5IR+8VgFz83VBa6OkaET6uN/mJOhHONuy3m1sgF0CV6mXdPSEBdA7e1eUbVvyNtANjMbg22JUv71BaDXLY6A==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + } + } + }, "@babel/template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", @@ -7645,6 +7663,12 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -7806,6 +7830,104 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.1.0.tgz", + "integrity": "sha512-D52KwdgkjYc+fmTZKW7CZpH5ZBJREJKZXRrveMiRCmlzZ+Rw9wRVJ1JAmHQ9b/+Ehy1ZeaylofDB9wwXUt83wg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "3.1.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz", + "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz", + "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@typescript-eslint/experimental-utils": { "version": "2.34.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", @@ -7829,6 +7951,97 @@ } } }, + "@typescript-eslint/parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.1.0.tgz", + "integrity": "sha512-NcDSJK8qTA2tPfyGiPes9HtVKLbksmuYjlgGAUs7Ld2K0swdWibnCq9IJx9kJN8JJdgUJSorFiGaPHBgH81F/Q==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "3.1.0", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz", + "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.1.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz", + "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@typescript-eslint/typescript-estree": { "version": "2.34.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", @@ -8741,6 +8954,4486 @@ } } }, + "@woocommerce/model-factories": { + "version": "file:tests/e2e/factories", + "dev": true, + "requires": { + "axios": "0.19.2", + "create-hmac": "1.1.7", + "faker": "4.1.0", + "fishery": "1.0.0", + "oauth-1.0a": "2.2.6" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.4.tgz", + "integrity": "sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/generator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", + "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", + "requires": { + "@babel/types": "^7.10.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", + "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", + "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", + "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==" + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/runtime-corejs3": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", + "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", + "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@babel/types": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + }, + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz", + "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/reporters": "^25.5.1", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^25.5.0", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-resolve-dependencies": "^25.5.4", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "jest-watcher": "^25.5.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "realpath-native": "^2.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + } + }, + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "requires": { + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", + "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "@types/create-hmac": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/create-hmac/-/create-hmac-1.1.0.tgz", + "integrity": "sha512-BNYNdzdhOZZQWCOpwvIll3FSvgo3e55Y2M6s/jOY6TuOCwqt3cLmQsK4tSmJ5fayDot8EG4k3+hcZagfww9JlQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/faker": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-4.1.12.tgz", + "integrity": "sha512-0MEyzJrLLs1WaOCx9ULK6FzdCSj2EuxdSP9kvuxxdBEGujZYUOZ4vkPXdgu3dhyg/pOdn7VCatelYX7k0YShlA==" + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.1.tgz", + "integrity": "sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA==", + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "@types/moxios": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@types/moxios/-/moxios-0.4.9.tgz", + "integrity": "sha512-Sd1b24QRW2N194j2LEDPQAZK1h0TBtpN+2EIH+rERCgm38qm14JZwC7NlpE7n3jULhlCIPZBG8uNcbjF8KcCaQ==", + "requires": { + "axios": "^0.19.0" + } + }, + "@types/node": { + "version": "13.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz", + "integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==" + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==" + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" + } + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", + "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", + "requires": { + "xregexp": "^4.2.4" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==" + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==" + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "requires": { + "bser": "2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fishery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fishery/-/fishery-1.0.0.tgz", + "integrity": "sha512-DLQtxcSPlLQYY6J0tL/dl7DfPhrULHCAO6fFDGnrXqA830J6AW124fHarYOLnfvcSXNBEooBS/g65N/HecQYjQ==", + "dev": true, + "requires": { + "lodash.merge": "^4.6.2" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-25.5.4.tgz", + "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==", + "requires": { + "@jest/core": "^25.5.4", + "import-local": "^3.0.2", + "jest-cli": "^25.5.4" + }, + "dependencies": { + "jest-cli": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz", + "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==", + "requires": { + "@jest/core": "^25.5.4", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^25.5.4", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "prompts": "^2.0.1", + "realpath-native": "^2.0.0", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz", + "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==", + "requires": { + "@jest/types": "^25.5.0", + "execa": "^3.2.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + } + } + }, + "jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + } + }, + "jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" + } + }, + "jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } + }, + "jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "requires": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "requires": { + "@jest/types": "^25.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz", + "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==", + "requires": { + "@jest/types": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-snapshot": "^25.5.1" + } + }, + "jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + } + }, + "jest-watcher": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz", + "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==", + "requires": { + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "jest-util": "^25.5.0", + "string-length": "^3.1.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "requires": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "moxios": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/moxios/-/moxios-0.4.0.tgz", + "integrity": "sha1-/A2ixlR31yXKa5Z51YNw7QxS9Ts=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" + }, + "node-notifier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", + "shellwords": "^0.1.1", + "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, + "oauth-1.0a": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-2.2.6.tgz", + "integrity": "sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "requires": { + "lodash": "^4.17.15" + } + }, + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "requires": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "requires": { + "xmlchars": "^2.1.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "^2.1.0" + } + }, + "ts-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.5.0.tgz", + "integrity": "sha512-govrjbOk1UEzcJ5cX5k8X8IUtFuP3lp3mrF3ZuKtCdAOQzdeCM7qualhb/U8s8SWFwEDutOqfF5PLkJ+oaYD4w==", + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "micromatch": "4.x", + "mkdirp": "0.x", + "semver": "6.x", + "yargs-parser": "18.x" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==" + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "requires": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz", + "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^3.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + } + } + } + } + }, "@wordpress/babel-plugin-import-jsx-pragma": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-1.1.3.tgz", @@ -8892,6 +13585,43 @@ } } }, + "@wordpress/eslint-plugin": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-7.1.0.tgz", + "integrity": "sha512-FTrKkpEa8vZg7/7M6GBhd1YW24hnh5rFGzKgKX4MGyB0Jw8GGSwld9J23eRbQ5JQWGFP/tmOMeiu6W1/arxy7Q==", + "dev": true, + "requires": { + "@wordpress/prettier-config": "^0.3.0", + "babel-eslint": "^10.1.0", + "eslint-config-prettier": "^6.10.1", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-jsdoc": "^26.0.0", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-react": "^7.20.0", + "eslint-plugin-react-hooks": "^4.0.4", + "globals": "^12.0.0", + "prettier": "npm:wp-prettier@2.0.5", + "requireindex": "^1.2.0" + }, + "dependencies": { + "eslint-plugin-react-hooks": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.8.tgz", + "integrity": "sha512-6SSb5AiMCPd8FDJrzah+Z4F44P2CdOaK026cXFV+o/xSRzfOiV1FNFeLl2z6xm3yqWOQEZ5OfVgiec90qV2xrQ==", + "dev": true + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, "@wordpress/i18n": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.13.0.tgz", @@ -8963,6 +13693,12 @@ } } }, + "@wordpress/prettier-config": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-0.3.0.tgz", + "integrity": "sha512-wL1ztV+so5Ttwz23lDmb8ZmREmND96sf+Dh/kbP2nyAw/DWt3K8uj31qbczVmjwfoetTiRoH9Z1CasgPs4bccg==", + "dev": true + }, "@wordpress/url": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.16.0.tgz", @@ -9361,6 +14097,33 @@ } } }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + } + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -9415,6 +14178,17 @@ "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", @@ -9462,6 +14236,17 @@ "es-abstract": "^1.17.0-next.1" } }, + "array.prototype.flatmap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", + "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -9539,6 +14324,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -9639,6 +14430,12 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, + "axe-core": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.5.5.tgz", + "integrity": "sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==", + "dev": true + }, "axios": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", @@ -9648,6 +14445,12 @@ "follow-redirects": "1.5.10" } }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -11186,12 +15989,6 @@ "safe-buffer": "^5.0.1" } }, - "cjk-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cjk-regex/-/cjk-regex-1.0.2.tgz", - "integrity": "sha512-NwSMtwULPLk8Ka9DEUcoFXhMRnV/bpyKDnoyDiVw/Qy5przhvHTvXLcsKaOmx13o8J4XEsPVT1baoCUj5zQs3w==", - "dev": true - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -11530,6 +16327,12 @@ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true }, + "comment-parser": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.5.tgz", + "integrity": "sha512-iH9YA35ccw94nx5244GVkpyC9eVTsL71jZz6iz5w6RIf79JLF2AsXHXq9p6Oaohyl3sx5qSMnGsWUDFIAfWL4w==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -12665,6 +17468,12 @@ } } }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -12904,6 +17713,12 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "dev": true + }, "dargs": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", @@ -12922,12 +17737,6 @@ "assert-plus": "^1.0.0" } }, - "dashify": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz", - "integrity": "sha1-agdBWgHJH69KMuONnfunH2HLIP4=", - "dev": true - }, "data-urls": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", @@ -13369,42 +18178,6 @@ "safer-buffer": "^2.1.0" } }, - "editorconfig": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.14.2.tgz", - "integrity": "sha512-tghjvKwo1gakrhFiZWlbo5ILWAfnuOu1JFztW0li+vzbnInN0CMZuF4F0T/Pnn9UWpT7Mr1aFTWdHVuxiR9K9A==", - "dev": true, - "requires": { - "bluebird": "^3.0.5", - "commander": "^2.9.0", - "lru-cache": "^3.2.0", - "semver": "^5.1.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "lru-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", - "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", - "dev": true, - "requires": { - "pseudomap": "^1.0.1" - } - } - } - }, - "editorconfig-to-prettier": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.0.6.tgz", - "integrity": "sha512-Ysw+hBdwhPFruYmLapKRm7Or5XgMzhasbqu4AN07V2l/AkqpgooWm2xtTQPzTD6S0tq54A+WbSxNt6qmsO3hoA==", - "dev": true - }, "electron-to-chromium": { "version": "1.3.483", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.483.tgz", @@ -13824,6 +18597,23 @@ } } }, + "eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, "eslint-config-wpcalypso": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-config-wpcalypso/-/eslint-config-wpcalypso-5.0.0.tgz", @@ -13842,6 +18632,201 @@ "@typescript-eslint/experimental-utils": "^2.5.0" } }, + "eslint-plugin-jsdoc": { + "version": "26.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-26.0.2.tgz", + "integrity": "sha512-KtZjqtM3Z8x84vQBFKGUyBbZRGXYHVWSJ2XyYSUTc8KhfFrvzQ/GXPp6f1M1/YCNzP3ImD5RuDNcr+OVvIZcBA==", + "dev": true, + "requires": { + "comment-parser": "^0.7.4", + "debug": "^4.1.1", + "jsdoctypeparser": "^6.1.0", + "lodash": "^4.17.15", + "regextras": "^0.7.1", + "semver": "^6.3.0", + "spdx-expression-parse": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.3.1.tgz", + "integrity": "sha512-i1S+P+c3HOlBJzMFORRbC58tHa65Kbo8b52/TwCwSKLohwvpfT5rm2GjGWzOHTEuq4xxf2aRlHHTtmExDQOP+g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^3.5.4", + "axobject-query": "^2.1.2", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1", + "language-tags": "^1.0.5" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "emoji-regex": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.0.0.tgz", + "integrity": "sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-react": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.5.tgz", + "integrity": "sha512-ajbJfHuFnpVNJjhyrfq+pH1C0gLc2y94OiCbAXT5O0J0YCKaFEHDV8+3+mDOr+w8WguRX+vSs1bM2BDG0VLvCw==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1", + "object.entries": "^1.1.2", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.17.0", + "string.prototype.matchall": "^4.0.2" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, "eslint-plugin-react-hooks": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.3.0.tgz", @@ -14214,6 +19199,12 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", @@ -14248,15 +19239,6 @@ "reusify": "^1.0.0" } }, - "fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "dev": true, - "requires": { - "format": "^0.2.0" - } - }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -14550,18 +19532,6 @@ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", - "dev": true - }, - "flow-parser": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.59.0.tgz", - "integrity": "sha1-9uvK5h/6GH5CCZnUDOCoAfObJjU=", - "dev": true - }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -14624,12 +19594,6 @@ "mime-types": "^2.1.12" } }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "dev": true - }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -16066,27 +21030,6 @@ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "globjoin": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", @@ -16127,15 +21070,6 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, - "graphql": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz", - "integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==", - "dev": true, - "requires": { - "iterall": "^1.1.0" - } - }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -17436,6 +22370,17 @@ } } }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + } + }, "interpret": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", @@ -18005,12 +22950,6 @@ "handlebars": "^4.0.3" } }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", - "dev": true - }, "jest": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz", @@ -18640,15 +23579,6 @@ } } }, - "jest-docblock": { - "version": "21.3.0-beta.11", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.3.0-beta.11.tgz", - "integrity": "sha512-sxSwZUm7JyCO8dverup5g/OKJhjYRrBdgEdezIO1qAmMGWuza7ewovpfDmxp+JLvlm0i2WRFKUQNNIMGmPGTVg==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, "jest-each": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.1.0.tgz", @@ -18829,12 +23759,6 @@ } } }, - "jest-get-type": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", - "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", - "dev": true - }, "jest-haste-map": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", @@ -19819,18 +24743,6 @@ } } }, - "jest-validate": { - "version": "21.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.1.0.tgz", - "integrity": "sha512-xS0cyErNWpsLFlGkn/b87pk/Mv7J+mCTs8hQ4KmtOIIoM1sHYobXII8AtkoN8FC7E3+Ptxjo+/3xWk6LK1dKcw==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^21.0.2", - "leven": "^2.1.0", - "pretty-format": "^21.1.0" - } - }, "jest-watcher": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.1.0.tgz", @@ -19961,6 +24873,12 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "jsdoctypeparser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", + "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", + "dev": true + }, "jsdom": { "version": "15.2.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", @@ -20100,6 +25018,16 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", + "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "object.assign": "^4.1.0" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -20121,6 +25049,21 @@ "integrity": "sha512-Vi3nxDGMm/z+lAaCjvAR1u+7fiv+sG6gU/iYDj5QOF8h76ytK9EW/EKfF0NeTyiGBi8Jy6Hklty/vxISrLox3w==", "dev": true }, + "language-subtag-registry": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz", + "integrity": "sha512-KPMwROklF4tEx283Xw0pNKtfTj1gZ4UByp4EsIFWLgBavJltF4TiYPc39k06zSTsLzxTVXXDSpbwaQXaFB4Qeg==", + "dev": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -20213,12 +25156,6 @@ } } }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, "levenary": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", @@ -20913,12 +25850,6 @@ "lodash._reinterpolate": "^3.0.0" } }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", - "dev": true - }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -21171,9 +26102,9 @@ "dev": true }, "marked": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.2.tgz", - "integrity": "sha512-LqxwVH3P/rqKX4EKGz7+c2G9r98WeM/SW34ybhgNGhUQNKtf1GmmSkJ6cDGJ/t6tiyae49qRkpyTw2B9HOrgUA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.3.tgz", + "integrity": "sha512-Fqa7eq+UaxfMriqzYLayfqAE40WN03jf+zHjT18/uXNuzjq3TY0XTbrAoPeqSJrAmPz11VuUA+kBPYOhHt9oOQ==", "dev": true }, "mathml-tag-names": { @@ -21266,15 +26197,6 @@ "unist-util-visit": "^1.1.0" } }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "memize": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", @@ -23248,92 +28170,6 @@ "@babel/core": ">=7.2.2" } }, - "postcss-less": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-1.1.3.tgz", - "integrity": "sha512-WS0wsQxRm+kmN8wEYAGZ3t4lnoNfoyx9EJZrhiPR1K0lMHR0UNWnz52Ya5QRXChHtY75Ef+kDc05FpnBujebgw==", - "dev": true, - "requires": { - "postcss": "^5.2.16" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, "postcss-markdown": { "version": "0.36.0", "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", @@ -23398,48 +28234,6 @@ "postcss": "^7.0.21" } }, - "postcss-scss": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.2.tgz", - "integrity": "sha1-/0XPM1S4ee6JpOtoaA9GrJuxT5Q=", - "dev": true, - "requires": { - "postcss": "^6.0.3" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", - "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", - "dev": true, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "postcss-syntax": { "version": "0.36.2", "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", @@ -23452,17 +28246,6 @@ "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==", "dev": true }, - "postcss-values-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-1.3.1.tgz", - "integrity": "sha512-chFn9CnFAAUpQ3cwrxvVjKB8c0y6BfONv6eapndJoTXJ3h8fr1uAiue8lGP3rUIpBI2KgJGdgCVk9KNvXh0n6A==", - "dev": true, - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -23470,163 +28253,18 @@ "dev": true }, "prettier": { - "version": "github:automattic/calypso-prettier#c56b42511ec98ba6d8f72b6c391e0a626e90f531", - "from": "github:automattic/calypso-prettier#c56b4251", + "version": "npm:wp-prettier@2.0.5", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.0.5.tgz", + "integrity": "sha512-5GCgdeevIXwR3cW4Qj5XWC5MO1iSCz8+IPn0mMw6awAt/PBiey8yyO7MhePRsaMqghJAhg6Q3QLYWSnUHWkG6A==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "requires": { - "babel-code-frame": "7.0.0-beta.3", - "babylon": "7.0.0-beta.34", - "camelcase": "4.1.0", - "chalk": "2.1.0", - "cjk-regex": "1.0.2", - "cosmiconfig": "3.1.0", - "dashify": "0.2.2", - "diff": "3.2.0", - "editorconfig": "0.14.2", - "editorconfig-to-prettier": "0.0.6", - "emoji-regex": "6.5.1", - "escape-string-regexp": "1.0.5", - "esutils": "2.0.2", - "flow-parser": "0.59.0", - "get-stream": "3.0.0", - "globby": "6.1.0", - "graphql": "0.10.5", - "ignore": "3.3.7", - "jest-docblock": "21.3.0-beta.11", - "jest-validate": "21.1.0", - "leven": "2.1.0", - "mem": "1.1.0", - "minimatch": "3.0.4", - "minimist": "1.2.0", - "parse5": "3.0.3", - "path-root": "0.1.1", - "postcss-less": "1.1.3", - "postcss-media-query-parser": "0.2.3", - "postcss-scss": "1.0.2", - "postcss-selector-parser": "2.2.3", - "postcss-values-parser": "1.3.1", - "remark-frontmatter": "1.1.0", - "remark-parse": "4.0.0", - "semver": "5.4.1", - "string-width": "2.1.1", - "typescript": "2.6.2", - "typescript-eslint-parser": "9.0.1", - "unicode-regex": "1.0.1", - "unified": "6.1.6" - }, - "dependencies": { - "babel-code-frame": { - "version": "7.0.0-beta.3", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-7.0.0-beta.3.tgz", - "integrity": "sha512-flMsJ9eSpShupt2Gwpka84DoMePvE4HlDObzdEc+1iNkacv3+NHlsJ7dMKmbnVA/AT22UhcGEBHwbJLoXWBO6Q==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^3.0.0" - } - }, - "babylon": { - "version": "7.0.0-beta.34", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.34.tgz", - "integrity": "sha512-ribEzWEhWKKjY+1FdKCryo+HiN/1idPjUB8vyR5Yf221MtGzCd5+7OwPvWvYHerHHC2eJLr6MhvumbTocXGY7Q==", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "cosmiconfig": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-3.1.0.tgz", - "integrity": "sha512-zedsBhLSbPBms+kE7AH4vHg6JsKDz6epSv2/+5XHs8ILHlgDciSJfSWf8sX9aQ52Jb7KI7VswUTsLpR/G0cr2Q==", - "dev": true, - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^3.0.0", - "require-from-string": "^2.0.1" - } - }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "emoji-regex": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", - "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "parse-json": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-3.0.0.tgz", - "integrity": "sha1-+m9HsY4jgm6tMvJj50TQ4ehH+xM=", - "dev": true, - "requires": { - "error-ex": "^1.3.1" - } - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } + "fast-diff": "^1.1.2" } }, "pretty-bytes": { @@ -23638,16 +28276,6 @@ "number-is-nan": "^1.0.0" } }, - "pretty-format": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", - "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" - } - }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -25542,6 +30170,16 @@ "safe-regex": "^1.1.0" } }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -25562,6 +30200,12 @@ "unicode-match-property-value-ecmascript": "^1.2.0" } }, + "regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", + "dev": true + }, "regjsgen": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", @@ -25655,39 +30299,6 @@ } } }, - "remark-frontmatter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.1.0.tgz", - "integrity": "sha512-mLbYtwP9w1L9TA8dX+I/HyDF5lCpa0dmYvvW9Io+zUPpqEZ49QMKWb0hSpunpLVA+Squy0SowzSzjHVPbxWq1g==", - "dev": true, - "requires": { - "fault": "^1.0.1", - "xtend": "^4.0.1" - } - }, - "remark-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", - "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, "remark-stringify": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", @@ -25813,18 +30424,18 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "resolve": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", @@ -26521,11 +31132,15 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" + } }, "signal-exit": { "version": "3.0.2", @@ -27025,6 +31640,28 @@ } } }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } + } + }, "string.prototype.trim": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz", @@ -27036,6 +31673,58 @@ "function-bind": "^1.1.1" } }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "string.prototype.trimleft": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", @@ -27056,6 +31745,58 @@ "function-bind": "^1.1.1" } }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + } + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -28461,29 +33202,11 @@ } }, "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", "dev": true }, - "typescript-eslint-parser": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-9.0.1.tgz", - "integrity": "sha512-w1jqotvnhLtLukD9H3gQPAlbD0kLf7ZkoQGwiwSIshKIlzRL7i0OY9Y7VIdE1xtytZXThg678eomxMZ1rZXGVQ==", - "dev": true, - "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - } - } - }, "uglify-js": { "version": "3.5.11", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.11.tgz", @@ -28568,27 +33291,6 @@ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", "dev": true }, - "unicode-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-1.0.1.tgz", - "integrity": "sha1-+BngUBkdW5VhozmljdO5CV7ZSzU=", - "dev": true - }, - "unified": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.1.6.tgz", - "integrity": "sha512-pW2f82bCIo2ifuIGYcV12fL96kMMYgw7JKVEgh7ODlrM9rj6vXSY3BV+H6lCcv1ksxynFf582hwWLnA1qRFy4w==", - "dev": true, - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-function": "^1.0.4", - "x-is-string": "^0.1.0" - } - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -28968,18 +33670,6 @@ "extsprintf": "^1.2.0" } }, - "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", - "dev": true, - "requires": { - "is-buffer": "^1.1.4", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - }, "vfile-location": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.4.tgz", @@ -29904,12 +34594,6 @@ "async-limiter": "~1.0.0" } }, - "x-is-function": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz", - "integrity": "sha1-XSlNw9Joy90GJYDgxd93o5HR+h4=", - "dev": true - }, "x-is-string": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", diff --git a/package.json b/package.json index e137b26819f..8b0a6c8d309 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@babel/polyfill": "7.10.4", "@babel/preset-env": "7.10.4", "@babel/register": "7.10.4", - "@jest/test-sequencer": "^25.0.0", + "@jest/test-sequencer": "25.1.0", "@typescript-eslint/eslint-plugin": "3.1.0", "@typescript-eslint/parser": "3.1.0", "@woocommerce/e2e-environment": "file:tests/e2e/env", From 8e8698a3f6fc729d5059fdb6b7ff2c9b52976014 Mon Sep 17 00:00:00 2001 From: Christopher Allford Date: Wed, 5 Aug 2020 15:43:08 -0700 Subject: [PATCH 421/440] Fixed test that used PHPUnit function from newer version --- tests/php/includes/class-wc-product-variable-test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/php/includes/class-wc-product-variable-test.php b/tests/php/includes/class-wc-product-variable-test.php index e80b5751a0f..28fc57529fe 100644 --- a/tests/php/includes/class-wc-product-variable-test.php +++ b/tests/php/includes/class-wc-product-variable-test.php @@ -12,7 +12,7 @@ class WC_Product_Variable_Test extends \WC_Unit_Test_Case { $variations = $product->get_available_variations(); - $this->assertIsArray( $variations[0] ); + $this->assertTrue( is_array( $variations[0] ) ); $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]['sku'] ); } @@ -24,7 +24,7 @@ class WC_Product_Variable_Test extends \WC_Unit_Test_Case { $variations = $product->get_available_variations( 'array' ); - $this->assertIsArray( $variations[0] ); + $this->assertTrue( is_array( $variations[0] ) ); $this->assertEquals( 'DUMMY SKU VARIABLE SMALL', $variations[0]['sku'] ); } From 089df498d38718cc637bec7fd650f324265ae9af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2020 23:04:18 +0000 Subject: [PATCH 422/440] Bump lodash from 4.17.15 to 4.17.19 in /tests/e2e/factories Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] --- tests/e2e/factories/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/factories/package-lock.json b/tests/e2e/factories/package-lock.json index 645ae0e5ea3..2039d4c6bec 100644 --- a/tests/e2e/factories/package-lock.json +++ b/tests/e2e/factories/package-lock.json @@ -3113,9 +3113,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "lodash.memoize": { From 5b32ec3755672c4e47c828bc4a44400ea9fa0cf1 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 23 Jul 2020 01:04:43 +0530 Subject: [PATCH 423/440] Remove REST API package because its added directly. --- composer.json | 6 ++++-- composer.lock | 56 +-------------------------------------------------- 2 files changed, 5 insertions(+), 57 deletions(-) diff --git a/composer.json b/composer.json index 282e63ab77d..b7360f379f0 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,7 @@ "pelago/emogrifier": "3.1.0", "woocommerce/action-scheduler": "3.1.6", "woocommerce/woocommerce-admin": "1.4.0-beta.3", - "woocommerce/woocommerce-blocks": "3.1.0", - "woocommerce/woocommerce-rest-api": "1.0.11" + "woocommerce/woocommerce-blocks": "3.1.0" }, "require-dev": { "phpunit/phpunit": "7.5.20", @@ -40,6 +39,9 @@ "includes/legacy", "includes/libraries" ], + "classmap": [ + "includes/api" + ], "psr-4": { "Automattic\\WooCommerce\\": "src/" } diff --git a/composer.lock b/composer.lock index a05f2f6a4c4..9c95657f4c1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d90fdd441ed3eebf7b0bb77b5304b616", + "content-hash": "ae4abaa8d39e860cc6c379cb5f6a0c2f", "packages": [ { "name": "automattic/jetpack-autoloader", @@ -645,46 +645,6 @@ "woocommerce" ], "time": "2020-07-29T15:45:19+00:00" - }, - { - "name": "woocommerce/woocommerce-rest-api", - "version": "1.0.11", - "source": { - "type": "git", - "url": "https://github.com/woocommerce/woocommerce-rest-api.git", - "reference": "304bb95cb4b95f182f09d56153d5ac254d5fe60a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-rest-api/zipball/304bb95cb4b95f182f09d56153d5ac254d5fe60a", - "reference": "304bb95cb4b95f182f09d56153d5ac254d5fe60a", - "shasum": "" - }, - "require": { - "automattic/jetpack-autoloader": "^2.0.0" - }, - "require-dev": { - "phpunit/phpunit": "6.5.14", - "woocommerce/woocommerce-sniffs": "0.0.9" - }, - "type": "wordpress-plugin", - "autoload": { - "classmap": [ - "src/Controllers/Version1", - "src/Controllers/Version2", - "src/Controllers/Version3" - ], - "psr-4": { - "Automattic\\WooCommerce\\RestApi\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-3.0-or-later" - ], - "description": "The WooCommerce core REST API.", - "homepage": "https://github.com/woocommerce/woocommerce-rest-api", - "time": "2020-07-24T13:38:16+00:00" } ], "packages-dev": [ @@ -2690,20 +2650,6 @@ "polyfill", "portable" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-07-14T12:35:20+00:00" }, { From 1c162956ad3be7c87a89129b7efe51f815bd667d Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 23 Jul 2020 01:05:08 +0530 Subject: [PATCH 424/440] Remove REST API package check as files are directly added. --- src/Packages.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Packages.php b/src/Packages.php index 1a5b82eb5a2..f58a2a75da5 100644 --- a/src/Packages.php +++ b/src/Packages.php @@ -28,7 +28,6 @@ class Packages { */ protected static $packages = array( 'woocommerce-blocks' => '\\Automattic\\WooCommerce\\Blocks\\Package', - 'woocommerce-rest-api' => '\\Automattic\\WooCommerce\\RestApi\\Package', 'woocommerce-admin' => '\\Automattic\\WooCommerce\\Admin\\Composer\\Package', ); From 4a4767ae93e36237f16a6c11db7626223999e1da Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 23 Jul 2020 01:05:20 +0530 Subject: [PATCH 425/440] Load API files. --- includes/class-woocommerce.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/class-woocommerce.php b/includes/class-woocommerce.php index 4b7fd58ec17..aab01d66591 100644 --- a/includes/class-woocommerce.php +++ b/includes/class-woocommerce.php @@ -445,6 +445,7 @@ final class WooCommerce { /** * REST API. */ + \Automattic\WooCommerce\RestApi\Server::instance()->init(); include_once WC_ABSPATH . 'includes/legacy/class-wc-legacy-api.php'; include_once WC_ABSPATH . 'includes/class-wc-api.php'; include_once WC_ABSPATH . 'includes/class-wc-rest-authentication.php'; From 16473d54e9feabc9119ed6c5f41d342c987a9050 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Mon, 27 Jul 2020 15:54:46 +0530 Subject: [PATCH 426/440] Fixes for correct time of loading API --- includes/api/src/Package.php | 2 +- includes/class-wc-api.php | 2 +- includes/class-woocommerce.php | 9 ++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/includes/api/src/Package.php b/includes/api/src/Package.php index e2b421d066c..1f2ba8b8f07 100644 --- a/includes/api/src/Package.php +++ b/includes/api/src/Package.php @@ -19,7 +19,7 @@ class Package { * * @var string */ - const VERSION = '1.0.10'; + const VERSION = WC_VERSION; /** * Init the package - load the REST API Server class. diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 37356a34330..629e82feec1 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -30,7 +30,7 @@ class WC_API extends WC_Legacy_API { } /** - * Get the version of the REST API package being ran. + * Get the version of the REST API package being ran. Since API package was merged into core, this now follows WC version. * * @since 3.7.0 * @return string|null diff --git a/includes/class-woocommerce.php b/includes/class-woocommerce.php index aab01d66591..146376c31f2 100644 --- a/includes/class-woocommerce.php +++ b/includes/class-woocommerce.php @@ -198,6 +198,7 @@ final class WooCommerce { add_action( 'init', array( 'WC_Shortcodes', 'init' ) ); add_action( 'init', array( 'WC_Emails', 'init_transactional_emails' ) ); add_action( 'init', array( $this, 'add_image_sizes' ) ); + add_action( 'init', array( $this, 'load_rest_api' ) ); add_action( 'switch_blog', array( $this, 'wpdb_table_fix' ), 0 ); add_action( 'activated_plugin', array( $this, 'activated_plugin' ) ); add_action( 'deactivated_plugin', array( $this, 'deactivated_plugin' ) ); @@ -298,6 +299,13 @@ final class WooCommerce { return apply_filters( 'woocommerce_is_rest_api_request', $is_rest_api_request ); } + /** + * Load REST API. + */ + public function load_rest_api() { + \Automattic\WooCommerce\RestApi\Package::init(); + } + /** * What type of request is this? * @@ -445,7 +453,6 @@ final class WooCommerce { /** * REST API. */ - \Automattic\WooCommerce\RestApi\Server::instance()->init(); include_once WC_ABSPATH . 'includes/legacy/class-wc-legacy-api.php'; include_once WC_ABSPATH . 'includes/class-wc-api.php'; include_once WC_ABSPATH . 'includes/class-wc-rest-authentication.php'; From d5bf302994e74404e01e4b0659acd75b45de69b4 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Mon, 27 Jul 2020 17:26:04 +0530 Subject: [PATCH 427/440] Add API UT helpers to autoload so that individual tests can run in isolation. --- composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b7360f379f0..a2534abe158 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,10 @@ "psr-4": { "Automattic\\WooCommerce\\Tests\\": "tests/php/src/", "Automattic\\WooCommerce\\Testing\\Tools\\": "tests/Tools/" - } + }, + "classmap": [ + "tests/legacy/unit-tests/api/unit-tests/Helpers" + ] }, "scripts": { "post-install-cmd": [ From cfe357cfb2f8a4a0b09152783b580f1001321c32 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Mon, 27 Jul 2020 17:33:03 +0530 Subject: [PATCH 428/440] Fix UT to add predefined values to run tests in isolation. --- .../unit-tests/Tests/Version2/settings.php | 85 +++++++++++-------- .../unit-tests/Tests/Version3/settings.php | 85 +++++++++++-------- tests/legacy/unit-tests/packages/packages.php | 1 - 3 files changed, 96 insertions(+), 75 deletions(-) diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/settings.php b/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/settings.php index 12baa1aca4e..6117fdc87e0 100644 --- a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/settings.php +++ b/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/settings.php @@ -6,6 +6,9 @@ * @since 3.0.0 */ +/** + * Class Settings_V2. + */ class Settings_V2 extends WC_REST_Unit_Test_Case { /** @@ -161,19 +164,19 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_get_group() { wp_set_current_user( $this->user ); - // test route callback receiving an empty group id + // test route callback receiving an empty group id. $result = $this->endpoint->get_group_settings( '' ); $this->assertWPError( $result ); - // test getting a group that does not exist + // test getting a group that does not exist. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/not-real' ) ); $this->assertEquals( 404, $response->get_status() ); - // test getting the 'invalid' group + // test getting the 'invalid' group. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/invalid' ) ); $this->assertEquals( 404, $response->get_status() ); - // test getting a valid group with settings attached to it + // test getting a valid group with settings attached to it. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( 1, count( $data ) ); @@ -201,12 +204,12 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_update_setting() { wp_set_current_user( $this->user ); - // test defaults first + // test defaults first. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test/woocommerce_shop_page_display' ) ); $data = $response->get_data(); $this->assertEquals( '', $data['value'] ); - // test updating shop display setting + // test updating shop display setting. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); $request->set_body_params( array( @@ -252,12 +255,12 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_update_settings() { wp_set_current_user( $this->user ); - // test defaults first + // test defaults first. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( '', $data[0]['value'] ); - // test setting both at once + // test setting both at once. $request = new WP_REST_Request( 'POST', '/wc/v2/settings/test/batch' ); $request->set_body_params( array( @@ -275,7 +278,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $this->assertEquals( 'both', $data['update'][0]['value'] ); $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - // test updating one, but making sure the other value stays the same + // test updating one, but making sure the other value stays the same. $request = new WP_REST_Request( 'POST', '/wc/v2/settings/test/batch' ); $request->set_body_params( array( @@ -301,17 +304,17 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_get_setting() { wp_set_current_user( $this->user ); - // test getting an invalid setting from a group that does not exist + // test getting an invalid setting from a group that does not exist. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/not-real/woocommerce_shop_page_display' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); - // test getting an invalid setting from a group that does exist + // test getting an invalid setting from a group that does exist. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/invalid/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); - // test getting a valid setting + // test getting a valid setting. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/test/woocommerce_shop_page_display' ) ); $data = $response->get_data(); @@ -451,7 +454,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_classic_settings() { wp_set_current_user( $this->user ); - // Make sure the group is properly registered + // Make sure the group is properly registered. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/products' ) ); $data = $response->get_data(); $this->assertTrue( is_array( $data ) ); @@ -480,13 +483,13 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $data ); - // test get single + // test get single. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/products/woocommerce_dimension_unit' ) ); $data = $response->get_data(); $this->assertEquals( 'cm', $data['default'] ); - // test update + // test update. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); $request->set_body_params( array( @@ -538,7 +541,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $settings ); - // test get single + // test get single. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/email_new_order/subject' ) ); $setting = $response->get_data(); @@ -555,7 +558,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $setting ); - // test update + // test update. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_new_order', 'subject' ) ); $request->set_body_params( array( @@ -578,14 +581,14 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $setting ); - // test updating another subject and making sure it works with a "similar" id + // test updating another subject and making sure it works with a "similar" id. $request = new WP_REST_Request( 'GET', sprintf( '/wc/v2/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); $response = $this->server->dispatch( $request ); $setting = $response->get_data(); $this->assertEmpty( $setting['value'] ); - // test update + // test update. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); $request->set_body_params( array( @@ -597,7 +600,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $this->assertEquals( 'This is my new subject', $setting['value'] ); - // make sure the other is what we left it + // make sure the other is what we left it. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/email_new_order/subject' ) ); $setting = $response->get_data(); @@ -612,7 +615,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_validation_checkbox() { wp_set_current_user( $this->user ); - // test bogus value + // test bogus value. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); $request->set_body_params( array( @@ -622,7 +625,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $this->assertEquals( 400, $response->get_status() ); - // test yes + // test yes. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); $request->set_body_params( array( @@ -632,7 +635,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); - // test no + // test no. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); $request->set_body_params( array( @@ -651,7 +654,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { public function test_validation_radio() { wp_set_current_user( $this->user ); - // not a valid option + // not a valid option. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); $request->set_body_params( array( @@ -661,7 +664,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $this->assertEquals( 400, $response->get_status() ); - // valid + // valid. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); $request->set_body_params( array( @@ -707,21 +710,21 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( 'kg', $setting['value'] ); - // invalid + // invalid. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); $request->set_body_params( array( - 'value' => 'pounds', // invalid, should be lbs + 'value' => 'pounds', // invalid, should be lbs. ) ); $response = $this->server->dispatch( $request ); $this->assertEquals( 400, $response->get_status() ); - // valid + // valid. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v2/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); $request->set_body_params( array( - 'value' => 'lbs', // invalid, should be lbs + 'value' => 'lbs', // invalid, should be lbs. ) ); $response = $this->server->dispatch( $request ); @@ -753,11 +756,13 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { */ public function test_woocommerce_store_address() { wp_set_current_user( $this->user ); + update_option( 'woocommerce_store_address', rand( 1000, 9999 ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_address' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); - // Repalce the old value with something uniquely new + // Repalce the old value with something uniquely new. $old_value = $setting['value']; $new_value = $old_value . ' ' . rand( 1000, 9999 ); $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address' ); @@ -770,7 +775,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( $new_value, $setting['value'] ); - // Put the original value back + // Put the original value back. $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address' ); $request->set_body_params( array( @@ -789,11 +794,13 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { */ public function test_woocommerce_store_address_2() { wp_set_current_user( $this->user ); + update_option( 'woocommerce_store_address_2', rand( 1000, 9999 ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_address_2' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); - // Repalce the old value with something uniquely new + // Repalce the old value with something uniquely new. $old_value = $setting['value']; $new_value = $old_value . ' ' . rand( 1000, 9999 ); $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address_2' ); @@ -806,7 +813,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( $new_value, $setting['value'] ); - // Put the original value back + // Put the original value back. $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_address_2' ); $request->set_body_params( array( @@ -825,11 +832,13 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { */ public function test_woocommerce_store_city() { wp_set_current_user( $this->user ); + update_option( 'woocommerce_store_city', rand( 1000, 9999 ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_city' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); - // Repalce the old value with something uniquely new + // Repalce the old value with something uniquely new. $old_value = $setting['value']; $new_value = $old_value . ' ' . rand( 1000, 9999 ); $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_city' ); @@ -842,7 +851,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( $new_value, $setting['value'] ); - // Put the original value back + // Put the original value back. $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_city' ); $request->set_body_params( array( @@ -861,11 +870,13 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { */ public function test_woocommerce_store_postcode() { wp_set_current_user( $this->user ); + update_option( 'woocommerce_store_postcode', rand( 1000, 9999 ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v2/settings/general/woocommerce_store_postcode' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); - // Repalce the old value with something uniquely new + // Repalce the old value with something uniquely new. $old_value = $setting['value']; $new_value = $old_value . ' ' . rand( 1000, 9999 ); $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_postcode' ); @@ -878,7 +889,7 @@ class Settings_V2 extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( $new_value, $setting['value'] ); - // Put the original value back + // Put the original value back. $request = new WP_REST_Request( 'PUT', '/wc/v2/settings/general/woocommerce_store_postcode' ); $request->set_body_params( array( diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/settings.php b/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/settings.php index 4c764de1f6c..daf907a7d8a 100644 --- a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/settings.php +++ b/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/settings.php @@ -6,6 +6,9 @@ * @since 3.5.0 */ +/** + * Class Settings. + */ class Settings extends WC_REST_Unit_Test_Case { /** @@ -162,19 +165,19 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_get_group() { wp_set_current_user( $this->user ); - // test route callback receiving an empty group id + // test route callback receiving an empty group id. $result = $this->endpoint->get_group_settings( '' ); $this->assertWPError( $result ); - // test getting a group that does not exist + // test getting a group that does not exist. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/not-real' ) ); $this->assertEquals( 404, $response->get_status() ); - // test getting the 'invalid' group + // test getting the 'invalid' group. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/invalid' ) ); $this->assertEquals( 404, $response->get_status() ); - // test getting a valid group with settings attached to it + // test getting a valid group with settings attached to it. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( 1, count( $data ) ); @@ -202,12 +205,12 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_update_setting() { wp_set_current_user( $this->user ); - // test defaults first + // test defaults first. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test/woocommerce_shop_page_display' ) ); $data = $response->get_data(); $this->assertEquals( '', $data['value'] ); - // test updating shop display setting + // test updating shop display setting. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); $request->set_body_params( array( @@ -253,12 +256,12 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_update_settings() { wp_set_current_user( $this->user ); - // test defaults first + // test defaults first. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( '', $data[0]['value'] ); - // test setting both at once + // test setting both at once. $request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' ); $request->set_body_params( array( @@ -276,7 +279,7 @@ class Settings extends WC_REST_Unit_Test_Case { $this->assertEquals( 'both', $data['update'][0]['value'] ); $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - // test updating one, but making sure the other value stays the same + // test updating one, but making sure the other value stays the same. $request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' ); $request->set_body_params( array( @@ -302,17 +305,17 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_get_setting() { wp_set_current_user( $this->user ); - // test getting an invalid setting from a group that does not exist + // test getting an invalid setting from a group that does not exist. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/not-real/woocommerce_shop_page_display' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); - // test getting an invalid setting from a group that does exist + // test getting an invalid setting from a group that does exist. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/invalid/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); - // test getting a valid setting + // test getting a valid setting. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/test/woocommerce_shop_page_display' ) ); $data = $response->get_data(); @@ -452,7 +455,7 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_classic_settings() { wp_set_current_user( $this->user ); - // Make sure the group is properly registered + // Make sure the group is properly registered. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/products' ) ); $data = $response->get_data(); $this->assertTrue( is_array( $data ) ); @@ -481,13 +484,13 @@ class Settings extends WC_REST_Unit_Test_Case { $data ); - // test get single + // test get single. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/products/woocommerce_dimension_unit' ) ); $data = $response->get_data(); $this->assertEquals( 'cm', $data['default'] ); - // test update + // test update. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); $request->set_body_params( array( @@ -539,7 +542,7 @@ class Settings extends WC_REST_Unit_Test_Case { $settings ); - // test get single + // test get single. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/email_new_order/subject' ) ); $setting = $response->get_data(); @@ -557,7 +560,7 @@ class Settings extends WC_REST_Unit_Test_Case { $setting ); - // test update + // test update. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_new_order', 'subject' ) ); $request->set_body_params( array( @@ -581,14 +584,14 @@ class Settings extends WC_REST_Unit_Test_Case { $setting ); - // test updating another subject and making sure it works with a "similar" id + // test updating another subject and making sure it works with a "similar" id. $request = new WP_REST_Request( 'GET', sprintf( '/wc/v3/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); $response = $this->server->dispatch( $request ); $setting = $response->get_data(); $this->assertEmpty( $setting['value'] ); - // test update + // test update. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_customer_new_account', 'subject' ) ); $request->set_body_params( array( @@ -600,7 +603,7 @@ class Settings extends WC_REST_Unit_Test_Case { $this->assertEquals( 'This is my new subject', $setting['value'] ); - // make sure the other is what we left it + // make sure the other is what we left it. $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/email_new_order/subject' ) ); $setting = $response->get_data(); @@ -615,7 +618,7 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_validation_checkbox() { wp_set_current_user( $this->user ); - // test bogus value + // test bogus value. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); $request->set_body_params( array( @@ -625,7 +628,7 @@ class Settings extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $this->assertEquals( 400, $response->get_status() ); - // test yes + // test yes. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); $request->set_body_params( array( @@ -635,7 +638,7 @@ class Settings extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); - // test no + // test no. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'email_cancelled_order', 'enabled' ) ); $request->set_body_params( array( @@ -654,7 +657,7 @@ class Settings extends WC_REST_Unit_Test_Case { public function test_validation_radio() { wp_set_current_user( $this->user ); - // not a valid option + // not a valid option. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); $request->set_body_params( array( @@ -664,7 +667,7 @@ class Settings extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $this->assertEquals( 400, $response->get_status() ); - // valid + // valid. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'shipping', 'woocommerce_ship_to_destination' ) ); $request->set_body_params( array( @@ -710,21 +713,21 @@ class Settings extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( 'kg', $setting['value'] ); - // invalid + // invalid. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); $request->set_body_params( array( - 'value' => 'pounds', // invalid, should be lbs + 'value' => 'pounds', // invalid, should be lbs. ) ); $response = $this->server->dispatch( $request ); $this->assertEquals( 400, $response->get_status() ); - // valid + // valid. $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v3/settings/%s/%s', 'products', 'woocommerce_weight_unit' ) ); $request->set_body_params( array( - 'value' => 'lbs', // invalid, should be lbs + 'value' => 'lbs', // invalid, should be lbs. ) ); $response = $this->server->dispatch( $request ); @@ -756,11 +759,13 @@ class Settings extends WC_REST_Unit_Test_Case { */ public function test_woocommerce_store_address() { wp_set_current_user( $this->user ); + update_option( 'woocommerce_store_address', rand( 1000, 9999 ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_address' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); - // Repalce the old value with something uniquely new + // Repalce the old value with something uniquely new. $old_value = $setting['value']; $new_value = $old_value . ' ' . rand( 1000, 9999 ); $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address' ); @@ -773,7 +778,7 @@ class Settings extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( $new_value, $setting['value'] ); - // Put the original value back + // Put the original value back. $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address' ); $request->set_body_params( array( @@ -792,11 +797,13 @@ class Settings extends WC_REST_Unit_Test_Case { */ public function test_woocommerce_store_address_2() { wp_set_current_user( $this->user ); + update_option( 'woocommerce_store_address_2', rand( 1000, 9999 ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_address_2' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); - // Repalce the old value with something uniquely new + // Repalce the old value with something uniquely new. $old_value = $setting['value']; $new_value = $old_value . ' ' . rand( 1000, 9999 ); $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address_2' ); @@ -809,7 +816,7 @@ class Settings extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( $new_value, $setting['value'] ); - // Put the original value back + // Put the original value back. $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_address_2' ); $request->set_body_params( array( @@ -828,11 +835,13 @@ class Settings extends WC_REST_Unit_Test_Case { */ public function test_woocommerce_store_city() { wp_set_current_user( $this->user ); + update_option( 'woocommerce_store_city', rand( 1000, 9999 ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_city' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); - // Repalce the old value with something uniquely new + // Repalce the old value with something uniquely new. $old_value = $setting['value']; $new_value = $old_value . ' ' . rand( 1000, 9999 ); $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_city' ); @@ -845,7 +854,7 @@ class Settings extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( $new_value, $setting['value'] ); - // Put the original value back + // Put the original value back. $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_city' ); $request->set_body_params( array( @@ -864,11 +873,13 @@ class Settings extends WC_REST_Unit_Test_Case { */ public function test_woocommerce_store_postcode() { wp_set_current_user( $this->user ); + update_option( 'woocommerce_store_postcode', rand( 1000, 9999 ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/settings/general/woocommerce_store_postcode' ) ); $setting = $response->get_data(); $this->assertEquals( 'text', $setting['type'] ); - // Repalce the old value with something uniquely new + // Repalce the old value with something uniquely new. $old_value = $setting['value']; $new_value = $old_value . ' ' . rand( 1000, 9999 ); $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_postcode' ); @@ -881,7 +892,7 @@ class Settings extends WC_REST_Unit_Test_Case { $setting = $response->get_data(); $this->assertEquals( $new_value, $setting['value'] ); - // Put the original value back + // Put the original value back. $request = new WP_REST_Request( 'PUT', '/wc/v3/settings/general/woocommerce_store_postcode' ); $request->set_body_params( array( diff --git a/tests/legacy/unit-tests/packages/packages.php b/tests/legacy/unit-tests/packages/packages.php index 5f96037a8ff..b960122e78f 100644 --- a/tests/legacy/unit-tests/packages/packages.php +++ b/tests/legacy/unit-tests/packages/packages.php @@ -15,7 +15,6 @@ class WC_Tests_Packages extends WC_Unit_Test_Case { */ public function test_packages_exist() { $this->assertTrue( \Automattic\WooCommerce\Packages::package_exists( 'woocommerce-blocks' ) ); - $this->assertTrue( \Automattic\WooCommerce\Packages::package_exists( 'woocommerce-rest-api' ) ); $this->assertTrue( \Automattic\WooCommerce\Packages::package_exists( 'woocommerce-admin' ) ); } From 1d782f025e156d3b1d3e0dcc21099bbb31078d12 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 30 Jul 2020 00:10:14 +0530 Subject: [PATCH 429/440] Deprecate API Package class because its not a package anymore. --- includes/api/src/Package.php | 16 ++++++++++++++-- includes/api/src/Server.php | 27 ++++++++++++++++++--------- includes/class-wc-api.php | 12 ++++++++++-- includes/class-woocommerce.php | 2 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/includes/api/src/Package.php b/includes/api/src/Package.php index 1f2ba8b8f07..05cda53a193 100644 --- a/includes/api/src/Package.php +++ b/includes/api/src/Package.php @@ -1,5 +1,7 @@ init() */ public static function init() { + wc_deprecated_function( 'Automattic\WooCommerce\RestApi\Server::instance()->init()', '4.5.0' ); \Automattic\WooCommerce\RestApi\Server::instance()->init(); } /** * Return the version of the package. * + * @deprecated since 4.5.0. This tracks WooCommerce version now. * @return string */ public static function get_version() { - return self::VERSION; + wc_deprecated_function( 'WC()->version', '4.5.0' ); + return WC()->version; } /** * Return the path to the package. * + * @deprecated since 4.5.0. Directly call Automattic\WooCommerce\RestApi\Server::get_path() * @return string */ public static function get_path() { - return dirname( __DIR__ ); + wc_deprecated_function( 'Automattic\WooCommerce\RestApi\Server::get_path()', '4.5.0' ); + return \Automattic\WooCommerce\RestApi\Server::get_path(); } } diff --git a/includes/api/src/Server.php b/includes/api/src/Server.php index 1c589c0da75..4eb3384baa3 100644 --- a/includes/api/src/Server.php +++ b/includes/api/src/Server.php @@ -22,7 +22,7 @@ class Server { * * @var array */ - protected $controllers = []; + protected $controllers = array(); /** * Hook into WordPress ready to init the REST API as needed. @@ -51,11 +51,11 @@ class Server { protected function get_rest_namespaces() { return apply_filters( 'woocommerce_rest_api_get_rest_namespaces', - [ + array( 'wc/v1' => $this->get_v1_controllers(), 'wc/v2' => $this->get_v2_controllers(), 'wc/v3' => $this->get_v3_controllers(), - ] + ) ); } @@ -65,7 +65,7 @@ class Server { * @return array */ protected function get_v1_controllers() { - return [ + return array( 'coupons' => 'WC_REST_Coupons_V1_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_V1_Controller', 'customers' => 'WC_REST_Customers_V1_Controller', @@ -86,7 +86,7 @@ class Server { 'taxes' => 'WC_REST_Taxes_V1_Controller', 'webhooks' => 'WC_REST_Webhooks_V1_Controller', 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V1_Controller', - ]; + ); } /** @@ -95,7 +95,7 @@ class Server { * @return array */ protected function get_v2_controllers() { - return [ + return array( 'coupons' => 'WC_REST_Coupons_V2_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_V2_Controller', 'customers' => 'WC_REST_Customers_V2_Controller', @@ -127,7 +127,7 @@ class Server { 'system-status-tools' => 'WC_REST_System_Status_Tools_V2_Controller', 'shipping-methods' => 'WC_REST_Shipping_Methods_V2_Controller', 'payment-gateways' => 'WC_REST_Payment_Gateways_V2_Controller', - ]; + ); } /** @@ -136,7 +136,7 @@ class Server { * @return array */ protected function get_v3_controllers() { - return [ + return array( 'coupons' => 'WC_REST_Coupons_Controller', 'customer-downloads' => 'WC_REST_Customer_Downloads_Controller', 'customers' => 'WC_REST_Customers_Controller', @@ -176,6 +176,15 @@ class Server { 'data-continents' => 'WC_REST_Data_Continents_Controller', 'data-countries' => 'WC_REST_Data_Countries_Controller', 'data-currencies' => 'WC_REST_Data_Currencies_Controller', - ]; + ); + } + + /** + * Return the path to the package. + * + * @return string + */ + public static function get_path() { + return dirname( __DIR__ ); } } diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 629e82feec1..5347b5f7499 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -39,6 +39,14 @@ class WC_API extends WC_Legacy_API { if ( ! $this->is_rest_api_loaded() ) { return null; } + if ( method_exists( \Automattic\WooCommerce\RestApi\Server::class, 'get_path' ) ) { + $path = \Automattic\WooCommerce\RestApi\Server::get_path(); + if ( 0 === strpos( $path, __DIR__ ) ) { + // We are loading API from included version. + return WC()->version; + } + } + // We are loading API from external plugin. return \Automattic\WooCommerce\RestApi\Package::get_version(); } @@ -52,7 +60,7 @@ class WC_API extends WC_Legacy_API { if ( ! $this->is_rest_api_loaded() ) { return null; } - return \Automattic\WooCommerce\RestApi\Package::get_path(); + return \Automattic\WooCommerce\RestApi\Server::get_path(); } /** @@ -62,7 +70,7 @@ class WC_API extends WC_Legacy_API { * @return boolean */ protected function is_rest_api_loaded() { - return class_exists( '\Automattic\WooCommerce\RestApi\Package', false ); + return class_exists( '\Automattic\WooCommerce\RestApi\Server', false ); } /** diff --git a/includes/class-woocommerce.php b/includes/class-woocommerce.php index 146376c31f2..9908924d103 100644 --- a/includes/class-woocommerce.php +++ b/includes/class-woocommerce.php @@ -303,7 +303,7 @@ final class WooCommerce { * Load REST API. */ public function load_rest_api() { - \Automattic\WooCommerce\RestApi\Package::init(); + \Automattic\WooCommerce\RestApi\Server::instance()->init(); } /** From 55a9687e6d14bacd32bdbd2d2c7e72645c48779a Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 30 Jul 2020 00:12:18 +0530 Subject: [PATCH 430/440] Make api included structure more linear. --- composer.json | 4 ++-- .../class-wc-rest-coupons-v1-controller.php | 0 ...ass-wc-rest-customer-downloads-v1-controller.php | 0 .../class-wc-rest-customers-v1-controller.php | 0 .../class-wc-rest-order-notes-v1-controller.php | 0 .../class-wc-rest-order-refunds-v1-controller.php | 0 .../Version1/class-wc-rest-orders-v1-controller.php | 0 ...c-rest-product-attribute-terms-v1-controller.php | 0 ...ass-wc-rest-product-attributes-v1-controller.php | 0 ...ass-wc-rest-product-categories-v1-controller.php | 0 .../class-wc-rest-product-reviews-v1-controller.php | 0 ...-rest-product-shipping-classes-v1-controller.php | 0 .../class-wc-rest-product-tags-v1-controller.php | 0 .../class-wc-rest-products-v1-controller.php | 0 .../class-wc-rest-report-sales-v1-controller.php | 0 ...ass-wc-rest-report-top-sellers-v1-controller.php | 0 .../class-wc-rest-reports-v1-controller.php | 0 .../class-wc-rest-tax-classes-v1-controller.php | 0 .../Version1/class-wc-rest-taxes-v1-controller.php | 0 ...ass-wc-rest-webhook-deliveries-v1-controller.php | 0 .../class-wc-rest-webhooks-v1-controller.php | 0 .../class-wc-rest-coupons-v2-controller.php | 0 ...ass-wc-rest-customer-downloads-v2-controller.php | 0 .../class-wc-rest-customers-v2-controller.php | 0 .../class-wc-rest-network-orders-v2-controller.php | 0 .../class-wc-rest-order-notes-v2-controller.php | 0 .../class-wc-rest-order-refunds-v2-controller.php | 0 .../Version2/class-wc-rest-orders-v2-controller.php | 0 ...class-wc-rest-payment-gateways-v2-controller.php | 0 ...c-rest-product-attribute-terms-v2-controller.php | 0 ...ass-wc-rest-product-attributes-v2-controller.php | 0 ...ass-wc-rest-product-categories-v2-controller.php | 0 .../class-wc-rest-product-reviews-v2-controller.php | 0 ...-rest-product-shipping-classes-v2-controller.php | 0 .../class-wc-rest-product-tags-v2-controller.php | 0 ...ass-wc-rest-product-variations-v2-controller.php | 0 .../class-wc-rest-products-v2-controller.php | 0 .../class-wc-rest-report-sales-v2-controller.php | 0 ...ass-wc-rest-report-top-sellers-v2-controller.php | 0 .../class-wc-rest-reports-v2-controller.php | 0 .../class-wc-rest-setting-options-v2-controller.php | 0 .../class-wc-rest-settings-v2-controller.php | 0 ...class-wc-rest-shipping-methods-v2-controller.php | 0 ...c-rest-shipping-zone-locations-v2-controller.php | 0 ...-wc-rest-shipping-zone-methods-v2-controller.php | 0 .../class-wc-rest-shipping-zones-v2-controller.php | 0 ...ss-wc-rest-system-status-tools-v2-controller.php | 0 .../class-wc-rest-system-status-v2-controller.php | 0 .../class-wc-rest-tax-classes-v2-controller.php | 0 .../Version2/class-wc-rest-taxes-v2-controller.php | 0 ...ass-wc-rest-webhook-deliveries-v2-controller.php | 0 .../class-wc-rest-webhooks-v2-controller.php | 0 .../Version3/class-wc-rest-controller.php | 0 .../Version3/class-wc-rest-coupons-controller.php | 0 .../Version3/class-wc-rest-crud-controller.php | 0 .../class-wc-rest-customer-downloads-controller.php | 0 .../Version3/class-wc-rest-customers-controller.php | 0 .../class-wc-rest-data-continents-controller.php | 0 .../Version3/class-wc-rest-data-controller.php | 0 .../class-wc-rest-data-countries-controller.php | 0 .../class-wc-rest-data-currencies-controller.php | 0 .../class-wc-rest-network-orders-controller.php | 0 .../class-wc-rest-order-notes-controller.php | 0 .../class-wc-rest-order-refunds-controller.php | 0 .../Version3/class-wc-rest-orders-controller.php | 0 .../class-wc-rest-payment-gateways-controller.php | 0 .../Version3/class-wc-rest-posts-controller.php | 0 ...s-wc-rest-product-attribute-terms-controller.php | 0 .../class-wc-rest-product-attributes-controller.php | 0 .../class-wc-rest-product-categories-controller.php | 0 .../class-wc-rest-product-reviews-controller.php | 0 ...-wc-rest-product-shipping-classes-controller.php | 0 .../class-wc-rest-product-tags-controller.php | 0 .../class-wc-rest-product-variations-controller.php | 0 .../Version3/class-wc-rest-products-controller.php | 0 ...ass-wc-rest-report-coupons-totals-controller.php | 0 ...s-wc-rest-report-customers-totals-controller.php | 0 ...lass-wc-rest-report-orders-totals-controller.php | 0 ...ss-wc-rest-report-products-totals-controller.php | 0 ...ass-wc-rest-report-reviews-totals-controller.php | 0 .../class-wc-rest-report-sales-controller.php | 0 .../class-wc-rest-report-top-sellers-controller.php | 0 .../Version3/class-wc-rest-reports-controller.php | 0 .../class-wc-rest-setting-options-controller.php | 0 .../Version3/class-wc-rest-settings-controller.php | 0 .../class-wc-rest-shipping-methods-controller.php | 0 ...s-wc-rest-shipping-zone-locations-controller.php | 0 ...ass-wc-rest-shipping-zone-methods-controller.php | 0 ...class-wc-rest-shipping-zones-controller-base.php | 0 .../class-wc-rest-shipping-zones-controller.php | 0 .../class-wc-rest-system-status-controller.php | 0 ...class-wc-rest-system-status-tools-controller.php | 0 .../class-wc-rest-tax-classes-controller.php | 0 .../Version3/class-wc-rest-taxes-controller.php | 0 .../Version3/class-wc-rest-terms-controller.php | 0 .../Version3/class-wc-rest-webhooks-controller.php | 0 includes/{api/src => rest-api}/Package.php | 0 includes/{api/src => rest-api}/Server.php | 0 .../src => rest-api}/Utilities/ImageAttachment.php | 0 .../src => rest-api}/Utilities/SingletonTrait.php | 0 .../unit-tests => rest-api}/AbstractRestApiTest.php | 0 .../Helpers/AdminNotesHelper.php | 0 .../Helpers/CouponHelper.php | 0 .../Helpers/CustomerHelper.php | 0 .../unit-tests => rest-api}/Helpers/OrderHelper.php | 0 .../Helpers/ProductHelper.php | 0 .../unit-tests => rest-api}/Helpers/QueueHelper.php | 0 .../Helpers/SettingsHelper.php | 0 .../Helpers/ShippingHelper.php | 0 .../Tests/Version2/coupons.php | 0 .../Tests/Version2/customers.php | 0 .../Tests/Version2/orders.php | 0 .../Tests/Version2/payment-gateways.php | 0 .../Tests/Version2/product-reviews.php | 0 .../Tests/Version2/product-variations.php | 0 .../Tests/Version2/products.php | 0 .../Tests/Version2/settings.php | 0 .../Tests/Version2/shipping-methods.php | 0 .../Tests/Version2/shipping-zones.php | 0 .../Tests/Version2/system-status.php | 0 .../Tests/Version3/coupons.php | 0 .../Tests/Version3/customers.php | 0 .../Tests/Version3/orders.php | 0 .../Tests/Version3/payment-gateways.php | 0 .../Tests/Version3/product-reviews.php | 0 .../Tests/Version3/product-variations.php | 0 .../Tests/Version3/products.php | 0 .../Tests/Version3/reports-coupons-totals.php | 0 .../Tests/Version3/reports-customers-totals.php | 0 .../Tests/Version3/reports-orders-totals.php | 0 .../Tests/Version3/reports-products-totals.php | 0 .../Tests/Version3/reports-reviews-totals.php | 0 .../Tests/Version3/settings.php | 0 .../Tests/Version3/shipping-methods.php | 0 .../Tests/Version3/shipping-zones.php | 0 .../Tests/Version3/system-status.php | 0 .../unit-tests => rest-api}/data/Dr1Bczxq4q.png | Bin .../{api/unit-tests => rest-api}/data/file.txt | 0 138 files changed, 2 insertions(+), 2 deletions(-) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-coupons-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-customers-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-orders-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-products-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-reports-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-taxes-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-coupons-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-customers-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-orders-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-products-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-reports-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-settings-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-system-status-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-taxes-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-coupons-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-crud-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-customer-downloads-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-customers-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-data-continents-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-data-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-data-countries-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-data-currencies-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-network-orders-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-order-notes-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-order-refunds-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-orders-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-payment-gateways-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-posts-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-product-attributes-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-product-categories-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-product-reviews-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-product-tags-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-product-variations-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-products-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-report-products-totals-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-report-sales-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-reports-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-setting-options-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-settings-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-shipping-methods-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-shipping-zones-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-system-status-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-system-status-tools-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-tax-classes-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-taxes-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-terms-controller.php (100%) rename includes/{api/src => rest-api}/Controllers/Version3/class-wc-rest-webhooks-controller.php (100%) rename includes/{api/src => rest-api}/Package.php (100%) rename includes/{api/src => rest-api}/Server.php (100%) rename includes/{api/src => rest-api}/Utilities/ImageAttachment.php (100%) rename includes/{api/src => rest-api}/Utilities/SingletonTrait.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/AbstractRestApiTest.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Helpers/AdminNotesHelper.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Helpers/CouponHelper.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Helpers/CustomerHelper.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Helpers/OrderHelper.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Helpers/ProductHelper.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Helpers/QueueHelper.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Helpers/SettingsHelper.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Helpers/ShippingHelper.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/coupons.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/customers.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/orders.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/payment-gateways.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/product-reviews.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/product-variations.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/products.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/settings.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/shipping-methods.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/shipping-zones.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version2/system-status.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/coupons.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/customers.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/orders.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/payment-gateways.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/product-reviews.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/product-variations.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/products.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/reports-coupons-totals.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/reports-customers-totals.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/reports-orders-totals.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/reports-products-totals.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/reports-reviews-totals.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/settings.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/shipping-methods.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/shipping-zones.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/Tests/Version3/system-status.php (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/data/Dr1Bczxq4q.png (100%) rename tests/legacy/unit-tests/{api/unit-tests => rest-api}/data/file.txt (100%) diff --git a/composer.json b/composer.json index a2534abe158..b870e932ddc 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "includes/libraries" ], "classmap": [ - "includes/api" + "includes/rest-api" ], "psr-4": { "Automattic\\WooCommerce\\": "src/" @@ -52,7 +52,7 @@ "Automattic\\WooCommerce\\Testing\\Tools\\": "tests/Tools/" }, "classmap": [ - "tests/legacy/unit-tests/api/unit-tests/Helpers" + "tests/legacy/unit-tests/rest-api/Helpers" ] }, "scripts": { diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-coupons-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-customers-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-orders-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-products-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-products-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-reports-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-taxes-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php diff --git a/includes/api/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php similarity index 100% rename from includes/api/src/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php rename to includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-coupons-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-customers-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-orders-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-products-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-products-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-reports-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-reports-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-reports-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-settings-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-system-status-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-taxes-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php diff --git a/includes/api/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php similarity index 100% rename from includes/api/src/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php rename to includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-coupons-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-coupons-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-coupons-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-coupons-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-crud-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-crud-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-customer-downloads-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-customer-downloads-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-customer-downloads-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-customers-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-customers-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-data-continents-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-data-continents-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-data-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-data-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-data-countries-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-data-countries-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-data-currencies-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-network-orders-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-network-orders-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-network-orders-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-network-orders-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-order-notes-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-order-notes-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-order-refunds-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-orders-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-orders-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-payment-gateways-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-posts-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-posts-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-attributes-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-product-attributes-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-product-attributes-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-product-categories-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-product-categories-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-product-reviews-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-product-tags-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-tags-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-product-tags-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-product-tags-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-product-variations-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-product-variations-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-products-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-products-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-report-products-totals-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-report-sales-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-report-sales-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-reports-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-reports-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-setting-options-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-setting-options-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-settings-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-settings-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-shipping-methods-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php b/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-shipping-zones-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-system-status-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-system-status-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-system-status-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-tools-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-system-status-tools-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-system-status-tools-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-tax-classes-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-tax-classes-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-tax-classes-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-taxes-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-taxes-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-taxes-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-taxes-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-terms-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-terms-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php diff --git a/includes/api/src/Controllers/Version3/class-wc-rest-webhooks-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php similarity index 100% rename from includes/api/src/Controllers/Version3/class-wc-rest-webhooks-controller.php rename to includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php diff --git a/includes/api/src/Package.php b/includes/rest-api/Package.php similarity index 100% rename from includes/api/src/Package.php rename to includes/rest-api/Package.php diff --git a/includes/api/src/Server.php b/includes/rest-api/Server.php similarity index 100% rename from includes/api/src/Server.php rename to includes/rest-api/Server.php diff --git a/includes/api/src/Utilities/ImageAttachment.php b/includes/rest-api/Utilities/ImageAttachment.php similarity index 100% rename from includes/api/src/Utilities/ImageAttachment.php rename to includes/rest-api/Utilities/ImageAttachment.php diff --git a/includes/api/src/Utilities/SingletonTrait.php b/includes/rest-api/Utilities/SingletonTrait.php similarity index 100% rename from includes/api/src/Utilities/SingletonTrait.php rename to includes/rest-api/Utilities/SingletonTrait.php diff --git a/tests/legacy/unit-tests/api/unit-tests/AbstractRestApiTest.php b/tests/legacy/unit-tests/rest-api/AbstractRestApiTest.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/AbstractRestApiTest.php rename to tests/legacy/unit-tests/rest-api/AbstractRestApiTest.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Helpers/AdminNotesHelper.php b/tests/legacy/unit-tests/rest-api/Helpers/AdminNotesHelper.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Helpers/AdminNotesHelper.php rename to tests/legacy/unit-tests/rest-api/Helpers/AdminNotesHelper.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Helpers/CouponHelper.php b/tests/legacy/unit-tests/rest-api/Helpers/CouponHelper.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Helpers/CouponHelper.php rename to tests/legacy/unit-tests/rest-api/Helpers/CouponHelper.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Helpers/CustomerHelper.php b/tests/legacy/unit-tests/rest-api/Helpers/CustomerHelper.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Helpers/CustomerHelper.php rename to tests/legacy/unit-tests/rest-api/Helpers/CustomerHelper.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Helpers/OrderHelper.php b/tests/legacy/unit-tests/rest-api/Helpers/OrderHelper.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Helpers/OrderHelper.php rename to tests/legacy/unit-tests/rest-api/Helpers/OrderHelper.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Helpers/ProductHelper.php b/tests/legacy/unit-tests/rest-api/Helpers/ProductHelper.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Helpers/ProductHelper.php rename to tests/legacy/unit-tests/rest-api/Helpers/ProductHelper.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Helpers/QueueHelper.php b/tests/legacy/unit-tests/rest-api/Helpers/QueueHelper.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Helpers/QueueHelper.php rename to tests/legacy/unit-tests/rest-api/Helpers/QueueHelper.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Helpers/SettingsHelper.php b/tests/legacy/unit-tests/rest-api/Helpers/SettingsHelper.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Helpers/SettingsHelper.php rename to tests/legacy/unit-tests/rest-api/Helpers/SettingsHelper.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Helpers/ShippingHelper.php b/tests/legacy/unit-tests/rest-api/Helpers/ShippingHelper.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Helpers/ShippingHelper.php rename to tests/legacy/unit-tests/rest-api/Helpers/ShippingHelper.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/coupons.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/coupons.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/coupons.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/coupons.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/customers.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/customers.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/customers.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/customers.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/orders.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/orders.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/orders.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/orders.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/payment-gateways.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/payment-gateways.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/payment-gateways.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/payment-gateways.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/product-reviews.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/product-reviews.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/product-reviews.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/product-reviews.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/product-variations.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/product-variations.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/product-variations.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/product-variations.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/products.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/products.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/products.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/products.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/settings.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/settings.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/settings.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/settings.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/shipping-methods.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/shipping-methods.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/shipping-methods.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/shipping-methods.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/shipping-zones.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/shipping-zones.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/shipping-zones.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/shipping-zones.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version2/system-status.php b/tests/legacy/unit-tests/rest-api/Tests/Version2/system-status.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version2/system-status.php rename to tests/legacy/unit-tests/rest-api/Tests/Version2/system-status.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/coupons.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/coupons.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/coupons.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/coupons.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/customers.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/customers.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/customers.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/customers.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/orders.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/orders.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/orders.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/orders.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/payment-gateways.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/payment-gateways.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/payment-gateways.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/payment-gateways.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/product-reviews.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/product-reviews.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/product-reviews.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/product-reviews.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/product-variations.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/product-variations.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/product-variations.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/product-variations.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/products.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/products.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/products.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/products.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-coupons-totals.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/reports-coupons-totals.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-coupons-totals.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/reports-coupons-totals.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-customers-totals.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/reports-customers-totals.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-customers-totals.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/reports-customers-totals.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-orders-totals.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/reports-orders-totals.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-orders-totals.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/reports-orders-totals.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-products-totals.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/reports-products-totals.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-products-totals.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/reports-products-totals.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-reviews-totals.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/reports-reviews-totals.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/reports-reviews-totals.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/reports-reviews-totals.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/settings.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/settings.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/settings.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/settings.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/shipping-methods.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/shipping-methods.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/shipping-methods.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/shipping-methods.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/shipping-zones.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/shipping-zones.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/shipping-zones.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/shipping-zones.php diff --git a/tests/legacy/unit-tests/api/unit-tests/Tests/Version3/system-status.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/system-status.php similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/Tests/Version3/system-status.php rename to tests/legacy/unit-tests/rest-api/Tests/Version3/system-status.php diff --git a/tests/legacy/unit-tests/api/unit-tests/data/Dr1Bczxq4q.png b/tests/legacy/unit-tests/rest-api/data/Dr1Bczxq4q.png similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/data/Dr1Bczxq4q.png rename to tests/legacy/unit-tests/rest-api/data/Dr1Bczxq4q.png diff --git a/tests/legacy/unit-tests/api/unit-tests/data/file.txt b/tests/legacy/unit-tests/rest-api/data/file.txt similarity index 100% rename from tests/legacy/unit-tests/api/unit-tests/data/file.txt rename to tests/legacy/unit-tests/rest-api/data/file.txt From 1526771eaa17d08bcdfbe2a6d5313fc5ea6713de Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 30 Jul 2020 19:47:29 +0530 Subject: [PATCH 431/440] Load from Server class if available --- includes/class-wc-api.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 5347b5f7499..dad7e3c7330 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -60,7 +60,12 @@ class WC_API extends WC_Legacy_API { if ( ! $this->is_rest_api_loaded() ) { return null; } - return \Automattic\WooCommerce\RestApi\Server::get_path(); + if ( method_exists( \Automattic\WooCommerce\RestApi\Server::class, 'get_path' ) ) { + // We are loading API from included version. + return \Automattic\WooCommerce\RestApi\Server::get_path(); + } + // We are loading API from external plugin. + return \Automattic\WooCommerce\RestApi\Package::get_path(); } /** From 2f76e52fa79ff91c3e46347e1f30c24a8cf5772e Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Wed, 5 Aug 2020 13:51:51 +0530 Subject: [PATCH 432/440] Skip test for < 5.3 as feature is not supported. --- .../unit-tests/rest-api/Tests/Version3/system-status.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/legacy/unit-tests/rest-api/Tests/Version3/system-status.php b/tests/legacy/unit-tests/rest-api/Tests/Version3/system-status.php index cdf30aedaef..7aa77fbde02 100644 --- a/tests/legacy/unit-tests/rest-api/Tests/Version3/system-status.php +++ b/tests/legacy/unit-tests/rest-api/Tests/Version3/system-status.php @@ -111,6 +111,10 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * the environment fields returned in the response. */ public function test_get_system_status_info_environment_filtered_by_field() { + if ( ! version_compare( get_bloginfo( 'version' ), '5.3', '>=' ) ) { + $this->markTestSkipped( 'Skipping because nested property support was introduced in 5.3.' ); + return; + } $expected_data = array( 'environment' => array( 'version' => WC()->version From cc96f6bbd19f3b007e1f8e01932bfc6846490b60 Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Wed, 5 Aug 2020 21:44:27 +0530 Subject: [PATCH 433/440] Fix compatibility for WP 5.5 --- .../class-wc-rest-coupons-v2-controller.php | 2 +- .../class-wc-rest-customers-v2-controller.php | 2 +- ...ss-wc-rest-order-refunds-v2-controller.php | 8 ++--- .../class-wc-rest-orders-v2-controller.php | 24 +++++++-------- ...-rest-product-variations-v2-controller.php | 4 +-- .../class-wc-rest-products-v2-controller.php | 2 +- ...-wc-rest-setting-options-v2-controller.php | 10 +++++-- .../Version3/class-wc-rest-controller.php | 29 +++++++++++++++++++ .../class-wc-rest-crud-controller.php | 2 ++ .../class-wc-rest-customers-controller.php | 2 +- ...-wc-rest-product-variations-controller.php | 2 +- .../class-wc-rest-products-controller.php | 2 +- ...ass-wc-rest-setting-options-controller.php | 10 +++++-- 13 files changed, 71 insertions(+), 28 deletions(-) diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php index 7dbcaa1c2ae..e8ab107a8e6 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php @@ -511,7 +511,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php index 29d4e07d2e2..22fb257e23d 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php @@ -350,7 +350,7 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php index dff06e2d063..c0b30dcba94 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php @@ -410,7 +410,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), @@ -432,13 +432,13 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), 'name' => array( 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'integer', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), @@ -535,7 +535,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php index a9422aec274..2744e42cae6 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -1170,7 +1170,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), @@ -1191,12 +1191,12 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'name' => array( 'description' => __( 'Product name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'product_id' => array( 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'integer' ), 'context' => array( 'view', 'edit' ), ), 'variation_id' => array( @@ -1282,7 +1282,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), @@ -1373,7 +1373,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), @@ -1397,12 +1397,12 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'method_title' => array( 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'method_id' => array( 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'instance_id' => array( @@ -1464,7 +1464,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), @@ -1488,7 +1488,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'name' => array( 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( @@ -1562,7 +1562,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), @@ -1586,7 +1586,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'code' => array( 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'discount' => array( @@ -1620,7 +1620,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php index 392098a7b94..4941870fb2e 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php @@ -799,7 +799,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), 'manage_stock' => array( 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'boolean', 'null' ), 'default' => false, 'context' => array( 'view', 'edit' ), ), @@ -982,7 +982,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php index f38ecb7dfb9..81554632935 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php @@ -2084,7 +2084,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php index 7c8a72a1220..e23aa3acc13 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php @@ -530,12 +530,18 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { ), 'value' => array( 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'array', 'null' ), + 'items' => array( + 'type' => array( 'string', 'null' ), + ), 'context' => array( 'view', 'edit' ), ), 'default' => array( 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'array', 'null' ), + 'items' => array( + 'type' => array( 'string', 'null' ), + ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php index 5ee0bc41122..d851be5adc8 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php @@ -77,6 +77,35 @@ abstract class WC_REST_Controller extends WP_REST_Controller { return $schema; } + /** + * Compatibility functions for WP 5.5, since custom types are not supported anymore. + * See @link https://core.trac.wordpress.org/changeset/48306 + * + * @param string $method Optional. HTTP method of the request. + * + * @return array Endpoint arguments. + */ + public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { + + $endpoint_args = parent::get_endpoint_args_for_item_schema( $method ); + + if ( false === strpos( WP_REST_Server::EDITABLE, $method ) ) { + return $endpoint_args; + } + + foreach ( $endpoint_args as $field_id => $params ) { + /** + * Custom types are not supported as of WP 5.5, this translates type => 'date-time' to type => 'string' with format date-time. + */ + if ( 'date-time' === $params['type'] ) { + $endpoint_args[ $field_id ]['type'] = 'string'; + $endpoint_args[ $field_id ]['format'] = 'date-time'; + } + } + + return $endpoint_args; + } + /** * Get normalized rest base. * diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php index c12186ed387..7aaa3af3e30 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php @@ -91,6 +91,8 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { return true; } + + /** * Get object permalink. * diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php index 65ce592cd55..072fb0893a5 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php @@ -293,7 +293,7 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php index 0477e818df9..6c710162e9b 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php @@ -736,7 +736,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php index a6401bf6d91..6f3d3a04024 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php @@ -1288,7 +1288,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), 'value' => array( 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php index b7255694912..59d3828e5e3 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php @@ -199,12 +199,18 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont ), 'value' => array( 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'array', 'null' ), + 'items' => array( + 'type' => array( 'string', 'null' ), + ), 'context' => array( 'view', 'edit' ), ), 'default' => array( 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), - 'type' => 'mixed', + 'type' => array( 'string', 'array', 'null' ), + 'items' => array( + 'type' => array( 'string', 'null' ), + ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), From 1966b0ba9a63186d1f60061db1ca51b2823f8e6d Mon Sep 17 00:00:00 2001 From: vedanshujain Date: Thu, 6 Aug 2020 18:18:18 +0530 Subject: [PATCH 434/440] Changed textdomain since API is merged into core now. --- .../class-wc-rest-coupons-v1-controller.php | 62 ++-- ...-rest-customer-downloads-v1-controller.php | 28 +- .../class-wc-rest-customers-v1-controller.php | 130 +++---- ...lass-wc-rest-order-notes-v1-controller.php | 46 +-- ...ss-wc-rest-order-refunds-v1-controller.php | 72 ++-- .../class-wc-rest-orders-v1-controller.php | 246 +++++++------- ...-product-attribute-terms-v1-controller.php | 24 +- ...-rest-product-attributes-v1-controller.php | 48 +-- ...-rest-product-categories-v1-controller.php | 30 +- ...-wc-rest-product-reviews-v1-controller.php | 64 ++-- ...product-shipping-classes-v1-controller.php | 10 +- ...ass-wc-rest-product-tags-v1-controller.php | 10 +- .../class-wc-rest-products-v1-controller.php | 320 +++++++++--------- ...ass-wc-rest-report-sales-v1-controller.php | 30 +- ...-rest-report-top-sellers-v1-controller.php | 6 +- .../class-wc-rest-reports-v1-controller.php | 10 +- ...lass-wc-rest-tax-classes-v1-controller.php | 20 +- .../class-wc-rest-taxes-v1-controller.php | 64 ++-- ...-rest-webhook-deliveries-v1-controller.php | 38 +-- .../class-wc-rest-webhooks-v1-controller.php | 84 ++--- .../class-wc-rest-coupons-v2-controller.php | 72 ++-- ...-rest-customer-downloads-v2-controller.php | 26 +- .../class-wc-rest-customers-v2-controller.php | 82 ++--- ...s-wc-rest-network-orders-v2-controller.php | 12 +- ...lass-wc-rest-order-notes-v2-controller.php | 14 +- ...ss-wc-rest-order-refunds-v2-controller.php | 84 ++--- .../class-wc-rest-orders-v2-controller.php | 292 ++++++++-------- ...wc-rest-payment-gateways-v2-controller.php | 46 +-- ...-rest-product-categories-v2-controller.php | 34 +- ...-wc-rest-product-reviews-v2-controller.php | 20 +- ...-rest-product-variations-v2-controller.php | 140 ++++---- .../class-wc-rest-products-v2-controller.php | 250 +++++++------- ...-wc-rest-setting-options-v2-controller.php | 40 +-- .../class-wc-rest-settings-v2-controller.php | 14 +- ...wc-rest-shipping-methods-v2-controller.php | 14 +- ...-shipping-zone-locations-v2-controller.php | 8 +- ...st-shipping-zone-methods-v2-controller.php | 56 +-- ...s-wc-rest-shipping-zones-v2-controller.php | 18 +- ...rest-system-status-tools-v2-controller.php | 158 ++++----- ...ss-wc-rest-system-status-v2-controller.php | 154 ++++----- ...-rest-webhook-deliveries-v2-controller.php | 24 +- .../class-wc-rest-webhooks-v2-controller.php | 28 +- .../Version3/class-wc-rest-controller.php | 16 +- .../class-wc-rest-crud-controller.php | 52 +-- .../class-wc-rest-customers-controller.php | 78 ++--- ...ass-wc-rest-data-continents-controller.php | 34 +- .../class-wc-rest-data-controller.php | 14 +- ...lass-wc-rest-data-countries-controller.php | 14 +- ...ass-wc-rest-data-currencies-controller.php | 10 +- .../class-wc-rest-order-notes-controller.php | 22 +- ...class-wc-rest-order-refunds-controller.php | 6 +- .../class-wc-rest-orders-controller.php | 6 +- ...ss-wc-rest-payment-gateways-controller.php | 34 +- .../class-wc-rest-posts-controller.php | 52 +-- ...-wc-rest-product-categories-controller.php | 34 +- ...ass-wc-rest-product-reviews-controller.php | 104 +++--- ...-wc-rest-product-variations-controller.php | 120 +++---- .../class-wc-rest-products-controller.php | 200 +++++------ ...-rest-report-coupons-totals-controller.php | 6 +- ...est-report-customers-totals-controller.php | 10 +- ...c-rest-report-orders-totals-controller.php | 6 +- ...rest-report-products-totals-controller.php | 6 +- ...-rest-report-reviews-totals-controller.php | 8 +- .../class-wc-rest-reports-controller.php | 16 +- ...ass-wc-rest-setting-options-controller.php | 24 +- .../class-wc-rest-settings-controller.php | 12 +- ...wc-rest-shipping-zones-controller-base.php | 18 +- .../class-wc-rest-terms-controller.php | 50 +-- .../rest-api/Utilities/ImageAttachment.php | 2 +- 69 files changed, 1941 insertions(+), 1941 deletions(-) diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php index 06ca52b6047..f9f312b6609 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php @@ -67,7 +67,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon code.', 'woocommerce' ), 'required' => true, 'type' => 'string', ), @@ -79,7 +79,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -105,7 +105,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -250,7 +250,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { // Validate required POST fields. if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { if ( empty( $request['code'] ) ) { - return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce-rest-api' ), 'code' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); } } @@ -266,7 +266,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); if ( $id_from_code ) { - return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); } $coupon->set_code( $coupon_code ); @@ -307,7 +307,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $coupon_id = $this->save_coupon( $request ); @@ -348,7 +348,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { $post_id = (int) $request['id']; if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } $coupon_id = $this->save_coupon( $request ); @@ -412,64 +412,64 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the object.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Coupon description.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'discount_type' => array( - 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce-rest-api' ), + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), 'type' => 'string', 'default' => 'fixed_cart', 'enum' => array_keys( wc_get_coupon_types() ), 'context' => array( 'view', 'edit' ), ), 'amount' => array( - 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce-rest-api' ), + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'expiry_date' => array( - 'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce-rest-api' ), + 'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'usage_count' => array( - 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'individual_use' => array( - 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce-rest-api' ), + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_ids' => array( - 'description' => __( "List of product IDs the coupon can be used on.", 'woocommerce-rest-api' ), + 'description' => __( "List of product IDs the coupon can be used on.", 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -477,7 +477,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'exclude_product_ids' => array( - 'description' => __( "List of product IDs the coupon cannot be used on.", 'woocommerce-rest-api' ), + 'description' => __( "List of product IDs the coupon cannot be used on.", 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -485,28 +485,28 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'usage_limit' => array( - 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce-rest-api' ), + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'usage_limit_per_user' => array( - 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce-rest-api' ), + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'limit_usage_to_x_items' => array( - 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce-rest-api' ), + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'free_shipping' => array( - 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce-rest-api' ), + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_categories' => array( - 'description' => __( "List of category IDs the coupon applies to.", 'woocommerce-rest-api' ), + 'description' => __( "List of category IDs the coupon applies to.", 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -514,7 +514,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'excluded_product_categories' => array( - 'description' => __( "List of category IDs the coupon does not apply to.", 'woocommerce-rest-api' ), + 'description' => __( "List of category IDs the coupon does not apply to.", 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -522,23 +522,23 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'exclude_sale_items' => array( - 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce-rest-api' ), + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'minimum_amount' => array( - 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce-rest-api' ), + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'maximum_amount' => array( - 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce-rest-api' ), + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email_restrictions' => array( - 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce-rest-api' ), + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -546,7 +546,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'used_by' => array( - 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce-rest-api' ), + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -569,7 +569,7 @@ class WC_REST_Coupons_V1_Controller extends WC_REST_Posts_Controller { $params = parent::get_collection_params(); $params['code'] = array( - 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php index 0d65f93dff9..0161f47a0df 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php @@ -43,7 +43,7 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'customer_id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -67,11 +67,11 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { $customer = get_user_by( 'id', (int) $request['customer_id'] ); if ( ! $customer ) { - return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_user_permissions( 'read', $customer->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -166,67 +166,67 @@ class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'download_url' => array( - 'description' => __( 'Download file URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Download file URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'download_id' => array( - 'description' => __( 'Download ID (MD5).', 'woocommerce-rest-api' ), + 'description' => __( 'Download ID (MD5).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Downloadable product ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Downloadable product ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'download_name' => array( - 'description' => __( 'Downloadable file name.', 'woocommerce-rest-api' ), + 'description' => __( 'Downloadable file name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Order ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), + 'description' => __( 'Order key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'downloads_remaining' => array( - 'description' => __( 'Number of downloads remaining.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'access_expires' => array( - 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File details.', 'woocommerce-rest-api' ), + 'description' => __( 'File details.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), + 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), + 'description' => __( 'File URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php index 8fc2687ca16..18b8d9786f6 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php @@ -55,16 +55,16 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'email' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'New user email address.', 'woocommerce-rest-api' ), + 'description' => __( 'New user email address.', 'woocommerce' ), ), 'username' => array( 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), - 'description' => __( 'New user username.', 'woocommerce-rest-api' ), + 'description' => __( 'New user username.', 'woocommerce' ), 'type' => 'string', ), 'password' => array( 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), - 'description' => __( 'New user password.', 'woocommerce-rest-api' ), + 'description' => __( 'New user password.', 'woocommerce' ), 'type' => 'string', ), ) ), @@ -75,7 +75,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -101,12 +101,12 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), 'reassign' => array( 'default' => 0, 'type' => 'integer', - 'description' => __( 'ID to reassign posts to.', 'woocommerce-rest-api' ), + 'description' => __( 'ID to reassign posts to.', 'woocommerce' ), ), ), ), @@ -132,7 +132,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -147,7 +147,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -163,7 +163,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'read', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -180,7 +180,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'edit', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -197,7 +197,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $id = (int) $request['id']; if ( ! wc_rest_check_user_permissions( 'delete', $id ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -212,7 +212,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_user_permissions( 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -324,7 +324,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { public function create_item( $request ) { try { if ( ! empty( $request['id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); } // Sets the username. @@ -342,7 +342,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $customer->save(); if ( ! $customer->get_id() ) { - throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); } $user_data = get_userdata( $customer->get_id() ); @@ -380,7 +380,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $user_data = get_userdata( $id ); if ( empty( $id ) || empty( $user_data->ID ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $customer = $this->prepare_item_for_response( $user_data, $request ); @@ -401,15 +401,15 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $customer = new WC_Customer( $id ); if ( ! $customer->get_id() ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); } if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->get_email() ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); } if ( ! empty( $request['username'] ) && $request['username'] !== $customer->get_username() ) { - throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); } // Customer email. @@ -463,17 +463,17 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $user_data = get_userdata( $id ); if ( ! $user_data ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); } if ( ! empty( $reassign ) ) { if ( $reassign === $id || ! get_userdata( $reassign ) ) { - return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -492,7 +492,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { } if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -629,31 +629,31 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), + 'description' => __( 'The email address for the customer.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer first name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -661,7 +661,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ), ), 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -669,7 +669,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ), ), 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer login name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -677,24 +677,24 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ), ), 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer password.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'last_order' => array( - 'description' => __( 'Last order data.', 'woocommerce-rest-api' ), + 'description' => __( 'Last order data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => array( 'id' => array( - 'description' => __( 'Last order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Last order ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date' => array( - 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -702,133 +702,133 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ), ), 'orders_count' => array( - 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce-rest-api' ), + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_spent' => array( - 'description' => __( 'Total amount spent.', 'woocommerce-rest-api' ), + 'description' => __( 'Total amount spent.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Avatar URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), + 'description' => __( 'List of billing address data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code of the country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), + 'description' => __( 'Email address.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), + 'description' => __( 'Phone number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), + 'description' => __( 'List of shipping address data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code of the country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -862,7 +862,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -871,7 +871,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -880,14 +880,14 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), + '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( 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), 'enum' => array( 'asc', 'desc' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', @@ -895,7 +895,7 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { ); $params['orderby'] = array( 'default' => 'name', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'enum' => array( 'id', 'include', @@ -907,13 +907,13 @@ class WC_REST_Customers_V1_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['email'] = array( - 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'validate_callback' => 'rest_validate_request_arg', ); $params['role'] = array( - 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce' ), 'type' => 'string', 'default' => 'customer', 'enum' => array_merge( array( 'all' ), $this->get_role_names() ), diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php index 785ff4627b4..731e5c9c4e6 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php @@ -50,7 +50,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'The order ID.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -67,7 +67,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'note' => array( 'type' => 'string', - 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), + 'description' => __( 'Order note content.', 'woocommerce' ), 'required' => true, ), ) ), @@ -78,11 +78,11 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'The order ID.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -102,7 +102,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -118,7 +118,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -133,7 +133,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -149,7 +149,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -166,7 +166,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -183,7 +183,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $args = array( @@ -217,20 +217,20 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } // Create the note. $note_id = $order->add_order_note( $request['note'], $request['customer_note'] ); if ( ! $note_id ) { - return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); } $note = get_comment( $note_id ); @@ -265,13 +265,13 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $order_note = $this->prepare_item_for_response( $note, $request ); @@ -292,19 +292,19 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); @@ -313,7 +313,7 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { $result = wc_delete_order_note( $note->comment_ID ); if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), 'order_note' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); } /** @@ -398,24 +398,24 @@ class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'note' => array( - 'description' => __( 'Order note.', 'woocommerce-rest-api' ), + 'description' => __( 'Order note.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_note' => array( - 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce-rest-api' ), + 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php index 659ffa844ae..d5a02e06ac0 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php @@ -58,7 +58,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'The order ID.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -80,11 +80,11 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'The order ID.', 'woocommerce' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -104,7 +104,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'force' => array( 'default' => true, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -124,13 +124,13 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); } $refund = wc_get_order( $post ); if ( ! $refund || $refund->get_parent_id() !== $order->get_id() ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce-rest-api' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); } $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); @@ -278,17 +278,17 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $order_data = get_post( (int) $request['order_id'] ); if ( empty( $order_data ) ) { - return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce-rest-api' ), 400 ); + return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); } if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); } // Create the refund. @@ -305,7 +305,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { } if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); } $post = get_post( $refund->get_id() ); @@ -341,29 +341,29 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'amount' => array( - 'description' => __( 'Refund amount.', 'woocommerce-rest-api' ), + 'description' => __( 'Refund amount.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'reason' => array( - 'description' => __( 'Reason for refund.', 'woocommerce-rest-api' ), + 'description' => __( 'Reason for refund.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), + 'description' => __( 'Line items data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -371,79 +371,79 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), + 'description' => __( 'Product SKU.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Product ID.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Quantity ordered.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class of product.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -451,19 +451,19 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax subtotal.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -472,7 +472,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { ), ), 'meta' => array( - 'description' => __( 'Line item meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Line item meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -480,19 +480,19 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { 'type' => 'object', 'properties' => array( 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Meta label.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta label.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -519,7 +519,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { $params['dp'] = array( 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php index 502bc2eeb29..52d4487a7bf 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php @@ -73,7 +73,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -99,7 +99,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -531,7 +531,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { try { // Make sure customer exists. if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] && false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce' ), 400 ); } // Make sure customer is part of blog. @@ -620,7 +620,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { } elseif ( 'update' === $action ) { $product_id = 0; } else { - throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); } return $product_id; } @@ -692,7 +692,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { if ( 'create' === $action ) { if ( empty( $posted['method_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); } } @@ -715,7 +715,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { if ( 'create' === $action ) { if ( empty( $posted['name'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); } } @@ -738,7 +738,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { if ( 'create' === $action ) { if ( empty( $posted['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); } } @@ -776,7 +776,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { absint( $order->get_id() ) ) ); if ( is_null( $result ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); } } @@ -825,7 +825,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $order_id = $this->create_order( $request ); @@ -864,7 +864,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { $post_id = (int) $request['id']; if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } $order_id = $this->update_order( $request ); @@ -918,236 +918,236 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'parent_id' => array( - 'description' => __( 'Parent order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Parent order ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Order status.', 'woocommerce-rest-api' ), + 'description' => __( 'Order status.', 'woocommerce' ), 'type' => 'string', 'default' => 'pending', 'enum' => $this->get_order_statuses(), 'context' => array( 'view', 'edit' ), ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), + 'description' => __( 'Order key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'number' => array( - 'description' => __( 'Order number.', 'woocommerce-rest-api' ), + 'description' => __( 'Order number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'currency' => array( - 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce-rest-api' ), + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), 'type' => 'string', 'default' => get_woocommerce_currency(), 'enum' => array_keys( get_woocommerce_currencies() ), 'context' => array( 'view', 'edit' ), ), 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce-rest-api' ), + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order was created, as GMT.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order was created, as GMT.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce-rest-api' ), + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), 'type' => 'integer', 'default' => 0, 'context' => array( 'view', 'edit' ), ), 'discount_total' => array( - 'description' => __( 'Total discount amount for the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_tax' => array( - 'description' => __( 'Total discount tax amount for the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_total' => array( - 'description' => __( 'Total shipping amount for the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax' => array( - 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_tax' => array( - 'description' => __( 'Sum of line item taxes only.', 'woocommerce-rest-api' ), + 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Grand total.', 'woocommerce-rest-api' ), + 'description' => __( 'Grand total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Sum of all taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Sum of all taxes.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'billing' => array( - 'description' => __( 'Billing address.', 'woocommerce-rest-api' ), + 'description' => __( 'Billing address.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), + 'description' => __( 'Email address.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), + 'description' => __( 'Phone number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'Shipping address.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping address.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1.', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2.', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'payment_method' => array( - 'description' => __( 'Payment method ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment method ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'payment_method_title' => array( - 'description' => __( 'Payment method title.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment method title.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -1155,131 +1155,131 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce-rest-api' ), + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'edit' ), ), 'transaction_id' => array( - 'description' => __( 'Unique transaction ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique transaction ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce-rest-api' ), + 'description' => __( "Customer's IP address.", 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce-rest-api' ), + 'description' => __( 'User agent of the customer.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows where the order was created.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce-rest-api' ), + 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_paid' => array( - 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_hash' => array( - 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce-rest-api' ), + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), + 'description' => __( 'Line items data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), + 'description' => __( 'Product SKU.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Product ID.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Quantity ordered.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class of product.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1287,19 +1287,19 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax subtotal.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1308,7 +1308,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'meta' => array( - 'description' => __( 'Line item meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Line item meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1316,19 +1316,19 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Meta label.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta label.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1340,7 +1340,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'tax_lines' => array( - 'description' => __( 'Tax lines data.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1348,43 +1348,43 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_code' => array( - 'description' => __( 'Tax rate code.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Tax rate label.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate label.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'compound' => array( - 'description' => __( 'Show if is a compound tax rate.', 'woocommerce-rest-api' ), + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_total' => array( - 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax_total' => array( - 'description' => __( 'Shipping tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1393,41 +1393,41 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'shipping_lines' => array( - 'description' => __( 'Shipping lines data.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_title' => array( - 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method name.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method ID.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1435,13 +1435,13 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1453,46 +1453,46 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'fee_lines' => array( - 'description' => __( 'Fee lines data.', 'woocommerce-rest-api' ), + 'description' => __( 'Fee lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), + 'description' => __( 'Fee name.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of fee.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class of fee.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status of fee.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax status of fee.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'taxable', 'none' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1500,19 +1500,19 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax subtotal.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1524,30 +1524,30 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'coupon_lines' => array( - 'description' => __( 'Coupons line data.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupons line data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon code.', 'woocommerce' ), 'type' => 'mixed', 'context' => array( 'view', 'edit' ), ), 'discount' => array( - 'description' => __( 'Discount total.', 'woocommerce-rest-api' ), + 'description' => __( 'Discount total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'discount_tax' => array( - 'description' => __( 'Discount total tax.', 'woocommerce-rest-api' ), + 'description' => __( 'Discount total tax.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1556,7 +1556,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { ), ), 'refunds' => array( - 'description' => __( 'List of refunds.', 'woocommerce-rest-api' ), + 'description' => __( 'List of refunds.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1564,19 +1564,19 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Refund ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Refund ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reason' => array( - 'description' => __( 'Refund reason.', 'woocommerce-rest-api' ), + 'description' => __( 'Refund reason.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Refund total.', 'woocommerce-rest-api' ), + 'description' => __( 'Refund total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1600,27 +1600,27 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), 'type' => 'string', 'enum' => array_merge( array( 'any' ), $this->get_order_statuses() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['customer'] = array( - 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['product'] = array( - 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['dp'] = array( 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php index 361febd1dcf..4d115f5ae2a 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php @@ -44,7 +44,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro array( 'args' => array( 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -61,7 +61,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'name' => array( 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Name for the resource.', 'woocommerce' ), 'required' => true, ), ) ), @@ -72,11 +72,11 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -102,7 +102,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -112,7 +112,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( 'args' => array( 'attribute_id' => array( - 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -193,13 +193,13 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Term name.', 'woocommerce-rest-api' ), + 'description' => __( 'Term name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -207,7 +207,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -215,7 +215,7 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -223,12 +223,12 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php index 88e67708da9..d655200d033 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php @@ -60,7 +60,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'name' => array( - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Name for the resource.', 'woocommerce' ), 'type' => 'string', 'required' => true, ), @@ -72,7 +72,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -98,7 +98,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => true, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -124,7 +124,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -138,7 +138,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -152,11 +152,11 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -170,11 +170,11 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function update_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -188,11 +188,11 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function delete_item_permissions_check( $request ) { if ( ! $this->get_taxonomy( $request ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -207,7 +207,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'attributes', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -360,7 +360,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $attribute = $this->get_attribute( (int) $request['id'] ); @@ -375,7 +375,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { $deleted = wc_delete_attribute( $attribute->attribute_id ); if ( false === $deleted ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -459,13 +459,13 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -473,7 +473,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -481,21 +481,21 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { ), ), 'type' => array( - 'description' => __( 'Type of attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'Type of attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'select', 'enum' => array_keys( wc_get_attribute_types() ), 'context' => array( 'view', 'edit' ), ), 'order_by' => array( - 'description' => __( 'Default sort order.', 'woocommerce-rest-api' ), + 'description' => __( 'Default sort order.', 'woocommerce' ), 'type' => 'string', 'default' => 'menu_order', 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ), 'context' => array( 'view', 'edit' ), ), 'has_archives' => array( - 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce-rest-api' ), + 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), @@ -554,7 +554,7 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { ", $id ) ); if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { - return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } return $attribute; @@ -570,11 +570,11 @@ class WC_REST_Product_Attributes_V1_Controller extends WC_REST_Controller { */ protected function validate_attribute_slug( $slug, $new_data = true ) { if ( strlen( $slug ) >= 28 ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { - return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce-rest-api' ), $slug ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); } return true; diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php index 956d5cd43b3..22d16a0d0bc 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php @@ -171,13 +171,13 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), + 'description' => __( 'Category name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -185,7 +185,7 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -193,12 +193,12 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller ), ), 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -206,59 +206,59 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller ), ), 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), + 'description' => __( 'Category archive display type.', 'woocommerce' ), 'type' => 'string', 'default' => 'default', 'enum' => array( 'default', 'products', 'subcategories', 'both' ), 'context' => array( 'view', 'edit' ), ), 'image' => array( - 'description' => __( 'Image data.', 'woocommerce-rest-api' ), + 'description' => __( 'Image data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'title' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php index e4d9b93075b..f52b7e098ab 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php @@ -43,11 +43,11 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -65,17 +65,17 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { 'review' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce-rest-api' ), + 'description' => __( 'Review content.', 'woocommerce' ), ), 'name' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce-rest-api' ), + 'description' => __( 'Name of the reviewer.', 'woocommerce' ), ), 'email' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce-rest-api' ), + 'description' => __( 'Email of the reviewer.', 'woocommerce' ), ), ) ), ), @@ -85,11 +85,11 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -115,7 +115,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -131,7 +131,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( 'product', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -147,7 +147,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $post = get_post( (int) $request['product_id'] ); if ( $post && ! wc_rest_check_post_permissions( 'product', 'read', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -162,7 +162,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { public function create_item_permissions_check( $request ) { $post = get_post( (int) $request['product_id'] ); if ( $post && ! wc_rest_check_post_permissions( 'product', 'create', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -176,7 +176,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { public function update_item_permissions_check( $request ) { $post = get_post( (int) $request['product_id'] ); if ( $post && ! wc_rest_check_post_permissions( 'product', 'edit', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -190,7 +190,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { public function delete_item_permissions_check( $request ) { $post = get_post( (int) $request['product_id'] ); if ( $post && ! wc_rest_check_post_permissions( 'product', 'delete', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -206,7 +206,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $reviews = get_approved_comments( $product_id ); @@ -231,13 +231,13 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $review = get_comment( $id ); if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $delivery = $this->prepare_item_for_response( $review, $request ); @@ -257,7 +257,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $prepared_review = $this->prepare_item_for_database( $request ); @@ -274,7 +274,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_review_id = wp_insert_comment( $prepared_review ); if ( ! $product_review_id ) { - return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); } update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); @@ -312,20 +312,20 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $review = get_comment( $product_review_id ); if ( empty( $product_review_id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $prepared_review = $this->prepare_item_for_database( $request ); $updated = wp_update_comment( $prepared_review ); if ( 0 === $updated ) { - return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); } if ( ! empty( $request['rating'] ) ) { @@ -363,7 +363,7 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $product_review = get_comment( $product_review_id ); if ( empty( $product_review_id ) || empty( $product_review->comment_ID ) || empty( $product_review->comment_post_ID ) ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce' ), array( 'status' => 404 ) ); } /** @@ -383,18 +383,18 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { $result = wp_delete_comment( $product_review_id, true ); } else { if ( ! $supports_trash ) { - return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } if ( 'trash' === $product_review->comment_approved ) { - return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce-rest-api' ), array( 'status' => 410 ) ); + return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); } $result = wp_trash_comment( $product_review->comment_ID ); } if ( ! $result ) { - return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -523,38 +523,38 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), + 'description' => __( 'The content of the review.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviewer name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviewer email.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php index 92ab292f1a0..fb2326df2dd 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php @@ -91,13 +91,13 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Shipping class name.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -105,7 +105,7 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -113,7 +113,7 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -121,7 +121,7 @@ class WC_REST_Product_Shipping_Classes_V1_Controller extends WC_REST_Terms_Contr ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php index c4e587b44da..a43ef8b43f6 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php @@ -91,13 +91,13 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -105,7 +105,7 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -113,7 +113,7 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -121,7 +121,7 @@ class WC_REST_Product_Tags_V1_Controller extends WC_REST_Terms_Controller { ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php index bf8629b027d..f0b6c7869c4 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php @@ -74,7 +74,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -99,7 +99,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'args' => array( 'force' => array( 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), 'type' => 'boolean', ), ), @@ -310,8 +310,8 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), // Default to now. 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), 'src' => wc_placeholder_img_src(), - 'name' => __( 'Placeholder', 'woocommerce-rest-api' ), - 'alt' => __( 'Placeholder', 'woocommerce-rest-api' ), + 'name' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), 'position' => 0, ); } @@ -736,7 +736,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $product_id = 0; @@ -781,7 +781,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $post_id = (int) $request['id']; if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } try { @@ -864,7 +864,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { } if ( ! wp_attachment_is_image( $attachment_id ) ) { - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); } if ( isset( $image['position'] ) && 0 === absint( $image['position'] ) ) { @@ -1369,7 +1369,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { // Create initial name and status. if ( ! $variation->get_slug() ) { /* translators: 1: variation id 2: product name */ - $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce-rest-api' ), $variation->get_id(), $product->get_name() ) ); + $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); } @@ -1634,9 +1634,9 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $product = wc_get_product( $id ); if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0; @@ -1653,7 +1653,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -1685,13 +1685,13 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( 'trash' === $post->post_status ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); } // (Note that internally this falls through to `wp_delete_post` if @@ -1702,7 +1702,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } // Delete parent product transients. @@ -1736,163 +1736,163 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Product slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Product URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Product type.', 'woocommerce-rest-api' ), + 'description' => __( 'Product type.', 'woocommerce' ), 'type' => 'string', 'default' => 'simple', 'enum' => array_keys( wc_get_product_types() ), 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), + 'description' => __( 'Product status (post status).', 'woocommerce' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), 'context' => array( 'view', 'edit' ), ), 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), + 'description' => __( 'Featured product.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), + 'description' => __( 'Catalog visibility.', 'woocommerce' ), 'type' => 'string', 'default' => 'visible', 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Product description.', 'woocommerce-rest-api' ), + 'description' => __( 'Product description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), + 'description' => __( 'Product short description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), + 'description' => __( 'Current product price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product regular price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( 'Start date of sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'Start date of sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( 'End date of sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'End date of sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of sales.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), + 'description' => __( 'If the product is virtual.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), + 'description' => __( 'List of downloadable files.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), + 'description' => __( 'File ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), + 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), + 'description' => __( 'File URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1900,163 +1900,163 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_type' => array( - 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce-rest-api' ), + 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce' ), 'type' => 'string', 'default' => 'standard', 'enum' => array( 'standard' ), 'context' => array( 'view', 'edit' ), ), 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax status.', 'woocommerce' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock management at product level.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock quantity.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'in_stock' => array( - 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), + 'description' => __( 'Product dimensions.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), + 'description' => __( 'Allow reviews.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviews average rating.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of related products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2065,7 +2065,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'readonly' => true, ), 'upsell_ids' => array( - 'description' => __( 'List of upsell products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of upsell products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2073,7 +2073,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2081,35 +2081,35 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Product parent ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), + 'description' => __( 'List of categories.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Category ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), + 'description' => __( 'Category name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Category slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -2118,25 +2118,25 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), + 'description' => __( 'List of tags.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -2145,47 +2145,47 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'images' => array( - 'description' => __( 'List of images.', 'woocommerce-rest-api' ), + 'description' => __( 'List of images.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), @@ -2193,41 +2193,41 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'List of attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute position.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), ), @@ -2235,24 +2235,24 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -2260,116 +2260,116 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'variations' => array( - 'description' => __( 'List of variations.', 'woocommerce-rest-api' ), + 'description' => __( 'List of variations.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Variation ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), + 'description' => __( 'Current variation price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation regular price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( 'Start date of sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'Start date of sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( 'End date of sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'End date of sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'visible' => array( - 'description' => __( 'If the variation is visible.', 'woocommerce-rest-api' ), + 'description' => __( 'If the variation is visible.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), + 'description' => __( 'List of downloadable files.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), + 'description' => __( 'File ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), + 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), + 'description' => __( 'File URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -2377,171 +2377,171 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), 'type' => 'integer', 'default' => null, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), 'type' => 'integer', 'default' => null, 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax status.', 'woocommerce' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock quantity.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'in_stock' => array( - 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation dimensions.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation image data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'List of attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -2552,7 +2552,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { ), ), 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2561,7 +2561,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { 'readonly' => true, ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), @@ -2580,57 +2580,57 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller { $params = parent::get_collection_params(); $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), 'type' => 'string', 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_types() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['sku'] = array( - 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php index 57bd5da4490..d880c86e7e5 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php @@ -66,7 +66,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -287,67 +287,67 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'total_sales' => array( - 'description' => __( 'Gross sales in the period.', 'woocommerce-rest-api' ), + 'description' => __( 'Gross sales in the period.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'net_sales' => array( - 'description' => __( 'Net sales in the period.', 'woocommerce-rest-api' ), + 'description' => __( 'Net sales in the period.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'average_sales' => array( - 'description' => __( 'Average net daily sales.', 'woocommerce-rest-api' ), + 'description' => __( 'Average net daily sales.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total_orders' => array( - 'description' => __( 'Total of orders placed.', 'woocommerce-rest-api' ), + 'description' => __( 'Total of orders placed.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'total_items' => array( - 'description' => __( 'Total of items purchased.', 'woocommerce-rest-api' ), + 'description' => __( 'Total of items purchased.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Total charged for taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Total charged for taxes.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total_shipping' => array( - 'description' => __( 'Total charged for shipping.', 'woocommerce-rest-api' ), + 'description' => __( 'Total charged for shipping.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total_refunds' => array( - 'description' => __( 'Total of refunded orders.', 'woocommerce-rest-api' ), + 'description' => __( 'Total of refunded orders.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'total_discount' => array( - 'description' => __( 'Total of coupons used.', 'woocommerce-rest-api' ), + 'description' => __( 'Total of coupons used.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'totals_grouped_by' => array( - 'description' => __( 'Group type.', 'woocommerce-rest-api' ), + 'description' => __( 'Group type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'totals' => array( - 'description' => __( 'Totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Totals.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'array', @@ -370,7 +370,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'period' => array( - 'description' => __( 'Report period.', 'woocommerce-rest-api' ), + 'description' => __( 'Report period.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'week', 'month', 'last_month', 'year' ), 'validate_callback' => 'rest_validate_request_arg', @@ -378,7 +378,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { ), 'date_min' => array( /* translators: %s: date format */ - 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce-rest-api' ), 'YYYY-MM-DD' ), + 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), 'type' => 'string', 'format' => 'date', 'validate_callback' => 'wc_rest_validate_reports_request_arg', @@ -386,7 +386,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller { ), 'date_max' => array( /* translators: %s: date format */ - 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce-rest-api' ), 'YYYY-MM-DD' ), + 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), 'type' => 'string', 'format' => 'date', 'validate_callback' => 'wc_rest_validate_reports_request_arg', diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php index 76d0aa9d2ae..22e928e05b8 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php @@ -149,19 +149,19 @@ class WC_REST_Report_Top_Sellers_V1_Controller extends WC_REST_Report_Sales_V1_C 'type' => 'object', 'properties' => array( 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Product ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'quantity' => array( - 'description' => __( 'Total number of purchases.', 'woocommerce-rest-api' ), + 'description' => __( 'Total number of purchases.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php index 1f1463ae2b5..c35b9e6329b 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php @@ -59,7 +59,7 @@ class WC_REST_Reports_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -75,11 +75,11 @@ class WC_REST_Reports_V1_Controller extends WC_REST_Controller { return array( array( 'slug' => 'sales', - 'description' => __( 'List of sales reports.', 'woocommerce-rest-api' ), + 'description' => __( 'List of sales reports.', 'woocommerce' ), ), array( 'slug' => 'top_sellers', - 'description' => __( 'List of top sellers products.', 'woocommerce-rest-api' ), + 'description' => __( 'List of top sellers products.', 'woocommerce' ), ), ); } @@ -154,13 +154,13 @@ class WC_REST_Reports_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human-readable description of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php index 5a7206fb6a6..b71cc27d75e 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php @@ -59,7 +59,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', array( 'args' => array( 'slug' => array( - 'description' => __( 'Unique slug for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), 'type' => 'string', ), ), @@ -71,7 +71,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -87,7 +87,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -102,7 +102,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -117,7 +117,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -135,7 +135,7 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { // Add standard class. $tax_classes[] = array( 'slug' => 'standard', - 'name' => __( 'Standard rate', 'woocommerce-rest-api' ), + 'name' => __( 'Standard rate', 'woocommerce' ), ); $classes = WC_Tax::get_tax_classes(); @@ -203,14 +203,14 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $tax_class = WC_Tax::get_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); $deleted = WC_Tax::delete_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); if ( ! $deleted ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); } if ( is_wp_error( $deleted ) ) { @@ -288,13 +288,13 @@ class WC_REST_Tax_Classes_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Tax class name.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'required' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php index ae81985a3d2..bbbc1869314 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php @@ -59,7 +59,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -85,7 +85,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -111,7 +111,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -126,7 +126,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -140,7 +140,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -155,7 +155,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -170,7 +170,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -185,7 +185,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -361,7 +361,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); } $tax = $this->create_or_update_tax( $request ); @@ -397,7 +397,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tax = $this->prepare_item_for_response( $tax_obj, $request ); @@ -417,7 +417,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tax = $this->create_or_update_tax( $request, $tax_obj ); @@ -454,13 +454,13 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $tax = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); } $request->set_param( 'context', 'edit' ); @@ -469,7 +469,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { WC_Tax::_delete_tax_rate( $id ); if ( 0 === $wpdb->rows_affected ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -573,66 +573,66 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'country' => array( - 'description' => __( 'Country ISO 3166 code.', 'woocommerce-rest-api' ), + 'description' => __( 'Country ISO 3166 code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'State code.', 'woocommerce-rest-api' ), + 'description' => __( 'State code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postcode / ZIP.', 'woocommerce-rest-api' ), + 'description' => __( 'Postcode / ZIP.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'rate' => array( - 'description' => __( 'Tax rate.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tax rate name.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'priority' => array( - 'description' => __( 'Tax priority.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax priority.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'context' => array( 'view', 'edit' ), ), 'compound' => array( - 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'shipping' => array( - 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'order' => array( - 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce-rest-api' ), + 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'default' => 'standard', 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), @@ -655,7 +655,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -663,7 +663,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-rest-api' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -672,14 +672,14 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), + '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( 'default' => 'asc', - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), 'enum' => array( 'asc', 'desc' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', @@ -687,7 +687,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { ); $params['orderby'] = array( 'default' => 'order', - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'enum' => array( 'id', 'order', @@ -697,7 +697,7 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['class'] = array( - 'description' => __( 'Sort by tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Sort by tax class.', 'woocommerce' ), 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), 'sanitize_callback' => 'sanitize_title', 'type' => 'string', diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php index adbd3f62b2f..033a2c797c8 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php @@ -44,7 +44,7 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'webhook_id' => array( - 'description' => __( 'Unique identifier for the webhook.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -60,11 +60,11 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'webhook_id' => array( - 'description' => __( 'Unique identifier for the webhook.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -88,7 +88,7 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -102,7 +102,7 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -119,7 +119,7 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { $webhook = wc_get_webhook( (int) $request['webhook_id'] ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $logs = array(); @@ -144,13 +144,13 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { $webhook = wc_get_webhook( (int) $request['webhook_id'] ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $log = array(); if ( empty( $id ) || empty( $log ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $delivery = $this->prepare_item_for_response( (object) $log, $request ); @@ -223,32 +223,32 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'duration' => array( - 'description' => __( 'The delivery duration, in seconds.', 'woocommerce-rest-api' ), + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'summary' => array( - 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce-rest-api' ), + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'request_url' => array( - 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce-rest-api' ), + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'request_headers' => array( - 'description' => __( 'Request headers.', 'woocommerce-rest-api' ), + 'description' => __( 'Request headers.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -257,25 +257,25 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { ), ), 'request_body' => array( - 'description' => __( 'Request body.', 'woocommerce-rest-api' ), + 'description' => __( 'Request body.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_code' => array( - 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce-rest-api' ), + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_message' => array( - 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce-rest-api' ), + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_headers' => array( - 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce-rest-api' ), + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -284,13 +284,13 @@ class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { ), ), 'response_body' => array( - 'description' => __( 'The response body from the receiving server.', 'woocommerce-rest-api' ), + 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php b/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php index d9f6c611c8a..9ad7e982b25 100644 --- a/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php +++ b/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php @@ -60,12 +60,12 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'topic' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook topic.', 'woocommerce' ), ), 'delivery_url' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Webhook delivery URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), ), ) ), ), @@ -75,7 +75,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -101,7 +101,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -127,7 +127,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -142,7 +142,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -156,7 +156,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -171,7 +171,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -186,7 +186,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function delete_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -201,7 +201,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'webhooks', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -297,7 +297,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { $id = (int) $request['id']; if ( empty( $id ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $id, $request ); @@ -315,17 +315,17 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } // Validate topic. if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); } // Validate delivery URL. if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -377,7 +377,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } // Update topic. @@ -385,7 +385,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { $webhook->set_topic( $request['topic'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -394,7 +394,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { if ( wc_is_valid_url( $request['delivery_url'] ) ) { $webhook->set_delivery_url( $request['delivery_url'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -408,7 +408,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { $webhook->set_status( $request['status'] ); } else { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -452,13 +452,13 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); @@ -467,7 +467,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -498,7 +498,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { // Validate required POST fields. if ( 'POST' === $request->get_method() && empty( $data->ID ) ) { - $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce-rest-api' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce-rest-api' ) ) ); // @codingStandardsIgnoreLine + $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ); // @codingStandardsIgnoreLine // Post author. $data->post_author = get_current_user_id(); @@ -546,7 +546,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } $data = array( @@ -612,42 +612,42 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ), + 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Webhook status.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook status.', 'woocommerce' ), 'type' => 'string', 'default' => 'active', 'enum' => array_keys( wc_get_webhook_statuses() ), 'context' => array( 'view', 'edit' ), ), 'topic' => array( - 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook topic.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'resource' => array( - 'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'event' => array( - 'description' => __( 'Webhook event.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook event.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hooks' => array( - 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ), + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -656,25 +656,25 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { ), ), 'delivery_url' => array( - 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ), + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'secret' => array( - 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ), + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -696,19 +696,19 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), + '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-rest-api' ), + '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['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -717,7 +717,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -726,20 +726,20 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), + '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-rest-api' ), + '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-rest-api' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -751,7 +751,7 @@ class WC_REST_Webhooks_V1_Controller extends WC_REST_Controller { ); $params['status'] = array( 'default' => 'all', - 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'all', 'active', 'paused', 'disabled' ), 'sanitize_callback' => 'sanitize_key', diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php index e8ab107a8e6..07bda40697c 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php @@ -58,7 +58,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon code.', 'woocommerce' ), 'required' => true, 'type' => 'string', ), @@ -73,7 +73,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -99,7 +99,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -268,7 +268,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { // Validate required POST fields. if ( $creating && empty( $request['code'] ) ) { - return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce-rest-api' ), 'code' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); } // Handle all writable props. @@ -283,7 +283,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); if ( $id_from_code ) { - return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); } $coupon->set_code( $coupon_code ); @@ -332,81 +332,81 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the object.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'amount' => array( - 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce-rest-api' ), + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_type' => array( - 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce-rest-api' ), + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), 'type' => 'string', 'default' => 'fixed_cart', 'enum' => array_keys( wc_get_coupon_types() ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Coupon description.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_expires' => array( - 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_expires_gmt' => array( - 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'usage_count' => array( - 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'individual_use' => array( - 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce-rest-api' ), + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_ids' => array( - 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce-rest-api' ), + 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -414,7 +414,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'excluded_product_ids' => array( - 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce-rest-api' ), + 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -422,28 +422,28 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'usage_limit' => array( - 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce-rest-api' ), + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'usage_limit_per_user' => array( - 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce-rest-api' ), + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'limit_usage_to_x_items' => array( - 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce-rest-api' ), + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'free_shipping' => array( - 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce-rest-api' ), + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'product_categories' => array( - 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce-rest-api' ), + 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -451,7 +451,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'excluded_product_categories' => array( - 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce-rest-api' ), + 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -459,23 +459,23 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'exclude_sale_items' => array( - 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce-rest-api' ), + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'minimum_amount' => array( - 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce-rest-api' ), + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'maximum_amount' => array( - 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce-rest-api' ), + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email_restrictions' => array( - 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce-rest-api' ), + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -483,7 +483,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'used_by' => array( - 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce-rest-api' ), + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -492,25 +492,25 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -531,7 +531,7 @@ class WC_REST_Coupons_V2_Controller extends WC_REST_CRUD_Controller { $params = parent::get_collection_params(); $params['code'] = array( - 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php index 1b7c0de9fd6..e403442f484 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php @@ -78,79 +78,79 @@ class WC_REST_Customer_Downloads_V2_Controller extends WC_REST_Customer_Download 'type' => 'object', 'properties' => array( 'download_id' => array( - 'description' => __( 'Download ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Download ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'download_url' => array( - 'description' => __( 'Download file URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Download file URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Downloadable product ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Downloadable product ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'product_name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'download_name' => array( - 'description' => __( 'Downloadable file name.', 'woocommerce-rest-api' ), + 'description' => __( 'Downloadable file name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'order_id' => array( - 'description' => __( 'Order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Order ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), + 'description' => __( 'Order key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'downloads_remaining' => array( - 'description' => __( 'Number of downloads remaining.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'access_expires' => array( - 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'access_expires_gmt' => array( - 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File details.', 'woocommerce-rest-api' ), + 'description' => __( 'File details.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), + 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), + 'description' => __( 'File URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php index 22fb257e23d..50fff8f641a 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php @@ -121,43 +121,43 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), + 'description' => __( 'The email address for the customer.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer first name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -165,7 +165,7 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { ), ), 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -173,13 +173,13 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { ), ), 'role' => array( - 'description' => __( 'Customer role.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer role.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer login name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -187,169 +187,169 @@ class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller { ), ), 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer password.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), + 'description' => __( 'List of billing address data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code of the country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), + 'description' => __( 'Email address.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), + 'description' => __( 'Phone number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), + 'description' => __( 'List of shipping address data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code of the country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'is_paying_customer' => array( - 'description' => __( 'Is the customer a paying customer?', 'woocommerce-rest-api' ), + 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), 'type' => 'bool', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'orders_count' => array( - 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce-rest-api' ), + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_spent' => array( - 'description' => __( 'Total amount spent.', 'woocommerce-rest-api' ), + 'description' => __( 'Total amount spent.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Avatar URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php index 357082d1b65..45d0f8b483d 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php @@ -55,31 +55,31 @@ class WC_REST_Network_Orders_V2_Controller extends WC_REST_Orders_V2_Controller $schema = parent::get_public_item_schema(); $schema['properties']['blog'] = array( - 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce-rest-api' ), + 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['edit_url'] = array( - 'description' => __( 'URL to edit the order', 'woocommerce-rest-api' ), + 'description' => __( 'URL to edit the order', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['customer'][] = array( - 'description' => __( 'Name of the customer for the order', 'woocommerce-rest-api' ), + 'description' => __( 'Name of the customer for the order', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['status_name'][] = array( - 'description' => __( 'Order Status', 'woocommerce-rest-api' ), + 'description' => __( 'Order Status', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ); $schema['properties']['formatted_total'][] = array( - 'description' => __( 'Order total formatted for locale', 'woocommerce-rest-api' ), + 'description' => __( 'Order total formatted for locale', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, @@ -146,7 +146,7 @@ class WC_REST_Network_Orders_V2_Controller extends WC_REST_Orders_V2_Controller $current_order['blog'] = get_blog_details( get_current_blog_id() ); $current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' ); /* translators: 1: first name 2: last name */ - $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce-rest-api' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); + $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); $current_order['status_name'] = wc_get_order_status_name( $order->get_status() ); $current_order['formatted_total'] = $order->get_formatted_order_total(); } diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php index 6ecd15e3165..f3d269c963f 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php @@ -36,7 +36,7 @@ class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controlle $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $args = array( @@ -126,30 +126,30 @@ class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controlle 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'note' => array( - 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), + 'description' => __( 'Order note content.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_note' => array( - 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce-rest-api' ), + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), @@ -170,7 +170,7 @@ class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controlle $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $params['type'] = array( 'default' => 'any', - 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce' ), 'type' => 'string', 'enum' => array( 'any', 'customer', 'internal' ), 'sanitize_callback' => 'sanitize_key', diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php index c0b30dcba94..dd7f2d3d3f6 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php @@ -61,7 +61,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'The order ID.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -85,11 +85,11 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'order_id' => array( - 'description' => __( 'The order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'The order ID.', 'woocommerce' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -109,7 +109,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'force' => array( 'default' => true, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -188,11 +188,11 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); } if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce-rest-api' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); } $data = $this->get_formatted_item_data( $object ); @@ -270,11 +270,11 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); } if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); } // Create the refund. @@ -293,7 +293,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { } if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); } if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { @@ -352,64 +352,64 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'amount' => array( - 'description' => __( 'Refund amount.', 'woocommerce-rest-api' ), + 'description' => __( 'Refund amount.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'reason' => array( - 'description' => __( 'Reason for refund.', 'woocommerce-rest-api' ), + 'description' => __( 'Reason for refund.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'refunded_by' => array( - 'description' => __( 'User ID of user who created the refund.', 'woocommerce-rest-api' ), + 'description' => __( 'User ID of user who created the refund.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'refunded_payment' => array( - 'description' => __( 'If the payment was refunded via the API.', 'woocommerce-rest-api' ), + 'description' => __( 'If the payment was refunded via the API.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -417,7 +417,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), + 'description' => __( 'Line items data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -425,67 +425,67 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Product ID.', 'woocommerce' ), 'type' => array( 'integer', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Quantity ordered.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class of product.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -493,19 +493,19 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax subtotal.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -514,7 +514,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -522,19 +522,19 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -543,13 +543,13 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), + 'description' => __( 'Product SKU.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product price.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -558,7 +558,7 @@ class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { ), ), 'api_refund' => array( - 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce-rest-api' ), + 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'default' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php index 2744e42cae6..75b366627de 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -83,7 +83,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -109,7 +109,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -529,7 +529,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { // Make sure customer exists. if ( false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); } // Make sure customer is part of blog. @@ -604,7 +604,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { } elseif ( 'update' === $action ) { $product_id = 0; } else { - throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); } return $product_id; } @@ -696,7 +696,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( 'create' === $action ) { if ( empty( $posted['method_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); } } @@ -720,7 +720,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( 'create' === $action ) { if ( empty( $posted['name'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); } } @@ -744,7 +744,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( 'create' === $action ) { if ( empty( $posted['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); } } @@ -781,7 +781,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { $item = $order->get_item( absint( $posted['id'] ), false ); if ( ! $item ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); } } @@ -844,271 +844,271 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'parent_id' => array( - 'description' => __( 'Parent order ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Parent order ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'number' => array( - 'description' => __( 'Order number.', 'woocommerce-rest-api' ), + 'description' => __( 'Order number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'order_key' => array( - 'description' => __( 'Order key.', 'woocommerce-rest-api' ), + 'description' => __( 'Order key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'created_via' => array( - 'description' => __( 'Shows where the order was created.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows where the order was created.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'version' => array( - 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Order status.', 'woocommerce-rest-api' ), + 'description' => __( 'Order status.', 'woocommerce' ), 'type' => 'string', 'default' => 'pending', 'enum' => $this->get_order_statuses(), 'context' => array( 'view', 'edit' ), ), 'currency' => array( - 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce-rest-api' ), + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), 'type' => 'string', 'default' => get_woocommerce_currency(), 'enum' => array_keys( get_woocommerce_currencies() ), 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_total' => array( - 'description' => __( 'Total discount amount for the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'discount_tax' => array( - 'description' => __( 'Total discount tax amount for the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_total' => array( - 'description' => __( 'Total shipping amount for the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax' => array( - 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce-rest-api' ), + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_tax' => array( - 'description' => __( 'Sum of line item taxes only.', 'woocommerce-rest-api' ), + 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Grand total.', 'woocommerce-rest-api' ), + 'description' => __( 'Grand total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_tax' => array( - 'description' => __( 'Sum of all taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Sum of all taxes.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'prices_include_tax' => array( - 'description' => __( 'True the prices included tax during checkout.', 'woocommerce-rest-api' ), + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_id' => array( - 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce-rest-api' ), + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), 'type' => 'integer', 'default' => 0, 'context' => array( 'view', 'edit' ), ), 'customer_ip_address' => array( - 'description' => __( "Customer's IP address.", 'woocommerce-rest-api' ), + 'description' => __( "Customer's IP address.", 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_user_agent' => array( - 'description' => __( 'User agent of the customer.', 'woocommerce-rest-api' ), + 'description' => __( 'User agent of the customer.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'customer_note' => array( - 'description' => __( 'Note left by customer during checkout.', 'woocommerce-rest-api' ), + 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'billing' => array( - 'description' => __( 'Billing address.', 'woocommerce-rest-api' ), + 'description' => __( 'Billing address.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), + 'description' => __( 'Email address.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), + 'description' => __( 'Phone number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'Shipping address.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping address.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce-rest-api' ), + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'payment_method' => array( - 'description' => __( 'Payment method ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment method ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'payment_method_title' => array( - 'description' => __( 'Payment method title.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment method title.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -1116,60 +1116,60 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'transaction_id' => array( - 'description' => __( 'Unique transaction ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique transaction ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_paid' => array( - 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_paid_gmt' => array( - 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_completed' => array( - 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_completed_gmt' => array( - 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'cart_hash' => array( - 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce-rest-api' ), + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -1177,67 +1177,67 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'line_items' => array( - 'description' => __( 'Line items data.', 'woocommerce-rest-api' ), + 'description' => __( 'Line items data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'product_id' => array( - 'description' => __( 'Product ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Product ID.', 'woocommerce' ), 'type' => array( 'integer' ), 'context' => array( 'view', 'edit' ), ), 'variation_id' => array( - 'description' => __( 'Variation ID, if applicable.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'quantity' => array( - 'description' => __( 'Quantity ordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Quantity ordered.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of product.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class of product.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal' => array( - 'description' => __( 'Line subtotal (before discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal_tax' => array( - 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1245,17 +1245,17 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax subtotal.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1263,25 +1263,25 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -1289,13 +1289,13 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'sku' => array( - 'description' => __( 'Product SKU.', 'woocommerce-rest-api' ), + 'description' => __( 'Product SKU.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'price' => array( - 'description' => __( 'Product price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product price.', 'woocommerce' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1304,7 +1304,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'tax_lines' => array( - 'description' => __( 'Tax lines data.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1312,67 +1312,67 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_code' => array( - 'description' => __( 'Tax rate code.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rate_id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'Tax rate label.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate label.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'compound' => array( - 'description' => __( 'Show if is a compound tax rate.', 'woocommerce-rest-api' ), + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tax_total' => array( - 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_tax_total' => array( - 'description' => __( 'Shipping tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -1383,46 +1383,46 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'shipping_lines' => array( - 'description' => __( 'Shipping lines data.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_title' => array( - 'description' => __( 'Shipping method name.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method name.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method ID.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'instance_id' => array( - 'description' => __( 'Shipping instance ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping instance ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1430,13 +1430,13 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1445,25 +1445,25 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -1474,47 +1474,47 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'fee_lines' => array( - 'description' => __( 'Fee lines data.', 'woocommerce-rest-api' ), + 'description' => __( 'Fee lines data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Fee name.', 'woocommerce-rest-api' ), + 'description' => __( 'Fee name.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class of fee.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class of fee.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status of fee.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax status of fee.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'taxable', 'none' ), ), 'total' => array( - 'description' => __( 'Line total (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'total_tax' => array( - 'description' => __( 'Line total tax (after discounts).', 'woocommerce-rest-api' ), + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxes' => array( - 'description' => __( 'Line taxes.', 'woocommerce-rest-api' ), + 'description' => __( 'Line taxes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1522,19 +1522,19 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tax rate ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax rate ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Tax total.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'subtotal' => array( - 'description' => __( 'Tax subtotal.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax subtotal.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1543,25 +1543,25 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -1572,54 +1572,54 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'coupon_lines' => array( - 'description' => __( 'Coupons line data.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupons line data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Item ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Item ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'code' => array( - 'description' => __( 'Coupon code.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon code.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), 'discount' => array( - 'description' => __( 'Discount total.', 'woocommerce-rest-api' ), + 'description' => __( 'Discount total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'discount_tax' => array( - 'description' => __( 'Discount total tax.', 'woocommerce-rest-api' ), + 'description' => __( 'Discount total tax.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -1630,7 +1630,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'refunds' => array( - 'description' => __( 'List of refunds.', 'woocommerce-rest-api' ), + 'description' => __( 'List of refunds.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1638,19 +1638,19 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Refund ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Refund ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reason' => array( - 'description' => __( 'Refund reason.', 'woocommerce-rest-api' ), + 'description' => __( 'Refund reason.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Refund total.', 'woocommerce-rest-api' ), + 'description' => __( 'Refund total.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1659,7 +1659,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'set_paid' => array( - 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce-rest-api' ), + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'edit' ), @@ -1680,27 +1680,27 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), 'type' => 'string', 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['customer'] = array( - 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['product'] = array( - 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); $params['dp'] = array( 'default' => wc_get_price_decimals(), - 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php index a652ea1fab3..69bfc51f418 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php @@ -51,7 +51,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'string', ), ), @@ -82,7 +82,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -95,7 +95,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -108,7 +108,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { */ public function update_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -141,7 +141,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { $gateway = $this->get_gateway( $request ); if ( is_null( $gateway ) ) { - return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $gateway = $this->prepare_item_for_response( $gateway, $request ); @@ -158,7 +158,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { $gateway = $this->get_gateway( $request ); if ( is_null( $gateway ) ) { - return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } // Get settings. @@ -184,7 +184,7 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { } if ( $errors_found ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -351,23 +351,23 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -375,71 +375,71 @@ class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller { ), ), 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway method title.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway method description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway settings.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Type of setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), + 'description' => __( 'Setting value.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Default value for the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php index 5c065477ffa..08c5f8f1980 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php @@ -100,13 +100,13 @@ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categorie 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), + 'description' => __( 'Category name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -114,7 +114,7 @@ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categorie ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -122,12 +122,12 @@ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categorie ), ), 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -135,71 +135,71 @@ class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categorie ), ), 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), + 'description' => __( 'Category archive display type.', 'woocommerce' ), 'type' => 'string', 'default' => 'default', 'enum' => array( 'default', 'products', 'subcategories', 'both' ), 'context' => array( 'view', 'edit' ), ), 'image' => array( - 'description' => __( 'Image data.', 'woocommerce-rest-api' ), + 'description' => __( 'Image data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'title' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php index a90d4ad232e..12ab7d62655 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php @@ -42,7 +42,7 @@ class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_C $this->namespace, '/' . $this->rest_base . '/batch', array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -65,7 +65,7 @@ class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_C */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( 'product', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -150,43 +150,43 @@ class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_C 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), + 'description' => __( 'The content of the review.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_created_gmt' => array( - 'description' => __( 'The date the review was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviewer name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviewer email.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php index 4941870fb2e..5c04d665029 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php @@ -47,7 +47,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -70,11 +70,11 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), 'type' => 'integer', ), 'id' => array( - 'description' => __( 'Unique identifier for the variation.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -104,7 +104,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -115,7 +115,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $this->namespace, '/' . $this->rest_base . '/batch', array( 'args' => array( 'product_id' => array( - 'description' => __( 'Unique identifier for the variable product.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -151,12 +151,12 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } // Check if variation belongs to the correct parent product. if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -488,7 +488,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( ! $object || 0 === $object->get_id() ) { return new WP_Error( - "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( + "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404, ) ); @@ -509,7 +509,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { return new WP_Error( /* translators: %s: post type */ - "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( + "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code(), ) ); @@ -527,7 +527,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( ! $supports_trash ) { return new WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( + 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501, ) ); @@ -538,7 +538,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( 'trash' === $object->get_status() ) { return new WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( + 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410, ) ); @@ -552,7 +552,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr if ( ! $result ) { return new WP_Error( /* translators: %s: post type */ - 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( + 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500, ) ); @@ -648,125 +648,125 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), + 'description' => __( 'Current variation price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation regular price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( 'End date of sale price, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'visible' => array( - 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce-rest-api' ), + 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), + 'description' => __( 'List of downloadable files.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), + 'description' => __( 'File ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), + 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), + 'description' => __( 'File URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -774,183 +774,183 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax status.', 'woocommerce' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), 'type' => array( 'boolean', 'null' ), 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock quantity.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'in_stock' => array( - 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation dimensions.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation image data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'List of attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -958,30 +958,30 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php index 81554632935..ad4dbd0807a 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php @@ -83,7 +83,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -112,7 +112,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'args' => array( 'force' => array( 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), 'type' => 'boolean', ), ), @@ -423,8 +423,8 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), 'date_modified_gmt' => wc_rest_prepare_date_response( time() ), 'src' => wc_placeholder_img_src(), - 'name' => __( 'Placeholder', 'woocommerce-rest-api' ), - 'alt' => __( 'Placeholder', 'woocommerce-rest-api' ), + 'name' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), 'position' => 0, ); } @@ -730,7 +730,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( 'variation' === $product->get_type() ) { return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404, ) @@ -1120,7 +1120,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( ! wp_attachment_is_image( $attachment_id ) ) { /* translators: %s: attachment id */ - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); } $gallery_positions[ $attachment_id ] = absint( isset( $image['position'] ) ? $image['position'] : $index ); @@ -1351,7 +1351,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( ! $object || 0 === $object->get_id() ) { return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", - __( 'Invalid ID.', 'woocommerce-rest-api' ), + __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404, ) @@ -1361,7 +1361,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( 'variation' === $object->get_type() ) { return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", - __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404, ) @@ -1384,7 +1384,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", /* translators: %s: post type */ - sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), + sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code(), ) @@ -1422,7 +1422,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { return new WP_Error( 'woocommerce_rest_trash_not_supported', /* translators: %s: post type */ - sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), + sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501, ) @@ -1435,7 +1435,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { return new WP_Error( 'woocommerce_rest_already_trashed', /* translators: %s: post type */ - sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), + sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410, ) @@ -1451,7 +1451,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { return new WP_Error( 'woocommerce_rest_cannot_delete', /* translators: %s: post type */ - sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), + sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500, ) @@ -1489,185 +1489,185 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Product slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Product URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Product type.', 'woocommerce-rest-api' ), + 'description' => __( 'Product type.', 'woocommerce' ), 'type' => 'string', 'default' => 'simple', 'enum' => array_keys( wc_get_product_types() ), 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), + 'description' => __( 'Product status (post status).', 'woocommerce' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), 'context' => array( 'view', 'edit' ), ), 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), + 'description' => __( 'Featured product.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), + 'description' => __( 'Catalog visibility.', 'woocommerce' ), 'type' => 'string', 'default' => 'visible', 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Product description.', 'woocommerce-rest-api' ), + 'description' => __( 'Product description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), + 'description' => __( 'Product short description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), + 'description' => __( 'Current product price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product regular price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( 'End date of sale price, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of sales.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), + 'description' => __( 'If the product is virtual.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), + 'description' => __( 'List of downloadable files.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), + 'description' => __( 'File ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), + 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), + 'description' => __( 'File URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1675,156 +1675,156 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax status.', 'woocommerce' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock management at product level.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock quantity.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'in_stock' => array( - 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce-rest-api' ), + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), + 'description' => __( 'Product dimensions.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), + 'description' => __( 'Allow reviews.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviews average rating.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of related products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1833,7 +1833,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'readonly' => true, ), 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1841,7 +1841,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1849,35 +1849,35 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Product parent ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), + 'description' => __( 'List of categories.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Category ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), + 'description' => __( 'Category name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Category slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1886,25 +1886,25 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), + 'description' => __( 'List of tags.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1913,59 +1913,59 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'images' => array( - 'description' => __( 'List of images.', 'woocommerce-rest-api' ), + 'description' => __( 'List of images.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce-rest-api' ), + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), @@ -1973,41 +1973,41 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'List of attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute position.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -2018,24 +2018,24 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -2043,7 +2043,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { ), ), 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of variations IDs.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -2052,7 +2052,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'readonly' => true, ), 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -2060,30 +2060,30 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { 'context' => array( 'view', 'edit' ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -2107,63 +2107,63 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'menu_order' ) ); $params['slug'] = array( - 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), 'type' => 'string', 'enum' => array_merge( array( 'any', 'future', 'trash' ), array_keys( get_post_statuses() ) ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['type'] = array( - 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_types() ), 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $params['sku'] = array( - 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['featured'] = array( - 'description' => __( 'Limit result set to featured products.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); $params['category'] = array( - 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['tag'] = array( - 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['shipping_class'] = array( - 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute'] = array( - 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['attribute_term'] = array( - 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'wp_parse_id_list', 'validate_callback' => 'rest_validate_request_arg', @@ -2171,7 +2171,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { if ( wc_tax_enabled() ) { $params['tax_class'] = array( - 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), 'type' => 'string', 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), 'sanitize_callback' => 'sanitize_text_field', @@ -2180,25 +2180,25 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller { } $params['in_stock'] = array( - 'description' => __( 'Limit result set to products in stock or out of stock.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products in stock or out of stock.', 'woocommerce' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); $params['on_sale'] = array( - 'description' => __( 'Limit result set to products on sale.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), 'type' => 'boolean', 'sanitize_callback' => 'wc_string_to_bool', 'validate_callback' => 'rest_validate_request_arg', ); $params['min_price'] = array( - 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['max_price'] = array( - 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php index e23aa3acc13..9564d26d47d 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php @@ -42,7 +42,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Settings group ID.', 'woocommerce' ), 'type' => 'string', ), ), @@ -59,7 +59,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/batch', array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Settings group ID.', 'woocommerce' ), 'type' => 'string', ), ), @@ -77,11 +77,11 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( 'args' => array( 'group' => array( - 'description' => __( 'Settings group ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Settings group ID.', 'woocommerce' ), 'type' => 'string', ), 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'string', ), ), @@ -156,13 +156,13 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ public function get_group_settings( $group_id ) { if ( empty( $group_id ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $filtered_settings = array(); @@ -231,7 +231,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ public function get_setting( $group_id, $setting_id ) { if ( empty( $setting_id ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = $this->get_group_settings( $group_id ); @@ -243,13 +243,13 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); if ( empty( $array_key ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } $setting = $settings[ $array_key[0] ]; if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } return $setting; @@ -373,7 +373,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -388,7 +388,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { */ 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-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -502,7 +502,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', @@ -511,7 +511,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -520,7 +520,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -529,7 +529,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), + 'description' => __( 'Setting value.', 'woocommerce' ), 'type' => array( 'string', 'array', 'null' ), 'items' => array( 'type' => array( 'string', 'null' ), @@ -537,7 +537,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Default value for the setting.', 'woocommerce' ), 'type' => array( 'string', 'array', 'null' ), 'items' => array( 'type' => array( 'string', 'null' ), @@ -546,7 +546,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -555,7 +555,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -564,7 +564,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Type of setting.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -574,7 +574,7 @@ class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller { 'readonly' => true, ), 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce-rest-api' ), + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php index 1ca5f153b40..f41c91e722d 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php @@ -60,7 +60,7 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { public function get_items( $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); } $defaults = $this->group_defaults(); @@ -176,7 +176,7 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -195,31 +195,31 @@ class WC_REST_Settings_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce-rest-api' ), + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce-rest-api' ), + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce-rest-api' ), + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php index 0c4a0ff8fcd..795c92b3e18 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php @@ -51,7 +51,7 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'string', ), ), @@ -76,7 +76,7 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -89,7 +89,7 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -121,7 +121,7 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { $wc_shipping = WC_Shipping::instance(); $methods = $wc_shipping->get_shipping_methods(); if ( empty( $methods[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $method = $methods[ $request['id'] ]; @@ -195,19 +195,19 @@ class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Method ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Method ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method title.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php index 434906709c7..9e171814f70 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php @@ -26,7 +26,7 @@ class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zon $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/locations', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -85,7 +85,7 @@ class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zon } if ( 0 === $zone->get_id() ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); } $raw_locations = $request->get_json_params(); @@ -166,12 +166,12 @@ class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zon 'type' => 'object', 'properties' => array( 'code' => array( - 'description' => __( 'Shipping zone location code.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping zone location code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'type' => array( - 'description' => __( 'Shipping zone location type.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping zone location type.', 'woocommerce' ), 'type' => 'string', 'default' => 'country', 'enum' => array( diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php index 67ad37bfd26..c753fd8e42f 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php @@ -26,7 +26,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods', array( 'args' => array( 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -44,7 +44,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones 'method_id' => array( 'required' => true, 'readonly' => false, - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method ID.', 'woocommerce' ), ), ) ), @@ -57,11 +57,11 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', array( 'args' => array( 'zone_id' => array( - 'description' => __( 'Unique ID for the zone.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), 'type' => 'integer', ), 'instance_id' => array( - 'description' => __( 'Unique ID for the instance.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique ID for the instance.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -84,7 +84,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -118,7 +118,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $method, $request ); @@ -174,7 +174,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -212,7 +212,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -227,7 +227,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones if ( $force ) { $zone->delete_shipping_method( $instance_id ); } else { - return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } /** @@ -266,7 +266,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( false === $method ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } $method = $this->update_fields( $instance_id, $method, $request ); @@ -311,7 +311,7 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones } if ( $errors_found ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); @@ -433,100 +433,100 @@ class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'instance_id' => array( - 'description' => __( 'Shipping method instance ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Shipping method customer facing title.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method customer facing title.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'order' => array( - 'description' => __( 'Shipping method sort order.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method sort order.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'enabled' => array( - 'description' => __( 'Shipping method enabled status.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method enabled status.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'method_id' => array( - 'description' => __( 'Shipping method ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_title' => array( - 'description' => __( 'Shipping method title.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method title.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_description' => array( - 'description' => __( 'Shipping method description.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'settings' => array( - 'description' => __( 'Shipping method settings.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping method settings.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Type of setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), + 'description' => __( 'Setting value.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Default value for the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php index cd8a6b75ccf..5190b6e84b5 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php @@ -38,7 +38,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro 'name' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping zone name.', 'woocommerce' ), ), ) ), @@ -51,7 +51,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -74,7 +74,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -151,7 +151,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); return $response; } else { - return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); } } @@ -169,7 +169,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro } if ( 0 === $zone->get_id() ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); } $zone_changed = false; @@ -211,7 +211,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro if ( $force ) { $zone->delete(); } else { - return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } return $response; @@ -278,13 +278,13 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping zone name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -292,7 +292,7 @@ class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Contro ), ), 'order' => array( - 'description' => __( 'Shipping zone order.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping zone order.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php index ee62d186b82..b98870cb42e 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -56,7 +56,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'string', ), ), @@ -84,7 +84,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { */ 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-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -97,7 +97,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { */ 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 view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -110,7 +110,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { */ public function update_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -124,97 +124,97 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { public function get_tools() { $tools = array( 'clear_transients' => array( - 'name' => __( 'WooCommerce transients', 'woocommerce-rest-api' ), - 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce-rest-api' ), + 'name' => __( 'WooCommerce transients', 'woocommerce' ), + 'button' => __( 'Clear transients', 'woocommerce' ), + 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ), ), 'clear_expired_transients' => array( - 'name' => __( 'Expired transients', 'woocommerce-rest-api' ), - 'button' => __( 'Clear transients', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce-rest-api' ), + 'name' => __( 'Expired transients', 'woocommerce' ), + 'button' => __( 'Clear transients', 'woocommerce' ), + 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce' ), ), 'delete_orphaned_variations' => array( - 'name' => __( 'Orphaned variations', 'woocommerce-rest-api' ), - 'button' => __( 'Delete orphaned variations', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce-rest-api' ), + 'name' => __( 'Orphaned variations', 'woocommerce' ), + 'button' => __( 'Delete orphaned variations', 'woocommerce' ), + 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce' ), ), 'clear_expired_download_permissions' => array( - 'name' => __( 'Used-up download permissions', 'woocommerce-rest-api' ), - 'button' => __( 'Clean up download permissions', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce-rest-api' ), + 'name' => __( 'Used-up download permissions', 'woocommerce' ), + 'button' => __( 'Clean up download permissions', 'woocommerce' ), + 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ), ), 'regenerate_product_lookup_tables' => array( - 'name' => __( 'Product lookup tables', 'woocommerce-rest-api' ), - 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce-rest-api' ), + 'name' => __( 'Product lookup tables', 'woocommerce' ), + 'button' => __( 'Regenerate', 'woocommerce' ), + 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce' ), ), 'recount_terms' => array( - 'name' => __( 'Term counts', 'woocommerce-rest-api' ), - 'button' => __( 'Recount terms', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce-rest-api' ), + 'name' => __( 'Term counts', 'woocommerce' ), + 'button' => __( 'Recount terms', 'woocommerce' ), + 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ), ), 'reset_roles' => array( - 'name' => __( 'Capabilities', 'woocommerce-rest-api' ), - 'button' => __( 'Reset capabilities', 'woocommerce-rest-api' ), - 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce-rest-api' ), + 'name' => __( 'Capabilities', 'woocommerce' ), + 'button' => __( 'Reset capabilities', 'woocommerce' ), + 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ), ), 'clear_sessions' => array( - 'name' => __( 'Clear customer sessions', 'woocommerce-rest-api' ), - 'button' => __( 'Clear', 'woocommerce-rest-api' ), + 'name' => __( 'Clear customer sessions', 'woocommerce' ), + 'button' => __( 'Clear', 'woocommerce' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce-rest-api' ) + __( 'Note:', 'woocommerce' ), + __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce' ) ), ), 'clear_template_cache' => array( - 'name' => __( 'Clear template cache', 'woocommerce-rest-api' ), - 'button' => __( 'Clear', 'woocommerce-rest-api' ), + 'name' => __( 'Clear template cache', 'woocommerce' ), + 'button' => __( 'Clear', 'woocommerce' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will empty the template cache.', 'woocommerce-rest-api' ) + __( 'Note:', 'woocommerce' ), + __( 'This tool will empty the template cache.', 'woocommerce' ) ), ), 'install_pages' => array( - 'name' => __( 'Create default WooCommerce pages', 'woocommerce-rest-api' ), - 'button' => __( 'Create pages', 'woocommerce-rest-api' ), + 'name' => __( 'Create default WooCommerce pages', 'woocommerce' ), + 'button' => __( 'Create pages', 'woocommerce' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce-rest-api' ) + __( 'Note:', 'woocommerce' ), + __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce' ) ), ), 'delete_taxes' => array( - 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce-rest-api' ), - 'button' => __( 'Delete tax rates', 'woocommerce-rest-api' ), + 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce' ), + 'button' => __( 'Delete tax rates', 'woocommerce' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce-rest-api' ) + __( 'Note:', 'woocommerce' ), + __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce' ) ), ), 'regenerate_thumbnails' => array( - 'name' => __( 'Regenerate shop thumbnails', 'woocommerce-rest-api' ), - 'button' => __( 'Regenerate', 'woocommerce-rest-api' ), - 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce-rest-api' ), + 'name' => __( 'Regenerate shop thumbnails', 'woocommerce' ), + 'button' => __( 'Regenerate', 'woocommerce' ), + 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce' ), ), 'db_update_routine' => array( - 'name' => __( 'Update database', 'woocommerce-rest-api' ), - 'button' => __( 'Update database', 'woocommerce-rest-api' ), + 'name' => __( 'Update database', 'woocommerce' ), + 'button' => __( 'Update database', 'woocommerce' ), 'desc' => sprintf( '%1$s %2$s', - __( 'Note:', 'woocommerce-rest-api' ), - __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce-rest-api' ) + __( 'Note:', 'woocommerce' ), + __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce' ) ), ), ); if ( method_exists( 'WC_Install', 'verify_base_tables' ) ) { $tools['verify_db_tables'] = array( - 'name' => __( 'Verify base database tables', 'woocommerce-rest-api' ), - 'button' => __( 'Verify database', 'woocommerce-rest-api' ), + 'name' => __( 'Verify base database tables', 'woocommerce' ), + 'button' => __( 'Verify database', 'woocommerce' ), 'desc' => sprintf( - __( 'Verify if all base database tables are present.', 'woocommerce-rest-api' ) + __( 'Verify if all base database tables are present.', 'woocommerce' ) ), ); } @@ -266,7 +266,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { public function get_item( $request ) { $tools = $this->get_tools(); if ( empty( $tools[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tool = $tools[ $request['id'] ]; return rest_ensure_response( @@ -291,7 +291,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { public function update_item( $request ) { $tools = $this->get_tools(); if ( empty( $tools[ $request['id'] ] ) ) { - return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tool = $tools[ $request['id'] ]; @@ -349,7 +349,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the tool.', 'woocommerce-rest-api' ), + 'description' => __( 'A unique identifier for the tool.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -357,7 +357,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), 'name' => array( - 'description' => __( 'Tool name.', 'woocommerce-rest-api' ), + 'description' => __( 'Tool name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -365,7 +365,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), 'action' => array( - 'description' => __( 'What running the tool will do.', 'woocommerce-rest-api' ), + 'description' => __( 'What running the tool will do.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -373,7 +373,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), 'description' => array( - 'description' => __( 'Tool description.', 'woocommerce-rest-api' ), + 'description' => __( 'Tool description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -381,12 +381,12 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ), ), 'success' => array( - 'description' => __( 'Did the tool run successfully?', 'woocommerce-rest-api' ), + 'description' => __( 'Did the tool run successfully?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'edit' ), ), 'message' => array( - 'description' => __( 'Tool return message.', 'woocommerce-rest-api' ), + 'description' => __( 'Tool return message.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( @@ -453,12 +453,12 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { } WC_Cache_Helper::get_transient_version( 'shipping', true ); - $message = __( 'Product transients cleared', 'woocommerce-rest-api' ); + $message = __( 'Product transients cleared', 'woocommerce' ); break; case 'clear_expired_transients': /* translators: %d: amount of expired transients */ - $message = sprintf( __( '%d transients rows cleared', 'woocommerce-rest-api' ), wc_delete_expired_transients() ); + $message = sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() ); break; case 'delete_orphaned_variations': @@ -472,7 +472,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ) ); /* translators: %d: amount of orphaned variations */ - $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce-rest-api' ), $result ); + $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result ); break; case 'clear_expired_download_permissions': @@ -487,20 +487,20 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ) ); /* translators: %d: amount of permissions */ - $message = sprintf( __( '%d permissions deleted', 'woocommerce-rest-api' ), $result ); + $message = sprintf( __( '%d permissions deleted', 'woocommerce' ), $result ); break; case 'regenerate_product_lookup_tables': if ( ! wc_update_product_lookup_tables_is_running() ) { wc_update_product_lookup_tables(); } - $message = __( 'Lookup tables are regenerating', 'woocommerce-rest-api' ); + $message = __( 'Lookup tables are regenerating', 'woocommerce' ); break; case 'reset_roles': // Remove then re-add caps and roles. WC_Install::remove_roles(); WC_Install::create_roles(); - $message = __( 'Roles successfully reset', 'woocommerce-rest-api' ); + $message = __( 'Roles successfully reset', 'woocommerce' ); break; case 'recount_terms': @@ -520,7 +520,7 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { ) ); _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); - $message = __( 'Terms successfully recounted', 'woocommerce-rest-api' ); + $message = __( 'Terms successfully recounted', 'woocommerce' ); break; case 'clear_sessions': @@ -528,12 +528,12 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. wp_cache_flush(); /* translators: %d: amount of sessions */ - $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce-rest-api' ), absint( $result ) ); + $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) ); break; case 'install_pages': WC_Install::create_pages(); - $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce-rest-api' ); + $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); break; case 'delete_taxes': @@ -545,12 +545,12 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { } else { WC_Cache_Helper::incr_cache_prefix( 'taxes' ); } - $message = __( 'Tax rates successfully deleted', 'woocommerce-rest-api' ); + $message = __( 'Tax rates successfully deleted', 'woocommerce' ); break; case 'regenerate_thumbnails': WC_Regenerate_Images::queue_image_regeneration(); - $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce-rest-api' ); + $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); break; case 'db_update_routine': @@ -558,31 +558,31 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); - $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce-rest-api' ); + $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' ); break; case 'clear_template_cache': if ( function_exists( 'wc_clear_template_cache' ) ) { wc_clear_template_cache(); - $message = __( 'Template cache cleared.', 'woocommerce-rest-api' ); + $message = __( 'Template cache cleared.', 'woocommerce' ); } else { - $message = __( 'The active version of WooCommerce does not support template cache clearing.', 'woocommerce-rest-api' ); + $message = __( 'The active version of WooCommerce does not support template cache clearing.', 'woocommerce' ); $ran = false; } break; case 'verify_db_tables': if ( ! method_exists( 'WC_Install', 'verify_base_tables' ) ) { - $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce-rest-api' ); + $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce' ); $ran = false; break; } // Try to manually create table again. $missing_tables = WC_Install::verify_base_tables( true, true ); if ( 0 === count( $missing_tables ) ) { - $message = __( 'Database verified successfully.', 'woocommerce-rest-api' ); + $message = __( 'Database verified successfully.', 'woocommerce' ); } else { - $message = __( 'Verifying database... One or more tables are still missing: ', 'woocommerce-rest-api' ); + $message = __( 'Verifying database... One or more tables are still missing: ', 'woocommerce' ); $message .= implode( ', ', $missing_tables ); $ran = false; } @@ -599,13 +599,13 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller { $callback_string = is_array( $callback ) ? get_class( $callback[0] ) . '::' . $callback[1] : $callback; $ran = false; /* translators: %s: callback string */ - $message = sprintf( __( 'There was an error calling %s', 'woocommerce-rest-api' ), $callback_string ); + $message = sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback_string ); } else { - $message = __( 'Tool ran.', 'woocommerce-rest-api' ); + $message = __( 'Tool ran.', 'woocommerce' ); } } else { $ran = false; - $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce-rest-api' ); + $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ); } break; } diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php index 448f30f0725..e2b6e93c325 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -59,7 +59,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { */ 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-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -90,195 +90,195 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'environment' => array( - 'description' => __( 'Environment.', 'woocommerce-rest-api' ), + 'description' => __( 'Environment.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'home_url' => array( - 'description' => __( 'Home URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Home URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'site_url' => array( - 'description' => __( 'Site URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Site URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'version' => array( - 'description' => __( 'WooCommerce version.', 'woocommerce-rest-api' ), + 'description' => __( 'WooCommerce version.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'log_directory' => array( - 'description' => __( 'Log directory.', 'woocommerce-rest-api' ), + 'description' => __( 'Log directory.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'log_directory_writable' => array( - 'description' => __( 'Is log directory writable?', 'woocommerce-rest-api' ), + 'description' => __( 'Is log directory writable?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_version' => array( - 'description' => __( 'WordPress version.', 'woocommerce-rest-api' ), + 'description' => __( 'WordPress version.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_multisite' => array( - 'description' => __( 'Is WordPress multisite?', 'woocommerce-rest-api' ), + 'description' => __( 'Is WordPress multisite?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_memory_limit' => array( - 'description' => __( 'WordPress memory limit.', 'woocommerce-rest-api' ), + 'description' => __( 'WordPress memory limit.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_debug_mode' => array( - 'description' => __( 'Is WordPress debug mode active?', 'woocommerce-rest-api' ), + 'description' => __( 'Is WordPress debug mode active?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'wp_cron' => array( - 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce-rest-api' ), + 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'language' => array( - 'description' => __( 'WordPress language.', 'woocommerce-rest-api' ), + 'description' => __( 'WordPress language.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'server_info' => array( - 'description' => __( 'Server info.', 'woocommerce-rest-api' ), + 'description' => __( 'Server info.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'php_version' => array( - 'description' => __( 'PHP version.', 'woocommerce-rest-api' ), + 'description' => __( 'PHP version.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'php_post_max_size' => array( - 'description' => __( 'PHP post max size.', 'woocommerce-rest-api' ), + 'description' => __( 'PHP post max size.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'php_max_execution_time' => array( - 'description' => __( 'PHP max execution time.', 'woocommerce-rest-api' ), + 'description' => __( 'PHP max execution time.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'php_max_input_vars' => array( - 'description' => __( 'PHP max input vars.', 'woocommerce-rest-api' ), + 'description' => __( 'PHP max input vars.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'curl_version' => array( - 'description' => __( 'cURL version.', 'woocommerce-rest-api' ), + 'description' => __( 'cURL version.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'suhosin_installed' => array( - 'description' => __( 'Is SUHOSIN installed?', 'woocommerce-rest-api' ), + 'description' => __( 'Is SUHOSIN installed?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'max_upload_size' => array( - 'description' => __( 'Max upload size.', 'woocommerce-rest-api' ), + 'description' => __( 'Max upload size.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'mysql_version' => array( - 'description' => __( 'MySQL version.', 'woocommerce-rest-api' ), + 'description' => __( 'MySQL version.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'mysql_version_string' => array( - 'description' => __( 'MySQL version string.', 'woocommerce-rest-api' ), + 'description' => __( 'MySQL version string.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'default_timezone' => array( - 'description' => __( 'Default timezone.', 'woocommerce-rest-api' ), + 'description' => __( 'Default timezone.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'fsockopen_or_curl_enabled' => array( - 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce-rest-api' ), + 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'soapclient_enabled' => array( - 'description' => __( 'Is SoapClient class enabled?', 'woocommerce-rest-api' ), + 'description' => __( 'Is SoapClient class enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'domdocument_enabled' => array( - 'description' => __( 'Is DomDocument class enabled?', 'woocommerce-rest-api' ), + 'description' => __( 'Is DomDocument class enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'gzip_enabled' => array( - 'description' => __( 'Is GZip enabled?', 'woocommerce-rest-api' ), + 'description' => __( 'Is GZip enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'mbstring_enabled' => array( - 'description' => __( 'Is mbstring enabled?', 'woocommerce-rest-api' ), + 'description' => __( 'Is mbstring enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_post_successful' => array( - 'description' => __( 'Remote POST successful?', 'woocommerce-rest-api' ), + 'description' => __( 'Remote POST successful?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_post_response' => array( - 'description' => __( 'Remote POST response.', 'woocommerce-rest-api' ), + 'description' => __( 'Remote POST response.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_get_successful' => array( - 'description' => __( 'Remote GET successful?', 'woocommerce-rest-api' ), + 'description' => __( 'Remote GET successful?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'remote_get_response' => array( - 'description' => __( 'Remote GET response.', 'woocommerce-rest-api' ), + 'description' => __( 'Remote GET response.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, @@ -286,31 +286,31 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'database' => array( - 'description' => __( 'Database.', 'woocommerce-rest-api' ), + 'description' => __( 'Database.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'wc_database_version' => array( - 'description' => __( 'WC database version.', 'woocommerce-rest-api' ), + 'description' => __( 'WC database version.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'database_prefix' => array( - 'description' => __( 'Database prefix.', 'woocommerce-rest-api' ), + 'description' => __( 'Database prefix.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'maxmind_geoip_database' => array( - 'description' => __( 'MaxMind GeoIP database.', 'woocommerce-rest-api' ), + 'description' => __( 'MaxMind GeoIP database.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'database_tables' => array( - 'description' => __( 'Database tables.', 'woocommerce-rest-api' ), + 'description' => __( 'Database tables.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -321,7 +321,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'active_plugins' => array( - 'description' => __( 'Active plugins.', 'woocommerce-rest-api' ), + 'description' => __( 'Active plugins.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -330,7 +330,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'inactive_plugins' => array( - 'description' => __( 'Inactive plugins.', 'woocommerce-rest-api' ), + 'description' => __( 'Inactive plugins.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -339,7 +339,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'dropins_mu_plugins' => array( - 'description' => __( 'Dropins & MU plugins.', 'woocommerce-rest-api' ), + 'description' => __( 'Dropins & MU plugins.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -348,62 +348,62 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'theme' => array( - 'description' => __( 'Theme.', 'woocommerce-rest-api' ), + 'description' => __( 'Theme.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'name' => array( - 'description' => __( 'Theme name.', 'woocommerce-rest-api' ), + 'description' => __( 'Theme name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'version' => array( - 'description' => __( 'Theme version.', 'woocommerce-rest-api' ), + 'description' => __( 'Theme version.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'version_latest' => array( - 'description' => __( 'Latest version of theme.', 'woocommerce-rest-api' ), + 'description' => __( 'Latest version of theme.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'author_url' => array( - 'description' => __( 'Theme author URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Theme author URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'is_child_theme' => array( - 'description' => __( 'Is this theme a child theme?', 'woocommerce-rest-api' ), + 'description' => __( 'Is this theme a child theme?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_woocommerce_support' => array( - 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce-rest-api' ), + 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_woocommerce_file' => array( - 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce-rest-api' ), + 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'has_outdated_templates' => array( - 'description' => __( 'Does this theme have outdated templates?', 'woocommerce-rest-api' ), + 'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'overrides' => array( - 'description' => __( 'Template overrides.', 'woocommerce-rest-api' ), + 'description' => __( 'Template overrides.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -412,19 +412,19 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'parent_name' => array( - 'description' => __( 'Parent theme name.', 'woocommerce-rest-api' ), + 'description' => __( 'Parent theme name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'parent_version' => array( - 'description' => __( 'Parent theme version.', 'woocommerce-rest-api' ), + 'description' => __( 'Parent theme version.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'parent_author_url' => array( - 'description' => __( 'Parent theme author URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Parent theme author URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), @@ -433,67 +433,67 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'settings' => array( - 'description' => __( 'Settings.', 'woocommerce-rest-api' ), + 'description' => __( 'Settings.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'api_enabled' => array( - 'description' => __( 'REST API enabled?', 'woocommerce-rest-api' ), + 'description' => __( 'REST API enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'force_ssl' => array( - 'description' => __( 'SSL forced?', 'woocommerce-rest-api' ), + 'description' => __( 'SSL forced?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'currency' => array( - 'description' => __( 'Currency.', 'woocommerce-rest-api' ), + 'description' => __( 'Currency.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'currency_symbol' => array( - 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), + 'description' => __( 'Currency symbol.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'currency_position' => array( - 'description' => __( 'Currency position.', 'woocommerce-rest-api' ), + 'description' => __( 'Currency position.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'thousand_separator' => array( - 'description' => __( 'Thousand separator.', 'woocommerce-rest-api' ), + 'description' => __( 'Thousand separator.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'decimal_separator' => array( - 'description' => __( 'Decimal separator.', 'woocommerce-rest-api' ), + 'description' => __( 'Decimal separator.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'number_of_decimals' => array( - 'description' => __( 'Number of decimals.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of decimals.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'geolocation_enabled' => array( - 'description' => __( 'Geolocation enabled?', 'woocommerce-rest-api' ), + 'description' => __( 'Geolocation enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'taxonomies' => array( - 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce-rest-api' ), + 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -502,7 +502,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'product_visibility_terms' => array( - 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce-rest-api' ), + 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -513,19 +513,19 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'security' => array( - 'description' => __( 'Security.', 'woocommerce-rest-api' ), + 'description' => __( 'Security.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view' ), 'readonly' => true, 'properties' => array( 'secure_connection' => array( - 'description' => __( 'Is the connection to your store secure?', 'woocommerce-rest-api' ), + 'description' => __( 'Is the connection to your store secure?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, ), 'hide_errors' => array( - 'description' => __( 'Hide errors from visitors?', 'woocommerce-rest-api' ), + 'description' => __( 'Hide errors from visitors?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view' ), 'readonly' => true, @@ -533,7 +533,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'pages' => array( - 'description' => __( 'WooCommerce pages.', 'woocommerce-rest-api' ), + 'description' => __( 'WooCommerce pages.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -542,7 +542,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { ), ), 'post_type_counts' => array( - 'description' => __( 'Total post count.', 'woocommerce-rest-api' ), + 'description' => __( 'Total post count.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -657,7 +657,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { $curl_version = curl_version(); $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; } elseif ( extension_loaded( 'curl' ) ) { - $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce-rest-api' ); + $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); } // WP memory limit. @@ -1156,23 +1156,23 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller { public function get_pages() { // WC pages to check against. $check_pages = array( - _x( 'Shop base', 'Page setting', 'woocommerce-rest-api' ) => array( + _x( 'Shop base', 'Page setting', 'woocommerce' ) => array( 'option' => 'woocommerce_shop_page_id', 'shortcode' => '', ), - _x( 'Cart', 'Page setting', 'woocommerce-rest-api' ) => array( + _x( 'Cart', 'Page setting', 'woocommerce' ) => array( 'option' => 'woocommerce_cart_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', ), - _x( 'Checkout', 'Page setting', 'woocommerce-rest-api' ) => array( + _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( 'option' => 'woocommerce_checkout_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', ), - _x( 'My account', 'Page setting', 'woocommerce-rest-api' ) => array( + _x( 'My account', 'Page setting', 'woocommerce' ) => array( 'option' => 'woocommerce_myaccount_page_id', 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', ), - _x( 'Terms and conditions', 'Page setting', 'woocommerce-rest-api' ) => array( + _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( 'option' => 'woocommerce_terms_page_id', 'shortcode' => '', ), diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php index 30639073e92..778a805d1e2 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php @@ -67,32 +67,32 @@ class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliverie 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view' ), 'readonly' => true, ), 'duration' => array( - 'description' => __( 'The delivery duration, in seconds.', 'woocommerce-rest-api' ), + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'summary' => array( - 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce-rest-api' ), + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'request_url' => array( - 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce-rest-api' ), + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), 'readonly' => true, ), 'request_headers' => array( - 'description' => __( 'Request headers.', 'woocommerce-rest-api' ), + 'description' => __( 'Request headers.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -101,25 +101,25 @@ class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliverie ), ), 'request_body' => array( - 'description' => __( 'Request body.', 'woocommerce-rest-api' ), + 'description' => __( 'Request body.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_code' => array( - 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce-rest-api' ), + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_message' => array( - 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce-rest-api' ), + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'response_headers' => array( - 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce-rest-api' ), + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view' ), 'readonly' => true, @@ -128,19 +128,19 @@ class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliverie ), ), 'response_body' => array( - 'description' => __( 'The response body from the receiving server.', 'woocommerce-rest-api' ), + 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the webhook delivery was logged, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the webhook delivery was logged, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php b/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php index d30967f2392..ede2c1d121a 100644 --- a/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php +++ b/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php @@ -36,7 +36,7 @@ class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller { $webhook = wc_get_webhook( $id ); if ( empty( $webhook ) || is_null( $webhook ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } $data = array( @@ -95,42 +95,42 @@ class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ), + 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Webhook status.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook status.', 'woocommerce' ), 'type' => 'string', 'default' => 'active', 'enum' => array_keys( wc_get_webhook_statuses() ), 'context' => array( 'view', 'edit' ), ), 'topic' => array( - 'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook topic.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'resource' => array( - 'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'event' => array( - 'description' => __( 'Webhook event.', 'woocommerce-rest-api' ), + 'description' => __( 'Webhook event.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hooks' => array( - 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ), + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -139,37 +139,37 @@ class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller { ), ), 'delivery_url' => array( - 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ), + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'secret' => array( - 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ), + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php index d851be5adc8..9365efbe7b3 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php @@ -139,7 +139,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { if ( $total > $limit ) { /* translators: %s: items limit */ - return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce-rest-api' ), $limit ), array( 'status' => 413 ) ); + return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); } return true; @@ -288,7 +288,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { if ( array_key_exists( $value, $setting['options'] ) ) { return $value; } else { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -306,7 +306,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { } if ( ! is_array( $values ) ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } $final_values = array(); @@ -329,7 +329,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { */ public function validate_setting_image_width_field( $values, $setting ) { if ( ! is_array( $values ) ) { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } $current = $setting['value']; @@ -372,7 +372,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; return $value; } else { - return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); } } @@ -432,7 +432,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { 'type' => 'object', 'properties' => array( 'create' => array( - 'description' => __( 'List of created resources.', 'woocommerce-rest-api' ), + 'description' => __( 'List of created resources.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -440,7 +440,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { ), ), 'update' => array( - 'description' => __( 'List of updated resources.', 'woocommerce-rest-api' ), + 'description' => __( 'List of updated resources.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -448,7 +448,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller { ), ), 'delete' => array( - 'description' => __( 'List of delete resources.', 'woocommerce-rest-api' ), + 'description' => __( 'List of delete resources.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php index 7aaa3af3e30..6b454a99914 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php @@ -40,7 +40,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { */ protected function get_object( $id ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce-rest-api' ), __METHOD__ ), array( 'status' => 405 ) ); + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); } /** @@ -53,7 +53,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -69,7 +69,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -85,7 +85,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -113,7 +113,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { */ protected function prepare_object_for_response( $object, $request ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce-rest-api' ), __METHOD__ ), array( 'status' => 405 ) ); + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); } /** @@ -126,7 +126,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { */ protected function prepare_object_for_database( $request, $creating = false ) { // translators: %s: Class method name. - return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce-rest-api' ), __METHOD__ ), array( 'status' => 405 ) ); + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); } /** @@ -139,7 +139,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_object_for_response( $object, $request ); @@ -187,7 +187,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $object = $this->save_object( $request, true ); @@ -234,7 +234,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $object = $this->get_object( (int) $request['id'] ); if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 400 ) ); } $object = $this->save_object( $request, false ); @@ -417,7 +417,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $result = false; if ( ! $object || 0 === $object->get_id() ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); @@ -434,7 +434,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -448,14 +448,14 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( is_callable( array( $object, 'get_status' ) ) ) { if ( 'trash' === $object->get_status() ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); } $object->delete(); @@ -465,7 +465,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -511,7 +511,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { $params['context']['default'] = 'view'; $params['page'] = array( - 'description' => __( 'Current page of the collection.', 'woocommerce-rest-api' ), + 'description' => __( 'Current page of the collection.', 'woocommerce' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', @@ -519,7 +519,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'minimum' => 1, ); $params['per_page'] = array( - 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce-rest-api' ), + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, @@ -528,25 +528,25 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['search'] = array( - 'description' => __( 'Limit results to those matching a string.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ); $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), + '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-rest-api' ), + '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['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -555,7 +555,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -564,20 +564,20 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), + '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-rest-api' ), + '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-rest-api' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -593,7 +593,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { if ( $this->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -602,7 +602,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller { 'default' => array(), ); $params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php index 072fb0893a5..da926c02605 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php @@ -76,43 +76,43 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'email' => array( - 'description' => __( 'The email address for the customer.', 'woocommerce-rest-api' ), + 'description' => __( 'The email address for the customer.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'first_name' => array( - 'description' => __( 'Customer first name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer first name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -120,7 +120,7 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { ), ), 'last_name' => array( - 'description' => __( 'Customer last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -128,13 +128,13 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { ), ), 'role' => array( - 'description' => __( 'Customer role.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer role.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'username' => array( - 'description' => __( 'Customer login name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer login name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -142,157 +142,157 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V2_Controller { ), ), 'password' => array( - 'description' => __( 'Customer password.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer password.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'billing' => array( - 'description' => __( 'List of billing address data.', 'woocommerce-rest-api' ), + 'description' => __( 'List of billing address data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code of the country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'email' => array( - 'description' => __( 'Email address.', 'woocommerce-rest-api' ), + 'description' => __( 'Email address.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'phone' => array( - 'description' => __( 'Phone number.', 'woocommerce-rest-api' ), + 'description' => __( 'Phone number.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping' => array( - 'description' => __( 'List of shipping address data.', 'woocommerce-rest-api' ), + 'description' => __( 'List of shipping address data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'first_name' => array( - 'description' => __( 'First name.', 'woocommerce-rest-api' ), + 'description' => __( 'First name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'last_name' => array( - 'description' => __( 'Last name.', 'woocommerce-rest-api' ), + 'description' => __( 'Last name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'company' => array( - 'description' => __( 'Company name.', 'woocommerce-rest-api' ), + 'description' => __( 'Company name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_1' => array( - 'description' => __( 'Address line 1', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 1', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'address_2' => array( - 'description' => __( 'Address line 2', 'woocommerce-rest-api' ), + 'description' => __( 'Address line 2', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'city' => array( - 'description' => __( 'City name.', 'woocommerce-rest-api' ), + 'description' => __( 'City name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'state' => array( - 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'postcode' => array( - 'description' => __( 'Postal code.', 'woocommerce-rest-api' ), + 'description' => __( 'Postal code.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'country' => array( - 'description' => __( 'ISO code of the country.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO code of the country.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'is_paying_customer' => array( - 'description' => __( 'Is the customer a paying customer?', 'woocommerce-rest-api' ), + 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), 'type' => 'bool', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'avatar_url' => array( - 'description' => __( 'Avatar URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Avatar URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php index 7b79f969397..37d3a55630d 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php @@ -56,7 +56,7 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'continent' => array( - 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), + 'description' => __( '2 character continent code.', 'woocommerce' ), 'type' => 'string', ), ), @@ -182,7 +182,7 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { public function get_item( $request ) { $data = $this->get_continent( strtoupper( $request['location'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -247,19 +247,19 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( '2 character continent code.', 'woocommerce-rest-api' ), + 'description' => __( '2 character continent code.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of continent.', 'woocommerce-rest-api' ), + 'description' => __( 'Full name of continent.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'countries' => array( 'type' => 'array', - 'description' => __( 'List of countries on this continent.', 'woocommerce-rest-api' ), + 'description' => __( 'List of countries on this continent.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -269,49 +269,49 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'currency_code' => array( 'type' => 'string', - 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce-rest-api' ), + 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'currency_pos' => array( 'type' => 'string', - 'description' => __( 'Currency symbol position for this country.', 'woocommerce-rest-api' ), + 'description' => __( 'Currency symbol position for this country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'decimal_sep' => array( 'type' => 'string', - 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce-rest-api' ), + 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'dimension_unit' => array( 'type' => 'string', - 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce-rest-api' ), + 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), + 'description' => __( 'Full name of country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'num_decimals' => array( 'type' => 'integer', - 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'states' => array( 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), + 'description' => __( 'List of states in this country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -321,13 +321,13 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce-rest-api' ), + 'description' => __( 'State code.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), + 'description' => __( 'Full name of state.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), @@ -336,13 +336,13 @@ class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller { ), 'thousand_sep' => array( 'type' => 'string', - 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce-rest-api' ), + 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'weight_unit' => array( 'type' => 'string', - 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce-rest-api' ), + 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php index e6b794a2ba7..67a69f025a5 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php @@ -58,7 +58,7 @@ class WC_REST_Data_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -72,7 +72,7 @@ class WC_REST_Data_Controller extends WC_REST_Controller { */ public function get_item_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -90,15 +90,15 @@ class WC_REST_Data_Controller extends WC_REST_Controller { $resources = array( array( 'slug' => 'continents', - 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce-rest-api' ), + 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce' ), ), array( 'slug' => 'countries', - 'description' => __( 'List of supported states in a given country.', 'woocommerce-rest-api' ), + 'description' => __( 'List of supported states in a given country.', 'woocommerce' ), ), array( 'slug' => 'currencies', - 'description' => __( 'List of supported currencies.', 'woocommerce-rest-api' ), + 'description' => __( 'List of supported currencies.', 'woocommerce' ), ), ); @@ -165,13 +165,13 @@ class WC_REST_Data_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'Data resource ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Data resource ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Data resource description.', 'woocommerce-rest-api' ), + 'description' => __( 'Data resource description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php index aaed5e2f30d..d8219a77439 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php @@ -56,7 +56,7 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'location' => array( - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), 'type' => 'string', ), ), @@ -130,7 +130,7 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { public function get_item( $request ) { $data = $this->get_country( strtoupper( $request['location'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -197,19 +197,19 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of country.', 'woocommerce-rest-api' ), + 'description' => __( 'Full name of country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'states' => array( 'type' => 'array', - 'description' => __( 'List of states in this country.', 'woocommerce-rest-api' ), + 'description' => __( 'List of states in this country.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, 'items' => array( @@ -219,13 +219,13 @@ class WC_REST_Data_Countries_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'State code.', 'woocommerce-rest-api' ), + 'description' => __( 'State code.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of state.', 'woocommerce-rest-api' ), + 'description' => __( 'Full name of state.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php index eb62a89f048..574d9d4c571 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php @@ -63,7 +63,7 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'location' => array( - 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), 'type' => 'string', ), ), @@ -123,7 +123,7 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { public function get_item( $request ) { $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); if ( empty( $data ) ) { - return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $data, $request ); } @@ -197,19 +197,19 @@ class WC_REST_Data_Currencies_Controller extends WC_REST_Data_Controller { 'properties' => array( 'code' => array( 'type' => 'string', - 'description' => __( 'ISO4217 currency code.', 'woocommerce-rest-api' ), + 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( 'type' => 'string', - 'description' => __( 'Full name of currency.', 'woocommerce-rest-api' ), + 'description' => __( 'Full name of currency.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), 'symbol' => array( 'type' => 'string', - 'description' => __( 'Currency symbol.', 'woocommerce-rest-api' ), + 'description' => __( 'Currency symbol.', 'woocommerce' ), 'context' => array( 'view' ), 'readonly' => true, ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php index 3e4d2e17f90..de492a952f1 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php @@ -35,7 +35,7 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { public function prepare_item_for_response( $note, $request ) { $data = array( 'id' => (int) $note->comment_ID, - 'author' => __( 'woocommerce', 'woocommerce-rest-api' ) === $note->comment_author ? 'system' : $note->comment_author, + 'author' => __( 'woocommerce', 'woocommerce' ) === $note->comment_author ? 'system' : $note->comment_author, 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), 'note' => $note->comment_content, @@ -70,20 +70,20 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order || $this->post_type !== $order->get_type() ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } // Create the note. $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); if ( ! $note_id ) { - return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); } $note = get_comment( $note_id ); @@ -119,42 +119,42 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'author' => array( - 'description' => __( 'Order note author.', 'woocommerce-rest-api' ), + 'description' => __( 'Order note author.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'note' => array( - 'description' => __( 'Order note content.', 'woocommerce-rest-api' ), + 'description' => __( 'Order note content.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'customer_note' => array( - 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce-rest-api' ), + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'added_by_user' => array( - 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce-rest-api' ), + 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'edit' ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php index 865634affe0..98731f5756c 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php @@ -37,11 +37,11 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controll $order = wc_get_order( (int) $request['order_id'] ); if ( ! $order ) { - return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce-rest-api' ), 404 ); + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); } if ( 0 > $request['amount'] ) { - return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce-rest-api' ), 400 ); + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); } // Create the refund. @@ -61,7 +61,7 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controll } if ( ! $refund ) { - return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce-rest-api' ), 500 ); + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); } if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php index 1d2ad09d5d7..5e4ea622fc8 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php @@ -47,7 +47,7 @@ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller { if ( is_array( $item ) ) { if ( empty( $item['id'] ) ) { if ( empty( $item['code'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); } $results = $order->apply_coupon( wc_clean( $item['code'] ) ); @@ -157,7 +157,7 @@ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller { if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { // Make sure customer exists. if ( false === get_user_by( 'id', $request['customer_id'] ) ) { - throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce-rest-api' ), 400 ); + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); } // Make sure customer is part of blog. @@ -257,7 +257,7 @@ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller { $params['status'] = array( 'default' => 'any', - 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'string', diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php index f48b155f3dd..5c0eb9c8ac9 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php @@ -114,23 +114,23 @@ class WC_REST_Payment_Gateways_Controller extends WC_REST_Payment_Gateways_V2_Co 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Payment gateway ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'title' => array( - 'description' => __( 'Payment gateway title on checkout.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Payment gateway description on checkout.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'order' => array( - 'description' => __( 'Payment gateway sort order.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -138,24 +138,24 @@ class WC_REST_Payment_Gateways_Controller extends WC_REST_Payment_Gateways_V2_Co ), ), 'enabled' => array( - 'description' => __( 'Payment gateway enabled status.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'method_title' => array( - 'description' => __( 'Payment gateway method title.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway method title.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_description' => array( - 'description' => __( 'Payment gateway method description.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway method description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'method_supports' => array( - 'description' => __( 'Supported features for this payment gateway.', 'woocommerce-rest-api' ), + 'description' => __( 'Supported features for this payment gateway.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -164,54 +164,54 @@ class WC_REST_Payment_Gateways_Controller extends WC_REST_Payment_Gateways_V2_Co ), ), 'settings' => array( - 'description' => __( 'Payment gateway settings.', 'woocommerce-rest-api' ), + 'description' => __( 'Payment gateway settings.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Type of setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), + 'description' => __( 'Setting value.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Default value for the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php index 0db471b87a3..979df645d82 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php @@ -54,7 +54,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -68,7 +68,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -84,7 +84,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -100,7 +100,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -116,7 +116,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( (int) $request['id'] ); if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -131,7 +131,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -148,9 +148,9 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( $id ); if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $post, $request ); @@ -172,7 +172,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -255,9 +255,9 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( $id ); if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); } $post = $this->prepare_item_for_database( $request ); @@ -418,7 +418,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( $id ); if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0; @@ -435,7 +435,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { /* translators: %s: post type */ - return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); @@ -448,13 +448,13 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( 'trash' === $post->post_status ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 410 ) ); + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); } // (Note that internally this falls through to `wp_delete_post` if @@ -464,7 +464,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( ! $result ) { /* translators: %s: post type */ - return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); } /** @@ -621,19 +621,19 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), + '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-rest-api' ), + '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['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -642,7 +642,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -651,20 +651,20 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), + '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-rest-api' ), + '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-rest-api' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date', 'enum' => array( @@ -682,7 +682,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -691,7 +691,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { 'default' => array(), ); $params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -704,7 +704,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( 'wc/v1' === $this->namespace ) { $params['filter'] = array( 'type' => 'object', - 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce-rest-api' ), + 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce' ), ); } diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php index 63ced695fec..c69f5640a99 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php @@ -100,13 +100,13 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), + 'description' => __( 'Category name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -114,7 +114,7 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V ), ), 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -122,12 +122,12 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V ), ), 'parent' => array( - 'description' => __( 'The ID for the parent of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'HTML description of the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -135,71 +135,71 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V ), ), 'display' => array( - 'description' => __( 'Category archive display type.', 'woocommerce-rest-api' ), + 'description' => __( 'Category archive display type.', 'woocommerce' ), 'type' => 'string', 'default' => 'default', 'enum' => array( 'default', 'products', 'subcategories', 'both' ), 'context' => array( 'view', 'edit' ), ), 'image' => array( - 'description' => __( 'Image data.', 'woocommerce-rest-api' ), + 'description' => __( 'Image data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'count' => array( - 'description' => __( 'Number of published products for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php index aee1016454f..7b4a12d2c6e 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php @@ -52,23 +52,23 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 'product_id' => array( 'required' => true, - 'description' => __( 'Unique identifier for the product.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the product.', 'woocommerce' ), 'type' => 'integer', ), 'review' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Review content.', 'woocommerce-rest-api' ), + 'description' => __( 'Review content.', 'woocommerce' ), ), 'reviewer' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Name of the reviewer.', 'woocommerce-rest-api' ), + 'description' => __( 'Name of the reviewer.', 'woocommerce' ), ), 'reviewer_email' => array( 'required' => true, 'type' => 'string', - 'description' => __( 'Email of the reviewer.', 'woocommerce-rest-api' ), + 'description' => __( 'Email of the reviewer.', 'woocommerce' ), ), ) ), @@ -81,7 +81,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -107,7 +107,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -136,7 +136,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -153,7 +153,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -167,7 +167,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function create_item_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -184,7 +184,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'edit', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -201,7 +201,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $review = get_comment( $id ); if ( $review && ! wc_rest_check_product_reviews_permissions( 'delete', $review->comment_ID ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -215,7 +215,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -371,13 +371,13 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { - return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce' ), array( 'status' => 400 ) ); } $product_id = (int) $request['product_id']; if ( 'product' !== get_post_type( $product_id ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $prepared_review = $this->prepare_item_for_database( $request ); @@ -391,7 +391,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). */ if ( empty( $prepared_review['comment_content'] ) ) { - return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); } // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). @@ -416,7 +416,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); } $prepared_review['comment_parent'] = 0; @@ -457,7 +457,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); if ( ! $review_id ) { - return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { @@ -527,7 +527,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $id = (int) $review->comment_ID; if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { - return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce' ), array( 'status' => 404 ) ); } $prepared_args = $this->prepare_item_for_database( $request ); @@ -537,7 +537,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { if ( ! empty( $prepared_args['comment_post_ID'] ) ) { if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } } @@ -546,7 +546,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $change = $this->handle_status_param( $request['status'], $id ); if ( ! $change ) { - return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce' ), array( 'status' => 500 ) ); } } elseif ( ! empty( $prepared_args ) ) { if ( is_wp_error( $prepared_args ) ) { @@ -554,7 +554,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { } if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { - return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); } $prepared_args['comment_ID'] = $id; @@ -562,13 +562,13 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); - return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); } $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); if ( false === $updated ) { - return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { @@ -639,11 +639,11 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { // If this type doesn't support trashing, error out. if ( ! $supports_trash ) { /* translators: %s: force=true */ - return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce-rest-api' ), 'force=true' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce' ), 'force=true' ), array( 'status' => 501 ) ); } if ( 'trash' === $review->comment_approved ) { - return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce-rest-api' ), array( 'status' => 410 ) ); + return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); } $result = wp_trash_comment( $review->comment_ID ); @@ -652,7 +652,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { } if ( ! $result ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -828,48 +828,48 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the review was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'product_id' => array( - 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Status of the review.', 'woocommerce-rest-api' ), + 'description' => __( 'Status of the review.', 'woocommerce' ), 'type' => 'string', 'default' => 'approved', 'enum' => array( 'approved', 'hold', 'spam', 'unspam', 'trash', 'untrash' ), 'context' => array( 'view', 'edit' ), ), 'reviewer' => array( - 'description' => __( 'Reviewer name.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviewer name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'reviewer_email' => array( - 'description' => __( 'Reviewer email.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviewer email.', 'woocommerce' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'view', 'edit' ), ), 'review' => array( - 'description' => __( 'The content of the review.', 'woocommerce-rest-api' ), + 'description' => __( 'The content of the review.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( @@ -877,12 +877,12 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ), ), 'rating' => array( - 'description' => __( 'Review rating (0 to 5).', 'woocommerce-rest-api' ), + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'verified' => array( - 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -897,14 +897,14 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { foreach ( $avatar_sizes as $size ) { $avatar_properties[ $size ] = array( /* translators: %d: avatar image size in pixels */ - 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce-rest-api' ), $size ), + 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce' ), $size ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ); } $schema['properties']['reviewer_avatar_urls'] = array( - 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce-rest-api' ), + 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -926,17 +926,17 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['after'] = array( - 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), 'type' => 'string', 'format' => 'date-time', ); $params['before'] = array( - 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce' ), 'type' => 'string', 'format' => 'date-time', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -944,7 +944,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'default' => array(), ); $params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -952,11 +952,11 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'default' => array(), ); $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), 'type' => 'integer', ); $params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( @@ -965,7 +965,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ), ); $params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), 'type' => 'string', 'default' => 'date_gmt', 'enum' => array( @@ -977,14 +977,14 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ), ); $params['reviewer'] = array( - 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $params['reviewer_exclude'] = array( - 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -992,13 +992,13 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ); $params['reviewer_email'] = array( 'default' => null, - 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce' ), 'format' => 'email', 'type' => 'string', ); $params['product'] = array( 'default' => array(), - 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1006,7 +1006,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ); $params['status'] = array( 'default' => 'approved', - 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', 'enum' => array( @@ -1040,7 +1040,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ protected function get_review( $id ) { $id = (int) $id; - $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce' ), array( 'status' => 404 ) ); if ( 0 >= $id ) { return $error; @@ -1055,7 +1055,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $post = get_post( (int) $review->comment_post_ID ); if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } } diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php index 6c710162e9b..b5f5245ec54 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php @@ -234,7 +234,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V if ( ! $parent ) { return new WP_Error( // Translators: %d parent ID. - "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce-rest-api' ), $variation->get_parent_id() ), array( + "woocommerce_rest_{$this->post_type}_invalid_parent", sprintf( __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), $variation->get_parent_id() ), array( 'status' => 404, ) ); @@ -368,7 +368,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V if ( ! wp_attachment_is_image( $attachment_id ) ) { /* translators: %s: attachment ID */ - throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); + throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); } $variation->set_image_id( $attachment_id ); @@ -405,126 +405,126 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( - 'description' => __( 'Variation description.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Variation URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current variation price.', 'woocommerce-rest-api' ), + 'description' => __( 'Current variation price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Variation regular price.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation regular price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Variation sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'on_sale' => array( - 'description' => __( 'Shows if the variation is on sale.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'status' => array( - 'description' => __( 'Variation status.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation status.', 'woocommerce' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_keys( get_post_statuses() ), 'context' => array( 'view', 'edit' ), ), 'purchasable' => array( - 'description' => __( 'Shows if the variation can be bought.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the variation is virtual.', 'woocommerce-rest-api' ), + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the variation is downloadable.', 'woocommerce-rest-api' ), + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), + 'description' => __( 'List of downloadable files.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), + 'description' => __( 'File ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), + 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), + 'description' => __( 'File URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -532,179 +532,179 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax status.', 'woocommerce' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at variation level.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock quantity.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), 'type' => 'string', 'default' => 'instock', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Variation dimensions.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation dimensions.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'image' => array( - 'description' => __( 'Variation image data.', 'woocommerce-rest-api' ), + 'description' => __( 'Variation image data.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'List of attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -712,30 +712,30 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ), ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -848,7 +848,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V ); $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'sanitize_callback' => 'sanitize_text_field', diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php index 6f3d3a04024..5af8575a2bb 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php @@ -250,7 +250,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { if ( ! wp_attachment_is_image( $attachment_id ) ) { /* translators: %s: image ID */ - throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $attachment_id ), 400 ); + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); } $featured_image = $product->get_image_id(); @@ -313,7 +313,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { if ( 'variation' === $product->get_type() ) { return new WP_Error( - "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce-rest-api' ), array( + "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404, ) ); @@ -698,183 +698,183 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'slug' => array( - 'description' => __( 'Product slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Product slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'permalink' => array( - 'description' => __( 'Product URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Product URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created' => array( - 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_created_gmt' => array( - 'description' => __( 'The date the product was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_modified' => array( - 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'type' => array( - 'description' => __( 'Product type.', 'woocommerce-rest-api' ), + 'description' => __( 'Product type.', 'woocommerce' ), 'type' => 'string', 'default' => 'simple', 'enum' => array_keys( wc_get_product_types() ), 'context' => array( 'view', 'edit' ), ), 'status' => array( - 'description' => __( 'Product status (post status).', 'woocommerce-rest-api' ), + 'description' => __( 'Product status (post status).', 'woocommerce' ), 'type' => 'string', 'default' => 'publish', 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), 'context' => array( 'view', 'edit' ), ), 'featured' => array( - 'description' => __( 'Featured product.', 'woocommerce-rest-api' ), + 'description' => __( 'Featured product.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'catalog_visibility' => array( - 'description' => __( 'Catalog visibility.', 'woocommerce-rest-api' ), + 'description' => __( 'Catalog visibility.', 'woocommerce' ), 'type' => 'string', 'default' => 'visible', 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'Product description.', 'woocommerce-rest-api' ), + 'description' => __( 'Product description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'short_description' => array( - 'description' => __( 'Product short description.', 'woocommerce-rest-api' ), + 'description' => __( 'Product short description.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sku' => array( - 'description' => __( 'Unique identifier.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'price' => array( - 'description' => __( 'Current product price.', 'woocommerce-rest-api' ), + 'description' => __( 'Current product price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'regular_price' => array( - 'description' => __( 'Product regular price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product regular price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sale_price' => array( - 'description' => __( 'Product sale price.', 'woocommerce-rest-api' ), + 'description' => __( 'Product sale price.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from' => array( - 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_from_gmt' => array( - 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'date_on_sale_to_gmt' => array( - 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'price_html' => array( - 'description' => __( 'Price formatted in HTML.', 'woocommerce-rest-api' ), + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'on_sale' => array( - 'description' => __( 'Shows if the product is on sale.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'purchasable' => array( - 'description' => __( 'Shows if the product can be bought.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'total_sales' => array( - 'description' => __( 'Amount of sales.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of sales.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'virtual' => array( - 'description' => __( 'If the product is virtual.', 'woocommerce-rest-api' ), + 'description' => __( 'If the product is virtual.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloadable' => array( - 'description' => __( 'If the product is downloadable.', 'woocommerce-rest-api' ), + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'downloads' => array( - 'description' => __( 'List of downloadable files.', 'woocommerce-rest-api' ), + 'description' => __( 'List of downloadable files.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'File ID.', 'woocommerce-rest-api' ), + 'description' => __( 'File ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'File name.', 'woocommerce-rest-api' ), + 'description' => __( 'File name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'file' => array( - 'description' => __( 'File URL.', 'woocommerce-rest-api' ), + 'description' => __( 'File URL.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -882,157 +882,157 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'download_limit' => array( - 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'download_expiry' => array( - 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce-rest-api' ), + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), 'type' => 'integer', 'default' => -1, 'context' => array( 'view', 'edit' ), ), 'external_url' => array( - 'description' => __( 'Product external URL. Only for external products.', 'woocommerce-rest-api' ), + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'button_text' => array( - 'description' => __( 'Product external button text. Only for external products.', 'woocommerce-rest-api' ), + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'tax_status' => array( - 'description' => __( 'Tax status.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax status.', 'woocommerce' ), 'type' => 'string', 'default' => 'taxable', 'enum' => array( 'taxable', 'shipping', 'none' ), 'context' => array( 'view', 'edit' ), ), 'tax_class' => array( - 'description' => __( 'Tax class.', 'woocommerce-rest-api' ), + 'description' => __( 'Tax class.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'manage_stock' => array( - 'description' => __( 'Stock management at product level.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock management at product level.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'stock_quantity' => array( - 'description' => __( 'Stock quantity.', 'woocommerce-rest-api' ), + 'description' => __( 'Stock quantity.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'stock_status' => array( - 'description' => __( 'Controls the stock status of the product.', 'woocommerce-rest-api' ), + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), 'type' => 'string', 'default' => 'instock', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'context' => array( 'view', 'edit' ), ), 'backorders' => array( - 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), 'type' => 'string', 'default' => 'no', 'enum' => array( 'no', 'notify', 'yes' ), 'context' => array( 'view', 'edit' ), ), 'backorders_allowed' => array( - 'description' => __( 'Shows if backorders are allowed.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'backordered' => array( - 'description' => __( 'Shows if the product is on backordered.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'sold_individually' => array( - 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce-rest-api' ), + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'weight' => array( /* translators: %s: weight unit */ - 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce-rest-api' ), $weight_unit ), + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'dimensions' => array( - 'description' => __( 'Product dimensions.', 'woocommerce-rest-api' ), + 'description' => __( 'Product dimensions.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array( 'length' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product length (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'width' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product width (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'height' => array( /* translators: %s: dimension unit */ - 'description' => sprintf( __( 'Product height (%s).', 'woocommerce-rest-api' ), $dimension_unit ), + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), ), ), 'shipping_required' => array( - 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_taxable' => array( - 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce-rest-api' ), + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'shipping_class' => array( - 'description' => __( 'Shipping class slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'shipping_class_id' => array( - 'description' => __( 'Shipping class ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Shipping class ID.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'reviews_allowed' => array( - 'description' => __( 'Allow reviews.', 'woocommerce-rest-api' ), + 'description' => __( 'Allow reviews.', 'woocommerce' ), 'type' => 'boolean', 'default' => true, 'context' => array( 'view', 'edit' ), ), 'average_rating' => array( - 'description' => __( 'Reviews average rating.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviews average rating.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rating_count' => array( - 'description' => __( 'Amount of reviews that the product have.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'related_ids' => array( - 'description' => __( 'List of related products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of related products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1041,7 +1041,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'readonly' => true, ), 'upsell_ids' => array( - 'description' => __( 'List of up-sell products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1049,7 +1049,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'context' => array( 'view', 'edit' ), ), 'cross_sell_ids' => array( - 'description' => __( 'List of cross-sell products IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1057,35 +1057,35 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'Product parent ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Product parent ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'purchase_note' => array( - 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce-rest-api' ), + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'categories' => array( - 'description' => __( 'List of categories.', 'woocommerce-rest-api' ), + 'description' => __( 'List of categories.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Category ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Category ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Category name.', 'woocommerce-rest-api' ), + 'description' => __( 'Category name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Category slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Category slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1094,25 +1094,25 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'tags' => array( - 'description' => __( 'List of tags.', 'woocommerce-rest-api' ), + 'description' => __( 'List of tags.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Tag ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Tag name.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( - 'description' => __( 'Tag slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Tag slug.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, @@ -1121,54 +1121,54 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'images' => array( - 'description' => __( 'List of images.', 'woocommerce-rest-api' ), + 'description' => __( 'List of images.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Image ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Image ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'date_created' => array( - 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_created_gmt' => array( - 'description' => __( 'The date the image was created, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified' => array( - 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce-rest-api' ), + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'date_modified_gmt' => array( - 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce-rest-api' ), + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'src' => array( - 'description' => __( 'Image URL.', 'woocommerce-rest-api' ), + 'description' => __( 'Image URL.', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Image name.', 'woocommerce-rest-api' ), + 'description' => __( 'Image name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'alt' => array( - 'description' => __( 'Image alternative text.', 'woocommerce-rest-api' ), + 'description' => __( 'Image alternative text.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1176,41 +1176,41 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'attributes' => array( - 'description' => __( 'List of attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'List of attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'position' => array( - 'description' => __( 'Attribute position.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute position.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'visible' => array( - 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce-rest-api' ), + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'variation' => array( - 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce-rest-api' ), + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'view', 'edit' ), ), 'options' => array( - 'description' => __( 'List of available term names of the attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'string', @@ -1221,24 +1221,24 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'default_attributes' => array( - 'description' => __( 'Defaults variation attributes.', 'woocommerce-rest-api' ), + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Attribute ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'name' => array( - 'description' => __( 'Attribute name.', 'woocommerce-rest-api' ), + 'description' => __( 'Attribute name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'option' => array( - 'description' => __( 'Selected attribute term name.', 'woocommerce-rest-api' ), + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -1246,7 +1246,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'variations' => array( - 'description' => __( 'List of variations IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'List of variations IDs.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( @@ -1255,7 +1255,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'readonly' => true, ), 'grouped_products' => array( - 'description' => __( 'List of grouped products ID.', 'woocommerce-rest-api' ), + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -1264,30 +1264,30 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { 'readonly' => true, ), 'menu_order' => array( - 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce-rest-api' ), + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'meta_data' => array( - 'description' => __( 'Meta data.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta data.', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'items' => array( 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'Meta ID.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta ID.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'key' => array( - 'description' => __( 'Meta key.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta key.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'value' => array( - 'description' => __( 'Meta value.', 'woocommerce-rest-api' ), + 'description' => __( 'Meta value.', 'woocommerce' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit' ), ), @@ -1310,7 +1310,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { unset( $params['in_stock'] ); $params['stock_status'] = array( - 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), 'type' => 'string', 'enum' => array_keys( wc_get_product_stock_status_options() ), 'sanitize_callback' => 'sanitize_text_field', diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php index 85d4ae34795..b6bfe4304b3 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php @@ -118,19 +118,19 @@ class WC_REST_Report_Coupons_Totals_Controller extends WC_REST_Reports_Controlle 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Coupon type name.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupon type name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of coupons.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of coupons.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php index 38867bd7135..929a2f3c73a 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php @@ -71,12 +71,12 @@ class WC_REST_Report_Customers_Totals_Controller extends WC_REST_Reports_Control $data = array( array( 'slug' => 'paying', - 'name' => __( 'Paying customer', 'woocommerce-rest-api' ), + 'name' => __( 'Paying customer', 'woocommerce' ), 'total' => $total_paying, ), array( 'slug' => 'non_paying', - 'name' => __( 'Non-paying customer', 'woocommerce-rest-api' ), + 'name' => __( 'Non-paying customer', 'woocommerce' ), 'total' => $total_customers - $total_paying, ), ); @@ -129,19 +129,19 @@ class WC_REST_Report_Customers_Totals_Controller extends WC_REST_Reports_Control 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Customer type name.', 'woocommerce-rest-api' ), + 'description' => __( 'Customer type name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of customers.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of customers.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php index 4c7c9289806..f70ebe6a5a4 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php @@ -102,19 +102,19 @@ class WC_REST_Report_Orders_Totals_Controller extends WC_REST_Reports_Controller 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Order status name.', 'woocommerce-rest-api' ), + 'description' => __( 'Order status name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of orders.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of orders.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php index d855b6298b9..c45671c50d9 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php @@ -108,19 +108,19 @@ class WC_REST_Report_Products_Totals_Controller extends WC_REST_Reports_Controll 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Product type name.', 'woocommerce-rest-api' ), + 'description' => __( 'Product type name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of products.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of products.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php index d585d586d27..c7b5cf2249a 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php @@ -54,7 +54,7 @@ class WC_REST_Report_Reviews_Totals_Controller extends WC_REST_Reports_Controlle $data[] = array( 'slug' => 'rated_' . $i . '_out_of_5', /* translators: %s: average rating */ - 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce-rest-api' ), $i ), + 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $i ), 'total' => (int) get_comments( $query_data ), ); } @@ -107,19 +107,19 @@ class WC_REST_Report_Reviews_Totals_Controller extends WC_REST_Reports_Controlle 'type' => 'object', 'properties' => array( 'slug' => array( - 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'name' => array( - 'description' => __( 'Review type name.', 'woocommerce-rest-api' ), + 'description' => __( 'Review type name.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, ), 'total' => array( - 'description' => __( 'Amount of reviews.', 'woocommerce-rest-api' ), + 'description' => __( 'Amount of reviews.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php index 2ae97fbb4c0..67a37e697da 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php @@ -36,35 +36,35 @@ class WC_REST_Reports_Controller extends WC_REST_Reports_V2_Controller { $reports[] = array( 'slug' => 'orders/totals', - 'description' => __( 'Orders totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Orders totals.', 'woocommerce' ), ); $reports[] = array( 'slug' => 'products/totals', - 'description' => __( 'Products totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Products totals.', 'woocommerce' ), ); $reports[] = array( 'slug' => 'customers/totals', - 'description' => __( 'Customers totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Customers totals.', 'woocommerce' ), ); $reports[] = array( 'slug' => 'coupons/totals', - 'description' => __( 'Coupons totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Coupons totals.', 'woocommerce' ), ); $reports[] = array( 'slug' => 'reviews/totals', - 'description' => __( 'Reviews totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Reviews totals.', 'woocommerce' ), ); $reports[] = array( 'slug' => 'categories/totals', - 'description' => __( 'Categories totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Categories totals.', 'woocommerce' ), ); $reports[] = array( 'slug' => 'tags/totals', - 'description' => __( 'Tags totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Tags totals.', 'woocommerce' ), ); $reports[] = array( 'slug' => 'attributes/totals', - 'description' => __( 'Attributes totals.', 'woocommerce-rest-api' ), + 'description' => __( 'Attributes totals.', 'woocommerce' ), ); return $reports; diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php index 59d3828e5e3..22afa819a38 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php @@ -73,13 +73,13 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont */ public function get_group_settings( $group_id ) { if ( empty( $group_id ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $filtered_settings = array(); @@ -162,7 +162,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', @@ -171,7 +171,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'group_id' => array( - 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce-rest-api' ), + 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', @@ -180,7 +180,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -189,7 +189,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -198,7 +198,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'value' => array( - 'description' => __( 'Setting value.', 'woocommerce-rest-api' ), + 'description' => __( 'Setting value.', 'woocommerce' ), 'type' => array( 'string', 'array', 'null' ), 'items' => array( 'type' => array( 'string', 'null' ), @@ -206,7 +206,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'context' => array( 'view', 'edit' ), ), 'default' => array( - 'description' => __( 'Default value for the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Default value for the setting.', 'woocommerce' ), 'type' => array( 'string', 'array', 'null' ), 'items' => array( 'type' => array( 'string', 'null' ), @@ -215,7 +215,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'tip' => array( - 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -224,7 +224,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'placeholder' => array( - 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce-rest-api' ), + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -233,7 +233,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'type' => array( - 'description' => __( 'Type of setting.', 'woocommerce-rest-api' ), + 'description' => __( 'Type of setting.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', @@ -243,7 +243,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Setting_Options_V2_Cont 'readonly' => true, ), 'options' => array( - 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce-rest-api' ), + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php index 0762c090fd4..77aebd681d4 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php @@ -48,7 +48,7 @@ class WC_REST_Settings_Controller extends WC_REST_Settings_V2_Controller { */ 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-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -80,27 +80,27 @@ class WC_REST_Settings_Controller extends WC_REST_Settings_V2_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce-rest-api' ), + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'label' => array( - 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'description' => array( - 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce-rest-api' ), + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce-rest-api' ), + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce-rest-api' ), + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php b/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php index 250269663d0..871c5199e31 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php @@ -44,7 +44,7 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller $zone = WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id ); if ( false === $zone ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } return $zone; @@ -58,11 +58,11 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function get_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -76,11 +76,11 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function create_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -94,11 +94,11 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function update_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -112,11 +112,11 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function delete_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php index 5722aeb8b5d..2422f99b286 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php @@ -52,7 +52,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { array( 'name' => array( 'type' => 'string', - 'description' => __( 'Name for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Name for the resource.', 'woocommerce' ), 'required' => true, ), ) @@ -68,7 +68,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { array( 'args' => array( 'id' => array( - 'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ), + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', ), ), @@ -94,7 +94,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { 'force' => array( 'default' => false, 'type' => 'boolean', - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ), + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), ), ), ), @@ -130,7 +130,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -149,7 +149,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -168,7 +168,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -187,7 +187,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -206,7 +206,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -225,7 +225,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( ! $permissions ) { - return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce-rest-api' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -242,7 +242,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { // Get taxonomy. $taxonomy = $this->get_taxonomy( $request ); if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } // Check permissions for a single term. @@ -251,7 +251,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { $term = get_term( $id, $taxonomy ); if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { - return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce-rest-api' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); } return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id ); @@ -390,7 +390,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); } $args['parent'] = $request['parent']; } @@ -487,7 +487,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { - return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce-rest-api' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); } $prepared_args['parent'] = $request['parent']; } @@ -536,7 +536,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { // We don't support trashing for this type, error out. if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) ); + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } $term = get_term( (int) $request['id'], $taxonomy ); @@ -545,7 +545,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { // Prevent deleting the default product category. if ( $default_category_id === (int) $request['id'] ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } $request->set_param( 'context', 'edit' ); @@ -553,7 +553,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { $retval = wp_delete_term( $term->term_id, $term->taxonomy ); if ( ! $retval ) { - return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce-rest-api' ), array( 'status' => 500 ) ); + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } /** @@ -701,7 +701,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -710,7 +710,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), 'type' => 'array', 'items' => array( 'type' => 'integer', @@ -720,14 +720,14 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { ); if ( ! $taxonomy->hierarchical ) { $params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ), + '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-rest-api' ), + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'asc', @@ -738,7 +738,7 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['orderby'] = array( - 'description' => __( 'Sort collection by resource attribute.', 'woocommerce-rest-api' ), + 'description' => __( 'Sort collection by resource attribute.', 'woocommerce' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'name', @@ -754,27 +754,27 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['hide_empty'] = array( - 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce-rest-api' ), + 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce' ), 'type' => 'boolean', 'default' => false, 'validate_callback' => 'rest_validate_request_arg', ); if ( $taxonomy->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); } $params['product'] = array( - 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce' ), 'type' => 'integer', 'default' => null, 'validate_callback' => 'rest_validate_request_arg', ); $params['slug'] = array( - 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce-rest-api' ), + 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); diff --git a/includes/rest-api/Utilities/ImageAttachment.php b/includes/rest-api/Utilities/ImageAttachment.php index 115aa7d0279..a9fab68b8c7 100644 --- a/includes/rest-api/Utilities/ImageAttachment.php +++ b/includes/rest-api/Utilities/ImageAttachment.php @@ -58,7 +58,7 @@ class ImageAttachment { if ( ! wp_attachment_is_image( $this->id ) ) { /* translators: %s: image ID */ - throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce-rest-api' ), $this->id ), 400 ); + throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $this->id ), 400 ); } } From 2d2e40c484596d9ad43f559653f2c4604ce972fc Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Thu, 6 Aug 2020 14:15:50 -0300 Subject: [PATCH 435/440] Applied woocommerce_order_item_quantity to ReserveStock --- includes/wc-stock-functions.php | 11 +++++++++-- src/Checkout/Helpers/ReserveStock.php | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/includes/wc-stock-functions.php b/includes/wc-stock-functions.php index c92e474d1a1..32087998778 100644 --- a/includes/wc-stock-functions.php +++ b/includes/wc-stock-functions.php @@ -64,8 +64,8 @@ function wc_update_product_stock( $product, $stock_quantity = null, $operation = /** * Update a product's stock status. * - * @param int $product_id Product ID. - * @param string $status Status. + * @param int $product_id Product ID. + * @param string $status Status. */ function wc_update_product_stock_status( $product_id, $status ) { $product = wc_get_product( $product_id ); @@ -170,6 +170,13 @@ function wc_reduce_stock_levels( $order_id ) { continue; } + /** + * Filter order item quantity. + * + * @param int|float $quantity Quantity. + * @param WC_Order $order Order data. + * @param WC_Order_Item_Product $item Order item data. + */ $qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item ); $item_name = $product->get_formatted_name(); $new_stock = wc_update_product_stock( $product, $qty, 'decrease' ); diff --git a/src/Checkout/Helpers/ReserveStock.php b/src/Checkout/Helpers/ReserveStock.php index b575ecc62fc..17220325c59 100644 --- a/src/Checkout/Helpers/ReserveStock.php +++ b/src/Checkout/Helpers/ReserveStock.php @@ -101,8 +101,18 @@ final class ReserveStock { continue; } - $managed_by_id = $product->get_stock_managed_by_id(); - $rows[ $managed_by_id ] = isset( $rows[ $managed_by_id ] ) ? $rows[ $managed_by_id ] + $item->get_quantity() : $item->get_quantity(); + $managed_by_id = $product->get_stock_managed_by_id(); + + /** + * Filter order item quantity. + * + * @param int|float $quantity Quantity. + * @param WC_Order $order Order data. + * @param WC_Order_Item_Product $item Order item data. + */ + $item_quantity = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item ); + + $rows[ $managed_by_id ] = isset( $rows[ $managed_by_id ] ) ? $rows[ $managed_by_id ] + $item_quantity : $item_quantity; } if ( ! empty( $rows ) ) { From def2ef499cf5dac82c0bf8c7b4215e00b6bb246d Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Fri, 7 Aug 2020 12:55:51 -0300 Subject: [PATCH 436/440] Master is 4.5.0 now --- includes/class-woocommerce.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-woocommerce.php b/includes/class-woocommerce.php index 9908924d103..2bad0bf07b0 100644 --- a/includes/class-woocommerce.php +++ b/includes/class-woocommerce.php @@ -22,7 +22,7 @@ final class WooCommerce { * * @var string */ - public $version = '4.4.0'; + public $version = '4.5.0'; /** * WooCommerce Schema version. From 3fd42a0fd55d6d938337ee2f36da0d15d1e0c5db Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Fri, 7 Aug 2020 13:26:51 -0300 Subject: [PATCH 437/440] Fixed packages required to run code sniffer on unit tests --- tests/bin/phpcs.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/bin/phpcs.sh b/tests/bin/phpcs.sh index 58ff2aa2a06..205e63d386a 100755 --- a/tests/bin/phpcs.sh +++ b/tests/bin/phpcs.sh @@ -5,9 +5,6 @@ if [[ ${RUN_PHPCS} == 1 ]]; then IGNORE="tests/cli/,includes/libraries/,includes/api/legacy/" if [ "$CHANGED_FILES" != "" ]; then - # Install wpcs globally: - composer require woocommerce/woocommerce-sniffs - echo "Running Code Sniffer." ./vendor/bin/phpcs --ignore=$IGNORE --encoding=utf-8 -s -n -p $CHANGED_FILES fi From 48732ee0dde5ed5236896a2e49746b4e516f6e8b Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Fri, 7 Aug 2020 13:35:15 -0300 Subject: [PATCH 438/440] Fixed package tag --- tests/legacy/framework/helpers/class-wc-helper-product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/legacy/framework/helpers/class-wc-helper-product.php b/tests/legacy/framework/helpers/class-wc-helper-product.php index a7556b46f3a..a9bd4ac746b 100644 --- a/tests/legacy/framework/helpers/class-wc-helper-product.php +++ b/tests/legacy/framework/helpers/class-wc-helper-product.php @@ -2,7 +2,7 @@ /** * Product helpers. * - * @package woocommerce/tests + * @package WooCommerce\Tests */ /** From 17f9883f0034b3d5c0c0a9344a8a5bad9a73f489 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Fri, 7 Aug 2020 13:36:41 -0300 Subject: [PATCH 439/440] Changed | to \ --- tests/legacy/framework/helpers/class-wc-helper-shipping.php | 2 +- tests/legacy/unit-tests/checkout/checkout.php | 2 +- tests/legacy/unit-tests/order/class-wc-tests-orders.php | 2 +- tests/php/includes/class-wc-ajax-test.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/legacy/framework/helpers/class-wc-helper-shipping.php b/tests/legacy/framework/helpers/class-wc-helper-shipping.php index 4436372638d..a54a5bed1f9 100644 --- a/tests/legacy/framework/helpers/class-wc-helper-shipping.php +++ b/tests/legacy/framework/helpers/class-wc-helper-shipping.php @@ -2,7 +2,7 @@ /** * Helper class for shipping related unit tests. * - * @package WooCommerce\Tests|Helper + * @package WooCommerce\Tests\Helper */ /** diff --git a/tests/legacy/unit-tests/checkout/checkout.php b/tests/legacy/unit-tests/checkout/checkout.php index d6639ec88ab..4d99a0c38d7 100644 --- a/tests/legacy/unit-tests/checkout/checkout.php +++ b/tests/legacy/unit-tests/checkout/checkout.php @@ -2,7 +2,7 @@ /** * Checkout tests. * - * @package WooCommerce|Tests|Checkout + * @package WooCommerce\Tests\Checkout */ /** diff --git a/tests/legacy/unit-tests/order/class-wc-tests-orders.php b/tests/legacy/unit-tests/order/class-wc-tests-orders.php index 4877745a592..9073011470f 100644 --- a/tests/legacy/unit-tests/order/class-wc-tests-orders.php +++ b/tests/legacy/unit-tests/order/class-wc-tests-orders.php @@ -2,7 +2,7 @@ /** * Class WC_Tests_Order file. * - * @package WooCommerce|Tests|Order + * @package WooCommerce\Tests\Order */ /** diff --git a/tests/php/includes/class-wc-ajax-test.php b/tests/php/includes/class-wc-ajax-test.php index 93904242f0a..afce0cb159a 100644 --- a/tests/php/includes/class-wc-ajax-test.php +++ b/tests/php/includes/class-wc-ajax-test.php @@ -2,7 +2,7 @@ /** * Class WC_AJAX_Test file. * - * @package WooCommerce|Tests|WC_AJAX. + * @package WooCommerce\Tests\WC_AJAX. */ /** From bf711d445e19468d2851915d79085e38e6f5bcd5 Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Mon, 10 Aug 2020 15:38:12 +0200 Subject: [PATCH 440/440] Added changelog for 4.3.2. --- CHANGELOG.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index d3f1e2a4f3c..23bcd8812c6 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -130,6 +130,18 @@ * Fix - 'Product Summary' in All Products block is not pulling in the short description of the product. #2913 * Dev - Add query filter when searching for a table. #2886 += 4.3.2 - 2020-08-10 = + +**WooCommerce** +* Fix - Remove new WP 5.5 meta box arrows from "Order data" and "Order items" meta boxes. #27173 +* Fix - "Product type" dropdown missing from Product's data meta box on WP 5.5. #27170 + +**WooCommerce Blocks 2.7.3** +* Fix - Fix missing permissions_callback arg in StoreApi route definitions. #2926 + +**WooCommerce REST API 1.0.10-pl-1** +* Enhancement - Compatibility fixes for WordPress 5.5 #232 + = 4.3.1 - 2020-07-21 = **WooCommerce Admin 1.3.1**